I would like to generate pkgconfig files in cmake from the targets. I started by writing something like this:
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()
This is a simplified version but it basically reads the INTERFACE_INCLUDE_DIRECTORIES
properties and processes the INSTALL_INTERFACE
of the generator expressions.
This works well as long as the include directories are set before calling auto_pkgconfig
, like this:
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)
However, sometimes properties are set after the call to auto_pkgconfig
, like this:
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}
)
However, this won't properly read the include directories anymore. I would like auto_pkgconfig
to run after all the target properties are set. I could use generator expressions for this, by changing auto_pkgconfig
to this:
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()
However, this will read the BUILD_INTERFACE
instead of the INSTALL_INTERFACE
. So is there another way to read target properties after they have been set?