diff --git a/CMake/GeneratePkgConfig.cmake b/CMake/GeneratePkgConfig.cmake index 3d3fa01d1f69..4cbdb15d9336 100644 --- a/CMake/GeneratePkgConfig.cmake +++ b/CMake/GeneratePkgConfig.cmake @@ -8,12 +8,13 @@ function(get_relative_link OUTPUT PATH) get_filename_component(NAME "${PATH}" NAME_WE) if (IS_ABSOLUTE ${PATH}) get_filename_component(DIRECTORY_NAME "${PATH}" DIRECTORY) - if (WIN32) - set(${OUTPUT} "-l\"${DIRECTORY_NAME}/${NAME}\"" PARENT_SCOPE) - else() - get_filename_component(FULL_NAME "${PATH}" NAME) - set(${OUTPUT} "-L\"${DIRECTORY_NAME}\" -l:${FULL_NAME}" PARENT_SCOPE) + get_filename_component(FULL_NAME "${PATH}" NAME) + string(REGEX REPLACE "^lib([^.]+).*$" "\\1" LIB_NAME "${FULL_NAME}") + # If the regex didn't match (no lib prefix), fall back to name without extension + if ("${LIB_NAME}" STREQUAL "${FULL_NAME}") + set(LIB_NAME "${NAME}") endif() + set(${OUTPUT} "-L\"${DIRECTORY_NAME}\" -l${LIB_NAME}" PARENT_SCOPE) return() endif() @@ -31,17 +32,58 @@ function(generate_pkgconfig TARGET DESCRIPTION) # message("Generating pkg-config for ${TARGET}") get_filename_component(PREFIX "${CMAKE_INSTALL_PREFIX}" REALPATH) - get_target_property(LIST "${TARGET}" LINK_LIBRARIES) + get_target_property(LIBRARY_TYPE "${TARGET}" TYPE) + if ("${LIBRARY_TYPE}" STREQUAL "INTERFACE_LIBRARY") + get_target_property(LIST "${TARGET}" INTERFACE_LINK_LIBRARIES) + else() + get_target_property(LIST "${TARGET}" LINK_LIBRARIES) + endif() + + if ("${LIST}" STREQUAL "LIST-NOTFOUND") + set(LIST "") + endif() + + set(INTERFACE_LIBS "") + if ("${LIBRARY_TYPE}" STREQUAL "INTERFACE_LIBRARY") + set(PROPAGATED "") + foreach (DEP ${LIST}) + if (TARGET "${DEP}") + get_target_property(DEP_TYPE "${DEP}" TYPE) + if ("${DEP_TYPE}" STREQUAL "STATIC_LIBRARY" OR "${DEP_TYPE}" STREQUAL "SHARED_LIBRARY") + list(APPEND INTERFACE_LIBS "${DEP}") + get_target_property(DEP_LIBS "${DEP}" LINK_LIBRARIES) + if (NOT "${DEP_LIBS}" STREQUAL "DEP_LIBS-NOTFOUND") + list(APPEND PROPAGATED ${DEP_LIBS}) + endif() + else() + list(APPEND PROPAGATED "${DEP}") + endif() + else() + list(APPEND PROPAGATED "${DEP}") + endif() + endforeach() + if (PROPAGATED) + list(REMOVE_DUPLICATES PROPAGATED) + endif() + set(LIST "${PROPAGATED}") + endif() + set(REQS "") set(LIBS "") foreach (LIB ${LIST}) if (TARGET "${LIB}") + if ("${LIBRARY_TYPE}" STREQUAL "SHARED_LIBRARY") + get_target_property(LIB_TYPE "${LIB}" TYPE) + if ("${LIB_TYPE}" STREQUAL "STATIC_LIBRARY") + continue() + endif() + endif() set(HAS_REQS 1) list(APPEND REQS "${LIB}") else() set(HAS_LIBS 1) get_relative_link(LINK "${LIB}") - if (NOT LINK EQUAL "") + if (NOT "${LINK}" STREQUAL "") list(APPEND LIBS "${LINK}") endif() endif() @@ -77,6 +119,36 @@ function(generate_pkgconfig TARGET DESCRIPTION) endif() file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/pkgconfig") + + get_target_property(TARGET_OUTPUT_NAME "${TARGET}" OUTPUT_NAME) + if ("${TARGET_OUTPUT_NAME}" STREQUAL "TARGET_OUTPUT_NAME-NOTFOUND") + set(TARGET_OUTPUT_NAME "${TARGET}") + endif() + + if ("${LIBRARY_TYPE}" STREQUAL "INTERFACE_LIBRARY") + set(LIBS_LINE "") + foreach (ILIB ${INTERFACE_LIBS}) + get_target_property(ILIB_OUTPUT_NAME "${ILIB}" OUTPUT_NAME) + if ("${ILIB_OUTPUT_NAME}" STREQUAL "ILIB_OUTPUT_NAME-NOTFOUND") + set(ILIB_OUTPUT_NAME "${ILIB}") + endif() + set(LIBS_LINE "${LIBS_LINE} -l${ILIB_OUTPUT_NAME}") + endforeach() + set(LIBS_LINE "Libs: -L\"${PKGCONFIG_LIBDIR}\"${LIBS_LINE}") + else() + set(LIBS_LINE "Libs: -L\"${PKGCONFIG_LIBDIR}\" -l${TARGET_OUTPUT_NAME}") + endif() + + get_target_property(_td_iface_defs "${TARGET}" INTERFACE_COMPILE_DEFINITIONS) + set(CFLAGS_DEFS "") + if (NOT "${_td_iface_defs}" STREQUAL "_td_iface_defs-NOTFOUND") + foreach(_def ${_td_iface_defs}) + string(APPEND CFLAGS_DEFS " -D${_def}") + endforeach() + unset(_def) + endif() + unset(_td_iface_defs) + file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/${TARGET}.pc" CONTENT "prefix=${PREFIX} @@ -84,15 +156,13 @@ Name: ${TARGET} Description: ${DESCRIPTION} Version: ${PROJECT_VERSION} -CFlags: -I\"${PKGCONFIG_INCLUDEDIR}\" -Libs: -L\"${PKGCONFIG_LIBDIR}\" -l${TARGET} +CFlags: -I\"${PKGCONFIG_INCLUDEDIR}\"${CFLAGS_DEFS} +${LIBS_LINE} ${REQUIRES}${LIBRARIES}") - get_target_property(LIBRARY_TYPE "${TARGET}" TYPE) - if (LIBRARY_TYPE STREQUAL "STATIC_LIBRARY" OR LIBRARY_TYPE STREQUAL "SHARED_LIBRARY") + if ("${LIBRARY_TYPE}" STREQUAL "STATIC_LIBRARY" OR "${LIBRARY_TYPE}" STREQUAL "SHARED_LIBRARY" OR + "${LIBRARY_TYPE}" STREQUAL "INTERFACE_LIBRARY") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/${TARGET}.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") - elseif (LIBRARY_TYPE STREQUAL "INTERFACE_LIBRARY") - # TODO: support interface libraries else() message(FATAL_ERROR "Don't know how to handle ${TARGET} of type ${LIBRARY_TYPE}") endif()