这是一个简化的版本,但基本上读取了
INTERFACE_INCLUDE_DIRECTORIES
属性并处理发电机表达式的
INSTALL_INTERFACE
。 只要在调用
auto_pkgconfig
之前设置包含目录,就可以很好地效果:add_library(foo foo.cpp)
target_include_directories(foo PUBLIC
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>
${OTHER_INCLUDE_DIRS}
)
auto_pkgconfig(foo)
,有时会在呼叫之后设置属性,如这样:
auto_pkgconfig
,但是,这将无法正确读取包含目录。我希望在设置所有目标属性后运行。我可以通过更改以下方式来使用发电机表达式:
add_library(foo foo.cpp)
auto_pkgconfig(foo)
target_include_directories(foo PUBLIC
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>
${OTHER_INCLUDE_DIRS}
)
,但是,这将读取
auto_pkgconfig
而不是
auto_pkgconfig
。因此,是否有另一种方法可以在设置目标属性后读取目标属性?
根据cmakeDocumentation
,仅在调用
function(auto_pkgconfig TARGET)
file(GENERATE OUTPUT ${TARGET}.pc CONTENT "
Name: ${TARGET}
Cflags: -I$<JOIN:$<TARGET_PROPERTY:${TARGET},INTERFACE_INCLUDE_DIRECTORIES>, -I>
Libs: -L$<TARGET_FILE_DIR:${TARGET}> -l${TARGET}
")
install(FILES ${TARGET}.pc DESTINATION lib/pkgconfig)
endfunction()
时可用。除非它们扩展Cmake,否则最好做其他事情来生成您的pkgconfig文件。理想情况下,您将对安装布局有足够的控制来简化此功能。
ever,这并不意味着您不能做自己问的事情;只是“小马托尼”邪恶的水平。我实际上犹豫要发布此信息。请不要将其作为建议。
BUILD_INTERFACE
代码的虚拟cmakeproject;虚拟项目将看到导出的,即。
INSTALL_INTERFACE
属性
i最初试图使用
INSTALL_INTERFACE
来做到这一点,但它也可以看到install(EXPORT)
视图。我已经在cmake话语上问了一下。
install(EXPORT)
这将导致以下结果:
file(GENERATE OUTPUT ...)
这应该让你难过。这让我难过。
Edit:关闭主题,因为在这里,PC文件是手动生成的PKGCONFIG模板文件
动力:
cmakelists.txt应该是真理的单一来源(名称,版本)
PKGCONFIG文件比CMake文件小约10倍(CMAKE到PKGCONFIG是一个有损的转换) themplate文件:INSTALL_INTERFACE
install(CODE [[ ... ]])
$<BUILD_INTERFACE:...>
cmake_minimum_required(VERSION 3.16)
project(example)
# Dummy library for demo
add_library(example SHARED example.cpp)
target_compile_definitions(example
PUBLIC $<BUILD_INTERFACE:BUILD>
$<INSTALL_INTERFACE:INSTALL>)
target_include_directories(example
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>)
# Here be dragons...
function(auto_pc TARGET)
file(CONFIGURE OUTPUT "pc.${TARGET}/CMakeLists.txt"
CONTENT [[
cmake_minimum_required(VERSION 3.16)
project(pc_@TARGET@)
find_package(pc_@TARGET@ REQUIRED CONFIG)
file(GENERATE OUTPUT @[email protected]
CONTENT [=[
Name: @TARGET@
Cflags: -I$<JOIN:$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>, -I> -D$<JOIN:$<TARGET_PROPERTY:INTERFACE_COMPILE_DEFINITIONS>, -D>
Libs: -L$<TARGET_FILE_DIR:@TARGET@> -l@TARGET@
]=] TARGET "@TARGET@")
]] @ONLY NEWLINE_STYLE LF)
install(TARGETS ${TARGET} EXPORT pc_${TARGET})
install(EXPORT pc_${TARGET} DESTINATION "_auto_pc" FILE pc_${TARGET}-config.cmake)
file(CONFIGURE OUTPUT "pc.${TARGET}/post-install.cmake"
CONTENT [[
file(REAL_PATH "${CMAKE_INSTALL_PREFIX}" prefix)
set(proj "@CMAKE_CURRENT_BINARY_DIR@/pc.@TARGET@")
execute_process(COMMAND "@CMAKE_COMMAND@" "-Dpc_@TARGET@_DIR=${prefix}/_auto_pc" -S "${proj}" -B "${proj}/build")
file(COPY "${proj}/build/@[email protected]" DESTINATION "${prefix}")
]] @ONLY NEWLINE_STYLE LF)
install(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/pc.${TARGET}/post-install.cmake")
endfunction()
auto_pc(example)
# Clean up install path
install(CODE [[ file(REMOVE_RECURSE "${CMAKE_INSTALL_PREFIX}/_auto_pc") ]])
基于:cmake生成pkg-config.pc
进出目标cmake文件