我想从目标中在CMake中生成pkgconfig文件。我开始写了类似于以下内容的东西:
function(auto_pkgconfig TARGET)
get_target_property(INCLUDE_DIRS ${TARGET} INTERFACE_INCLUDE_DIRECTORIES)
string(REPLACE "$<BUILD_INTERFACE:" "$<0:" INCLUDE_DIRS "${INCLUDE_DIRS}")
string(REPLACE "$<INSTALL_INTERFACE:" "$<1:" INCLUDE_DIRS "${INCLUDE_DIRS}")
string(REPLACE "$<INSTALL_PREFIX>" "${CMAKE_INSTALL_PREFIX}" INCLUDE_DIRS "${INCLUDE_DIRS}")
file(GENERATE OUTPUT ${TARGET}.pc CONTENT "
Name: ${TARGET}
Cflags: -I$<JOIN:${INCLUDE_DIRS}, -I>
Libs: -L${CMAKE_INSTALL_PREFIX}/lib -l${TARGET}
")
install(FILES ${TARGET}.pc DESTINATION lib/pkgconfig)
endfunction()
这是一个简化版本,但基本上它会读取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
更改为以下内容:
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()
然而,这将读取BUILD_INTERFACE
而不是INSTALL_INTERFACE
。那么在设置好目标属性后,是否有另一种方法来读取它们?