编译特定的生成的源文件时,如何指定要使用的包含目录?

时间:2020-07-08 19:45:28

标签: cmake

我有CMakeLists.txt

add_custom_command(OUTPUT chattr.tab.cpp
  DEPENDS table_gen
  COMMAND ./table_gen > chattr.tab.cpp
)

这会将生成的源文件chattr.tab.cpp放在对象目录中(这是我想要的)。但是,结果是#include "someheader.h"中的chattr.tab.cpp找不到源目录中的标头。

此生成的文件仅添加到某些目标。有没有办法在编译生成的源文件(到CMakeFiles/sometarget.dir/chattr.tab.cpp.o时,并且仅在编译该源文件时,添加一些包含目录?而不是将include目录添加到使用它的所有目标?后者将需要添加多个target_include_directories(),并将导致包含文件用于该目标的每个源文件,而不仅仅是生成的源文件。

编辑:

根据squareskittles的答案,我生成了以下CMakeLists.txt文件(仅显示底部):

....
#=================================================================
# GENERATED SOURCE FILES
#

add_executable(table_gen table_gen.cxx)

add_custom_command(OUTPUT chattr.tab.cpp
  DEPENDS table_gen
  COMMAND ./table_gen > chattr.tab.cpp
)

add_custom_command(OUTPUT PgnGrammar.h
  DEPENDS generate_PgnGrammar.h.sh
  COMMAND ${CMAKE_CURRENT_LIST_DIR}/generate_PgnGrammar.h.sh
)

set(GENERATED_SOURCES chattr.tab.cpp PgnGrammar.h)

set_source_files_properties(chattr.tab.cpp PROPERTIES
  INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}"  # For local header files.
)

#=================================================================
# TEST EXECUTABLES
#

add_executable(tstchessposition tstchessposition.cxx)
target_link_libraries(tstchessposition PRIVATE AICxx::cwchessboard AICxx::cwds)

add_executable(tstbenchmark tstbenchmark.cxx)
target_link_libraries(tstbenchmark PRIVATE AICxx::cwchessboard AICxx::cwds)

add_executable(tstpgnread tstpgnread.cxx PgnDatabase.cxx MemoryBlockList.cxx ${GENERATED_SOURCES})
target_link_libraries(tstpgnread PRIVATE AICxx::cwchessboard AICxx::cwds)

add_executable(tsticonv tsticonv.cxx)
target_link_libraries(tsticonv PRIVATE PkgConfig::glibmm)

add_executable(tstpgn tstpgn.cxx PgnDatabase.cxx MemoryBlockList.cxx ${GENERATED_SOURCES})
target_link_libraries(tstpgn PRIVATE AICxx::cwchessboard AICxx::cwds)

add_executable(tstspirit tstspirit.cxx PgnGrammar.h)
target_include_directories(tstspirit PUBLIC "${top_objdir}")

但这会导致:

[ 51%] Generating chattr.tab.cpp
./table_gen > chattr.tab.cpp
[ 54%] Generating chattr.tab.cpp
./table_gen > chattr.tab.cpp

显然,因为tstpgnreadtstpgn都与chattr.tab.cpp链接,所以它生成两次?!这是CMake中的错误,还是我做错了其他事情?

2 个答案:

答案 0 :(得分:1)

我最终创建了所生成源文件的OBJECT库,然后与之“链接”:

...
#================================================================
# GENERATED SOURCE FILES
#

add_executable(table_gen table_gen.cxx)

add_custom_command(OUTPUT chattr.tab.cpp
  DEPENDS table_gen
  COMMAND ./table_gen > chattr.tab.cpp
)

add_custom_command(OUTPUT PgnGrammar.h
  DEPENDS generate_PgnGrammar.h.sh
  COMMAND ${CMAKE_CURRENT_LIST_DIR}/generate_PgnGrammar.h.sh
)

add_library(generated_ObjLib OBJECT)
target_sources(generated_ObjLib
  PRIVATE
    "chattr.tab.cpp"
    "PgnGrammar.h"
)

target_include_directories(generated_ObjLib
  PRIVATE
    "${CMAKE_CURRENT_SOURCE_DIR}" # For local header files.
)

add_library(generated::sources ALIAS generated_ObjLib)

#==================================================================
# TEST EXECUTABLES
#

add_executable(tstchessposition tstchessposition.cxx)
target_link_libraries(tstchessposition PRIVATE CWChessboard::position AICxx::cwds)

add_executable(tstbenchmark tstbenchmark.cxx)
target_link_libraries(tstbenchmark PRIVATE CWChessboard::position AICxx::cwds)

add_executable(tstpgnread tstpgnread.cxx PgnDatabase.cxx MemoryBlockList.cxx)
target_link_libraries(tstpgnread PRIVATE generated::sources CWChessboard::position AICxx::cwds)

add_executable(tsticonv tsticonv.cxx)
target_link_libraries(tsticonv PRIVATE PkgConfig::glibmm)

add_executable(tstpgn tstpgn.cxx PgnDatabase.cxx MemoryBlockList.cxx)
target_link_libraries(tstpgn PRIVATE generated::sources CWChessboard::position AICxx::cwds)

add_executable(tstspirit tstspirit.cxx PgnGrammar.h)
target_include_directories(tstspirit PUBLIC "${top_objdir}")

技巧为add_library(generated_ObjLib OBJECT)及以下,然后与generated::sources关联。

答案 1 :(得分:0)

与“ override compile flags for single files”帖子一样,您可以为单个文件修改INCLUDE_DIRECTORIES源文件属性:

set_source_files_properties(chattr.tab.cpp PROPERTIES 
    INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/other/include/dir
)
相关问题