title: cmake precompiled header in shared library
body: <p>I'm trying to precompile my headers using gcc and cmake.</p>
  
  <p>I know some scripts like cotire or customPCH do it, but I would like to write my own script.</p>
  
  <p>The project is pretty simple : there is a shared library with some files, and a main calling functions defined in those files.
  I have manages to build the library (with precompiled header), but I have a strange compilation error when building the main ("precompiled.hpp", no such file or directory), even if the preompiled header is in the include search path (the library uses the same include paths and does not complain)</p>
  
  <pre><code>[100%] Building CXX object CMakeFiles/prog.dir/src/bin/main.cpp.o
  /usr/bin/c++ -DUSE_PRECOMPILED -Isrc -Ibuild -Winvalid-pch -fPIC -o CMakeFiles/prog.dir/src/bin/main.cpp.o -c src/bin/main.cpp
  src/lib/dir2/file2.hpp:7:42: fatal error: build/precompiled_header.hpp: No such file or directory
       #include "precompiled_header.hpp"
  </code></pre>
  
  <p>I have set up a working toy example available here : git clone -b toy <a href="https://bitbucket.org/mrdut/precompiled_header.git" rel="nofollow">https://bitbucket.org/mrdut/precompiled_header.git</a> </p>
  
  <p>Does anyone have any advice ?</p>
  
  <p>Thanks in advance,</p>
  
  <p>Here is the content of my project:</p>
  
  <pre><code>run.sh
  CMakeLists.txt
  src/
     lib/
        dir1/file1.cpp, file1.hpp
        dir2/file2.cpp, file2.hpp
     bin/main.cpp
  </code></pre>
  
  <p>run.sh :</p>
  
  <pre><code>mkdir build
  cd build/
  cmake .. &amp;&amp; make VERBOSE=1 &amp;&amp; ./bin/prog
  cd ..
  </code></pre>
  
  <p>CMakeslist.txt :</p>
  
  <pre><code>cmake_minimum_required(VERSION 2.8.11)
  
  project('PRECOMPILED' CXX)
  
  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY bin)
  set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY lib)
  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY lib)
  
  add_compile_options(-Winvalid-pch)
  
  set(use_precompiled_header 1) # &lt;= everything is fine if not using precompiled header
  set(executable_name prog)
  set(library_name erty)
  set(precompiled_header_name precompiled_header )
  
  ###########
  # library #
  ###########
  add_library(${library_name} SHARED src/lib/dir1/file1.cpp src/lib/dir2/file2.cpp)
  target_include_directories(${library_name} PUBLIC src )
  
  ##############
  # executable #
  ##############
  add_executable(${executable_name} src/bin/main.cpp)
  target_include_directories(${executable_name} PUBLIC src )
  target_link_libraries(${executable_name} ${library_name})
  target_compile_options(${executable_name} PRIVATE "-fPIC") # because we are building SHARED library
  
  ######################
  # precompiled header #
  ######################
  if( ${use_precompiled_header} )
  
      set(precompiled_header_dir ${CMAKE_CURRENT_BINARY_DIR} )
      set(precompiled_header_src ${CMAKE_CURRENT_SOURCE_DIR}/src/header.hpp )
      set(precompiled_header_dst precompiled_header.hpp.gch )
  
      add_custom_target( ${precompiled_header_name} ALL DEPENDS ${precompiled_header_dst} )
      add_custom_command( OUTPUT ${precompiled_header_dst}
                              COMMAND ${CMAKE_CXX_COMPILER} -fPIC -DUSE_PRECOMPILED ${precompiled_header_src} -o ${precompiled_header_dst}
                              MAIN_DEPENDENCY ${precompiled_header_src}
                              WORKING_DIRECTORY ${precompiled_header_dir}
                              VERBATIM )
  
      add_dependencies( ${library_name} ${precompiled_header_name} )
  
      target_compile_definitions(${library_name} PUBLIC -DUSE_PRECOMPILED )
      target_compile_definitions(${executable_name} PUBLIC -DUSE_PRECOMPILED )
  
      target_include_directories(${library_name} PUBLIC ${precompiled_header_dir})
      target_include_directories(${executable_name} PUBLIC ${precompiled_header_dir})
  
  endif()
  </code></pre>
  
  <p>src/header.hpp :</p>
  
  <pre><code>#ifndef HEADER_HPP
  #define HEADER_HPP
      #include &lt;iostream&gt;
  #endif
  </code></pre>
  
  <p>src/bin/main.cpp :</p>
  
  <pre><code>#include "lib/dir1/file1.hpp"
  #include "lib/dir2/file2.hpp"
  int main(int argc, char** argv)
  {
      std::cout &lt;&lt; "\n -= " &lt;&lt; argv[0] &lt;&lt; " =-\n";
      libfunc1();
      libfunc2();
      return 0;
  }
  </code></pre>
  
  <p>src/lib.dir1/file1.cpp :</p>
  
  <pre><code>#include "lib/dir1/file1.hpp"
  void libfunc1() { std::cout &lt;&lt; "function 1" &lt;&lt; std::endl; }
  </code></pre>
  
  <p>src/lib.dir1/file1.hpp :</p>
  
  <pre><code>#ifndef LIBRARY_FILE_1_HPP
  #define LIBRARY_FILE_1_HPP
      #ifndef USE_PRECOMPILED
          #include "header.hpp"
      #else
          #include "precompiled_header.hpp"
      #endif
      void libfunc1();
  #endif
  </code></pre>
  
  <p>src/lib.dir2/file2.cpp :</p>
  
  <pre><code>#include "lib/dir2/file2.hpp"
  void libfunc2() { std::cout &lt;&lt; "function 2" &lt;&lt; std::endl; }
  </code></pre>
  
  <p>src/lib.dir1/file2.hpp:</p>
  
  <pre><code>#ifndef LIBRARY_FILE_2_HPP
  #define LIBRARY_FILE_2_HPP
      #ifndef USE_PRECOMPILED
          #include "header.hpp"
      #else
          #include "precompiled_header.hpp"
      #endif
      void libfunc2();
  #endif
  </code></pre>