function(get_relative_link OUTPUT PATH) if (PATH MATCHES "^[$]<[$]:") set(${OUTPUT} "" PARENT_SCOPE) return() endif() string(REGEX REPLACE "^[$]<[$]>:(.*)>$" "\\1" PATH "${PATH}") get_filename_component(NAME "${PATH}" NAME_WE) if (IS_ABSOLUTE ${PATH}) get_filename_component(DIRECTORY_NAME "${PATH}" DIRECTORY) 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() if (NOT WIN32 AND NAME MATCHES "^lib") string(REGEX REPLACE "^lib" "-l" LINK "${NAME}") elseif (NAME MATCHES "^-") set(LINK "${NAME}") else() string(CONCAT LINK "-l" "${NAME}") endif() set(${OUTPUT} "${LINK}" PARENT_SCOPE) endfunction() function(generate_pkgconfig TARGET DESCRIPTION) # message("Generating pkg-config for ${TARGET}") get_filename_component(PREFIX "${CMAKE_INSTALL_PREFIX}" REALPATH) 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}" STREQUAL "") list(APPEND LIBS "${LINK}") endif() endif() endforeach() if (HAS_REQS) set(REQUIRES "") foreach (REQ ${REQS}) set(REQUIRES "${REQUIRES} ${REQ}") endforeach() set(REQUIRES "Requires.private:${REQUIRES}\n") endif() if (HAS_LIBS) set(LIBRARIES "") list(REVERSE LIBS) list(REMOVE_DUPLICATES LIBS) foreach (LIB ${LIBS}) set(LIBRARIES " ${LIB}${LIBRARIES}") endforeach() set(LIBRARIES "Libs.private:${LIBRARIES}\n") endif() if (IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}") set(PKGCONFIG_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}") else() set(PKGCONFIG_INCLUDEDIR "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") endif() if (IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}") set(PKGCONFIG_LIBDIR "${CMAKE_INSTALL_LIBDIR}") else() set(PKGCONFIG_LIBDIR "\${prefix}/${CMAKE_INSTALL_LIBDIR}") 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} Name: ${TARGET} Description: ${DESCRIPTION} Version: ${PROJECT_VERSION} CFlags: -I\"${PKGCONFIG_INCLUDEDIR}\"${CFLAGS_DEFS} ${LIBS_LINE} ${REQUIRES}${LIBRARIES}") 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") else() message(FATAL_ERROR "Don't know how to handle ${TARGET} of type ${LIBRARY_TYPE}") endif() endfunction()