如何从目标中获取包含目录以便在 add_custom_target 中使用?
How to get include directories from a target for use in add_custom_target?
我正在使用 target_link_libraries
建模依赖关系,正如在 this 博客 post 中所做的那样。
target_link_libraries(Foo
LibraryA
LibraryB
)
这很好用,但由于各种原因,我需要使用 add_custom_target
通过自定义命令预处理文件。问题是,这个自定义目标依赖于 LibraryA 和 LibraryB 的包含。我真的很希望像 target_link_libraries
的工作方式一样执行以下操作(参见 LibraryA 和 LibraryB 位):
add_custom_target(Bar ALL
COMMAND ${CMAKE_C_COMPILER} thing.cpp LibraryA LibraryB /P
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/Path/Here
COMMENT "Preprocessing to a file"
VERBATIM
)
但是,这不起作用。 LibraryA 和 LibraryB 按它们出现的样子放入。即使它确实有效,我想我会得到比包含更多的东西,因为我认为目标也包括库。也许这不是一个好方法。
那么,我可以在这里做什么?如何从每个目标中提取包含目录,以便在自定义命令中使用?我发现如果我 find_package(Foo REQUIRED)
我可以访问 Foo_DIR
,但它指向构建目录而不是包含所在的源目录。
您可以使用 get_target_property()
. A target's INCLUDE_DIRECTORIES
property contains the include directories for that target. Since you have two targets, LibraryA
and LibraryB
, we have to call it twice. Then, we can concatenate the list of include directories together using foreach()
. If you are using these as include directories in a compiler command (such as MSVC), you can append the /I
compiler option 从每个目标提取包含目录到循环中的每个目录:
# Get the include directories for the target.
get_target_property(LIBA_INCLUDES LibraryA INCLUDE_DIRECTORIES)
get_target_property(LIBB_INCLUDES LibraryB INCLUDE_DIRECTORIES)
# Construct the compiler string for the include directories.
foreach(dir ${LIBA_INCLUDES} ${LIBB_INCLUDES})
string(APPEND INCLUDE_COMPILER_STRING "/I${dir} ")
endforeach()
然后,您可以使用构造的INCLUDE_COMPILER_STRING
变量调用自定义目标命令:
add_custom_target(Bar ALL
COMMAND ${CMAKE_C_COMPILER} thing.cpp ${INCLUDE_COMPILER_STRING} /P
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/Path/Here
COMMENT "Preprocessing to a file"
VERBATIM
)
如果您想要更简洁的内容,可以使用生成器表达式示例 here,它会在您的自定义目标命令中获取目标的包含目录并内联扩展它们。像这样的东西也可以工作:
add_custom_target(Bar ALL
COMMAND ${CMAKE_C_COMPILER} thing.cpp
"/I$<JOIN:$<TARGET_PROPERTY:LibraryA,INCLUDE_DIRECTORIES>,;/I>"
"/I$<JOIN:$<TARGET_PROPERTY:LibraryB,INCLUDE_DIRECTORIES>,;/I>"
/P
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/Path/Here
COMMENT "Preprocessing to a file"
VERBATIM
COMMAND_EXPAND_LISTS
)
我正在使用 target_link_libraries
建模依赖关系,正如在 this 博客 post 中所做的那样。
target_link_libraries(Foo
LibraryA
LibraryB
)
这很好用,但由于各种原因,我需要使用 add_custom_target
通过自定义命令预处理文件。问题是,这个自定义目标依赖于 LibraryA 和 LibraryB 的包含。我真的很希望像 target_link_libraries
的工作方式一样执行以下操作(参见 LibraryA 和 LibraryB 位):
add_custom_target(Bar ALL
COMMAND ${CMAKE_C_COMPILER} thing.cpp LibraryA LibraryB /P
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/Path/Here
COMMENT "Preprocessing to a file"
VERBATIM
)
但是,这不起作用。 LibraryA 和 LibraryB 按它们出现的样子放入。即使它确实有效,我想我会得到比包含更多的东西,因为我认为目标也包括库。也许这不是一个好方法。
那么,我可以在这里做什么?如何从每个目标中提取包含目录,以便在自定义命令中使用?我发现如果我 find_package(Foo REQUIRED)
我可以访问 Foo_DIR
,但它指向构建目录而不是包含所在的源目录。
您可以使用 get_target_property()
. A target's INCLUDE_DIRECTORIES
property contains the include directories for that target. Since you have two targets, LibraryA
and LibraryB
, we have to call it twice. Then, we can concatenate the list of include directories together using foreach()
. If you are using these as include directories in a compiler command (such as MSVC), you can append the /I
compiler option 从每个目标提取包含目录到循环中的每个目录:
# Get the include directories for the target.
get_target_property(LIBA_INCLUDES LibraryA INCLUDE_DIRECTORIES)
get_target_property(LIBB_INCLUDES LibraryB INCLUDE_DIRECTORIES)
# Construct the compiler string for the include directories.
foreach(dir ${LIBA_INCLUDES} ${LIBB_INCLUDES})
string(APPEND INCLUDE_COMPILER_STRING "/I${dir} ")
endforeach()
然后,您可以使用构造的INCLUDE_COMPILER_STRING
变量调用自定义目标命令:
add_custom_target(Bar ALL
COMMAND ${CMAKE_C_COMPILER} thing.cpp ${INCLUDE_COMPILER_STRING} /P
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/Path/Here
COMMENT "Preprocessing to a file"
VERBATIM
)
如果您想要更简洁的内容,可以使用生成器表达式示例 here,它会在您的自定义目标命令中获取目标的包含目录并内联扩展它们。像这样的东西也可以工作:
add_custom_target(Bar ALL
COMMAND ${CMAKE_C_COMPILER} thing.cpp
"/I$<JOIN:$<TARGET_PROPERTY:LibraryA,INCLUDE_DIRECTORIES>,;/I>"
"/I$<JOIN:$<TARGET_PROPERTY:LibraryB,INCLUDE_DIRECTORIES>,;/I>"
/P
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/Path/Here
COMMENT "Preprocessing to a file"
VERBATIM
COMMAND_EXPAND_LISTS
)