库依赖于头文件

时间:2017-11-16 06:07:55

标签: cmake

假设我有一个包含一系列库的项目。我还需要生成一个将由所有这些项目使用的头文件。所以我创建了一个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文件夹中),但感觉不对,因为标题不需要是这些库的一部分

所以我根本不知道如何让一个库依赖于一个包含文件,而不是它的一部分。

如何解决这个问题?

2 个答案:

答案 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,因为如果没有将ccpp文件添加到库中,cmake将无法正确推断它