【问题标题】:Header files with prefix in CMake projectCMake项目中带有前缀的头文件
【发布时间】:2016-08-10 17:21:32
【问题描述】:

我建立了一个CMake项目,其目录结构如下:

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

src/CMakeLists.txt 使用add_subdirectory 拉入libA 和main。 libA/CMakeLists.txt 使用add_library 定义一个名为libA 的库,它通过target_include_directories 导出foo.h。如果我现在使用target_link_library 在main 中链接libA,我可以通过#include <foo.h> 在main.cpp 中包含foo.h。

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

【问题讨论】:

  • 此链接可能会有所帮助:stackoverflow.com/questions/19460707/…
  • 在target_include_directories 中包含根目录而不是libA 有什么问题?
  • @usr1234567 因为例如您希望可以选择在使用不提供前缀的子目录和使用具有该前缀的系统包之间切换。例如,在使用 Bullet 库时,不使用丑陋的#ifdefs 来区分#include <btVector3.h> 和#include <bullet/btVector3.h> 会很方便。
  • @MateuszDrost 这可能很方便,但它的风格很糟糕。

标签: build cmake


【解决方案1】:

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

在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;
}

【讨论】:

    【解决方案2】:

    这是一个老问题,但我遇到了完全相同的问题。我最终通过添加一个 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 &lt;libA/foo.h&gt;。

    【讨论】:

      猜你喜欢
      • 2023-03-17
      • 1970-01-01
      • 2019-05-18
      • 2014-04-28
      • 1970-01-01
      • 2014-08-14
      • 2022-01-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多