2015-11-09 102 views
0

我想用gcc和cmake预编译头文件。共享库中的cmake预编译头文件

我知道像cotire或customPCH这样的脚本,但我想写我自己的脚本。

该项目非常简单:有一个共享库,其中包含一些文件以及在这些文件中定义的主要调用函数。 我设法构建了库(带有预编译头文件),但是当构建main(“precompiled.hpp”,没有这样的文件或目录)时,即使预包装头文件位于include搜索路径中,我也遇到了一个奇怪的编译错误(库使用相同的包括路径和不抱怨)

[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" 

我已经设置了可以在这里找到一个工作玩具例子:git的克隆-b玩具https://bitbucket.org/mrdut/precompiled_header.git

有没有人有什么建议吗?

由于提前,

这里是我的项目的内容:

run.sh 
CMakeLists.txt 
src/ 
    lib/ 
     dir1/file1.cpp, file1.hpp 
     dir2/file2.cpp, file2.hpp 
    bin/main.cpp 

run.sh:

mkdir build 
cd build/ 
cmake .. && make VERBOSE=1 && ./bin/prog 
cd .. 

CMakeslist.txt:

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) # <= 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() 

SRC /header.hpp:

#ifndef HEADER_HPP 
#define HEADER_HPP 
    #include <iostream> 
#endif 

SRC/bin中/ main.cpp中:

#include "lib/dir1/file1.hpp" 
#include "lib/dir2/file2.hpp" 
int main(int argc, char** argv) 
{ 
    std::cout << "\n -= " << argv[0] << " =-\n"; 
    libfunc1(); 
    libfunc2(); 
    return 0; 
} 

SRC/lib.dir1/file1.cpp:

#include "lib/dir1/file1.hpp" 
void libfunc1() { std::cout << "function 1" << std::endl; } 

SRC/lib.dir1/file1.hpp:

#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 

的src/lib.dir2/file2.cpp:

#include "lib/dir2/file2.hpp" 
void libfunc2() { std::cout << "function 2" << std::endl; } 

的src/lib.dir1/file2.hpp:

#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 
+0

'我必须设法构建库(与预编译头),但我有建设main'时,一个奇怪的编译错误 - 请提供你的代码[MCVE(HTTP的形式:// stackoverflow.com/help/mcve)和错误消息,这是由代码引起的。 – Tsyvarev

+0

感谢您的建议,我更新了我的帖子 – flod

回答

0

因为file1.hppfile2.hpp包括您precompiled_header.hpp你需要预编译它们也使事情工作。

从GCC预编译头documentation

一旦该第一C令牌被认为是预编译的报头不能被使用。在预编译头文件之前可以有预处理程序指令; 您不能在另一个标头中包含预编译头。

0

它似乎工作,如果我首先包括预编译头在主要的其他头。CPP

#ifdef USE_PRECOMPILED 
    #include "precompiled_header.hpp" 
    #undef USE_PRECOMPILED 
#endif 
+0

这样一种方式,您可以使用'main.cpp'中的正常头文件'header.hpp'和'file.hpp'中的预编译precompiled_header.hpp'(也包括' main.cpp')。这样的使用只是消除了预编译头的需求,这可能不是你想要的。 – Tsyvarev