How to automatically create pkgconfig files from cmake targets

I would like to generate pkgconfig files in cmake from targets. I stared at 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 mainly reads properties INTERFACE_INCLUDE_DIRECTORIES

and processes INSTALL_INTERFACE

generator expression expressions. This works well as long as the include directories are set before the call auto_pkgconfig

, for example:

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 auto_pkgconfig

, for example:

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 will not read the include directories correctly. I would like to auto_pkgconfig

run after all target properties are set. I could use generator expressions auto_pkgconfig

for this , changing 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 be read BUILD_INTERFACE

instead INSTALL_INTERFACE

. So, is there any other way to read the target properties after they have been set?

+3


source to share





All Articles