gpt4 book ai didi

CMake:带有生成文件的仅 header 库

转载 作者:行者123 更新时间:2023-12-04 02:15:05 24 4
gpt4 key购买 nike

我有一个库,它需要携带一些从非源文件的内容(在本例中为 OpenGL 着色器代码)注入(inject)的常量数据。为此,我使用 add_custom_command()生成包含文件,然后我可以 #include进入我的代码以初始化 const 静态变量。

这与常规库(静态或共享)完美配合,但现在我想让我的库只包含标题。 C++ 允许静态方法返回静态数据而不冒在每个翻译单元中复制该数据的风险(“魔术静态”)的能力使这成为可能。

然而,问题是 CMake 似乎假设 INTERFACE 库(这是我用来创建仅 header 库的 CMake 功能)不需要构建 - 在这种情况下,这是错误的。

(我意识到我的库没有实际义务仅是 header 。在这种特殊情况下,我想要这样做的原因是我希望正在执行 OpenGL 的库保持独立于任何特定的绑定(bind)库 [例如 GLEWGLee 或新人 glbinding ]。通过保留我的库标题,我可以将选择留给用户 - 他需要做的只是 #include 之前绑定(bind)库的标题矿。)

最迟在构建消费者项目时,有没有人看到让 CMake 触发生成 header 的自定义命令的方法?

编辑:我刚刚意识到我可以拥有“两全其美”,因为它保持我的库静态但仍然保留我的所有代码,除了头文件中的常量数据。这样,仍然不需要选择特定的 OpenGL 绑定(bind)库。
然而,让一个库只包含标题仍然有好处——一个简单的使用——所以我把我的问题悬而未决。

编辑#2:这是我的 CMakeLists.txt 的相关部分文件(我只从最后剥离了库依赖项 - 所有仅头文件):

set(SHADER_FILES "src/vertex.glsl" "src/fragment.glsl")

add_library(libGPCGUIGLRenderer INTERFACE)
target_sources(libGPCGUIGLRenderer INTERFACE ${SHADER_FILES})

target_include_directories(libGPCGUIGLRenderer BEFORE
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)

# Embed shader files

source_group("Shader files" FILES ${SHADER_FILES})

set(GENERATED "${CMAKE_CURRENT_BINARY_DIR}/generated")
target_include_directories(libGPCGUIGLRenderer INTERFACE ${GENERATED})

# Find the GPC Bin2C utility
find_package(GPCBin2C REQUIRED)

# Add a custom target and a dependency for each shader file
foreach(shader ${SHADER_FILES})
get_filename_component(name "${shader}" NAME)
set(shader_header "${GENERATED}/${name}.h")
add_custom_command(
OUTPUT ${shader_header}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${shader}
COMMAND GPCBin2C --input=${CMAKE_CURRENT_SOURCE_DIR}/${shader} --output=${shader_header}
)
target_sources(libGPCGUIGLRenderer INTERFACE ${shader_header})
endforeach()

最佳答案

创建一个以标题为唯一来源的静态库对我有用。当然,这只是一种变通方法。

  • 创建仅包含头文件的静态库会导致库为空。我说 !<arch>作为唯一的内容。
  • CMake 将自动跨子目录获取正确的依赖关系。
  • 由于所有来源都是 header ,因此您需要告诉 CMake 应该使用哪种链接器语言。

  • 代码:
    set(OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/generated_include")
    add_custom_command(
    OUTPUT "${OUTDIR}/outfile.h"
    # Replace the next two lines with a proper generating script.
    COMMAND mkdir -p ${OUTDIR}
    COMMAND touch ${OUTDIR}/outfile.h
    )

    # Note, I am only adding header files to the library.
    add_library(generated-headers STATIC
    "${OUTDIR}/outfile.h"
    )
    set_target_properties(generated-headers
    PROPERTIES LINKER_LANGUAGE CXX)
    target_include_directories(generated-headers PUBLIC ${OUTDIR})

    在其他目录中使用,如下所示:
    # In any other directory of the same CMake project:
    add_executable(main main.cpp)
    target_link_libraries(main generated-headers)

    在 CMake 3.2、3.8 和 3.9 上测试。使用 Ninja 和 Make 生成器。

    关于CMake:带有生成文件的仅 header 库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28421943/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com