在CMake项目中带有前缀的头文件

时间:2016-08-10 17:21:32

标签: build cmake

我已经设置了一个CMake项目,其目录结构如下所示:

src/
--CMakeLists.txt
--libA/
----CMakeLists.txt
----foo.h
----foo.cpp
--main/
----CMakeLists.txt
----main.cpp

src/CMakeLists.txt使用add_subdirectory来引入libAmainlibA/CMakeLists.txt使用add_library来定义名为libA的库,该库通过foo.h导出target_include_directories。如果我现在使用libAmain中的target_link_library相关联,我可以foo.h通过#include <foo.h>添加main.cpp

问题:是否可以为libA的公共接口提供前缀,以便我可以(并且必须)在#include <libA/foo.h>中写main.cpp而不是?

2 个答案:

答案 0 :(得分:0)

这是一个老问题,但是我遇到了完全相同的问题。我最后通过添加一个export_headers()函数来解决这个问题,该函数创建指向二进制文件头的符号链接:

function(export_headers TARGET HEADER_SOURCE_DIR HEADER_DEST_DIR)

    # Put all headers that are in the source directory into EXPORT_HEADERS variable
    file(GLOB_RECURSE EXPORT_HEADERS CONFIGURE_DEPENDS 
        RELATIVE "${HEADER_SOURCE_DIR}" 
        "${HEADER_SOURCE_DIR}/*.h"
    )

    # For each header that will be exported
    foreach(HEADER ${EXPORT_HEADERS})

        # Get the directory portion that needs to be created        
        get_filename_component(HEADER_DIRECTORY "${HEADER}" DIRECTORY)

        # Create the directory  
        add_custom_command(TARGET ${TARGET} POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E make_directory "${HEADER_DEST_DIR}/${HEADER_DIRECTORY}"
        )

        if (MSVC)

            # Make a hard link to the file
            add_custom_command(TARGET ${TARGET} POST_BUILD
                COMMAND if not exist "${HEADER_DEST_DIR}/${HEADER}" \( mklink /h "${HEADER_DEST_DIR}/${HEADER}" "${HEADER_SOURCE_DIR}/${HEADER}" \) 
            )

        else()

            # Make a symbolic link to the file
            add_custom_command(TARGET ${TARGET} POST_BUILD
                COMMAND ln -sf "${HEADER_SOURCE_DIR}/${HEADER}" "${HEADER_DEST_DIR}/${HEADER}"
            )

        endif()


    endforeach(HEADER)

endfunction()

您可以这样称呼它:

add_library(libA STATIC ${LIBA_SOURCES}
export_headers(libA ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/include/libA)
target_include_directories(libA INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/include)

然后,如果您链​​接到libA,则可以#include <libA/foo.h>

答案 1 :(得分:0)

您可以在libA调用中使用 base 源目录(或target_include_directories()的父目录)。这样将允许INTERFACE_INCLUDE_DIRECTORIES目标属性相对于另一个目录(在本示例中为CMAKE_SOURCE_DIR)定义。所以看起来像这样:

libA/CMakeLists.txt中:

add_library(libA foo.cpp)
# Define the include files with respect to the directory above this.
target_include_directories(libA PUBLIC ${CMAKE_SOURCE_DIR})

main/main.cpp文件:

#include <iostream>
#include <libA/foo.h>

int main() {

    FooClass fooclass;
    fooclass.myFunction();

    std::cout << "Hello World!" << std::endl;
    return 0;
}