假设我有一个包含一系列库的项目。我还需要生成一个将由所有这些项目使用的头文件。所以我创建了一个CMake文件,如下所示:
project(main)
add_subdirectory(sub_1)
add_subdirectory(sub_2)
# ...
add_subdirectory(sub_n)
add_custom_command(
OUTPUT CustomHeader.h
COMMENT "Generating custom header for all the libraries"
COMMAND ...)
add_library(${PROJECT_NAME} STATIC ${OBJECT_LIST})
问题是,我不知道如何告诉CMake运行我的自定义命令(生成此CustomHeader.h
)之前它会尝试在子文件夹中构建库
我尝试add_custom_target(TARGET MyPrebuild PRE_BUILD ...)
但我在Linux上运行,此选项仅适用于documentation的Windows平台。
add_dependencies
仅在目标之间工作,而不是目标和单个文件。
理论上,我可以将标题添加到各个库的源文件中(在sub_1,..,sub_n文件夹中),但感觉不对,因为标题不需要是这些库的一部分
所以我根本不知道如何让一个库依赖于一个包含文件,而不是它的一部分。
如何解决这个问题?
答案 0 :(得分:1)
对于在编译子目录中的库之前构建的make头文件(re),您可以创建 target ,它构建文件,并使库依赖于目标:
# *CMakeLists.txt*
# ...
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/CustomHeader.h ...)
add_custom_target(generate_custom_header DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/CustomHeader.h)
# *sub/CMakeLists.txt*
# ...
add_library(libA ...)
add_dependencies(libA generate_custom_header)
您可以创建仅限标题的库,而不是使用add_dependencies
,它可以“实现”您的标题并与之链接:
# *CMakeLists.txt*
# ...
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/CustomHeader.h ...)
add_custom_target(generate_custom_header DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/CustomHeader.h)
add_library(libCustom INTERFACE) # Header only library
add_dependencies(libCustom generate_custom_header) # which depends on generated header
# You may even assign include directories for the header-only library
target_include_directories(libCustom INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
# *sub/CMakeLists.txt*
# ...
add_library(libA ...)
target_link_libraries(libA libCustom) # Common linking with a header-only library.
请注意, INTERFACE 库是“假的” - 它永远不会自行创建。相反, INTERFACE 库的所有“功能”都只会传播给其用户。
答案 1 :(得分:0)
我建议添加另一个库目标,它将跟踪生成的标题,并有助于正确配置其他库以了解在哪里找到它们(即target_include_directories
)。
cmake_minimum_required(VERSION 3.0)
project(testable)
set(CustomHeaderInPath ${CMAKE_CURRENT_SOURCE_DIR}/CustomHeader.example)
set(CustomHeaderPath ${CMAKE_CURRENT_BINARY_DIR}/CustomHeader.h)
add_custom_command(
OUTPUT ${CustomHeaderPath}
COMMAND cp ${CustomHeaderInPath} ${CustomHeaderPath}
COMMENT "Generated file"
DEPENDS ${CustomHeaderInPath})
add_library(CustomHeaderLibrary ${CustomHeaderPath})
target_include_directories(CustomHeaderLibrary PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
set_target_properties(CustomHeaderLibrary PROPERTIES LINKER_LANGUAGE C)
add_library(LibA a.c)
target_link_libraries(LibA CustomHeaderLibrary)
add_library(LibB b.c)
target_link_libraries(LibB CustomHeaderLibrary)
add_executable(${PROJECT_NAME} main.c)
target_link_libraries(${PROJECT_NAME} PUBLIC LibA LibB)
请注意,我必须明确设置新目标的LINKER_LANGUAGE
,因为如果没有将c
或cpp
文件添加到库中,cmake将无法正确推断它