function(qt_internal_collect_direct_target_dependencies target targets_out_var) __qt_internal_walk_libs("${target}" "${targets_out_var}" _rcc_objects "qt_direct_targets_dict" "direct_targets") set("${targets_out_var}" "${${targets_out_var}}" PARENT_SCOPE) endfunction() macro(qt_internal_set_pkg_config_cpp_flags var options flag) set(tmpopts "${options}") list(FILTER tmpopts EXCLUDE REGEX "\\$]+>") list(FILTER tmpopts EXCLUDE REGEX "\\$]+>") list(TRANSFORM tmpopts REPLACE "\\$<\\$]+>:([^,>]+)>" "\\1") list(TRANSFORM tmpopts REPLACE "\\$]+)>" "\\1") list(TRANSFORM tmpopts REPLACE ">" "$") list(TRANSFORM tmpopts REPLACE "," "$") set(${var} "$<$:${flag}$, ${flag}>>") unset(tmpopts) endmacro() # Create a Qt6*.pc file intended for pkg-config consumption. function(qt_internal_generate_pkg_config_file module) # TODO: PkgConfig is supported under MSVC with pkgconf (github.com/pkgconf/pkgconf) if((NOT UNIX OR QT_FEATURE_framework) AND NOT MINGW OR CMAKE_VERSION VERSION_LESS "3.20" OR ANDROID) return() endif() if(NOT BUILD_SHARED_LIBS) return() endif() set(pkgconfig_file "${QT_CMAKE_EXPORT_NAMESPACE}${module}") set(pkgconfig_name "${QT_CMAKE_EXPORT_NAMESPACE} ${module}") set(pkgconfig_description "Qt ${module} module") set(target "${QT_CMAKE_EXPORT_NAMESPACE}::${module}") set(is_interface_library "$,INTERFACE_LIBRARY>") # The flags macro expanded this variables so it's better to set them at # their corresponding PkgConfig string. set(includedir "\${includedir}") set(mkspecsdir "\${mkspecsdir}") get_target_property(is_internal_module ${target} _qt_is_internal_module) if(is_internal_module) return() endif() get_target_property(loose_link_options ${target} INTERFACE_LINK_OPTIONS) get_target_property(loose_compile_defs ${target} INTERFACE_COMPILE_DEFINITIONS) get_target_property(loose_include_dirs ${target} INTERFACE_INCLUDE_DIRECTORIES) list(TRANSFORM loose_include_dirs REPLACE "${INSTALL_INCLUDEDIR}" "\${includedir}") list(TRANSFORM loose_include_dirs REPLACE "${INSTALL_MKSPECSDIR}" "\${mkspecsdir}") qt_internal_set_pkg_config_cpp_flags(link_options "${loose_link_options}" "") qt_internal_set_pkg_config_cpp_flags(compile_defs "${loose_compile_defs}" -D) qt_internal_set_pkg_config_cpp_flags(include_dirs "${loose_include_dirs}" -I) if("${include_dirs}" MATCHES "\\${mkspecsdir}") set(contains_mkspecs TRUE) endif() # TODO: Handle macOS framework builds qt_internal_collect_direct_target_dependencies(${target} loose_target_requires) foreach(dep IN LISTS loose_target_requires) if(dep MATCHES "^Qt::") string(REGEX REPLACE "Qt" "${QT_CMAKE_EXPORT_NAMESPACE}" dep ${dep}) else() # TODO: Figure out a way to get non-Qt requirements PkgConfig files. continue() endif() if(NOT TARGET ${dep}) continue() endif() get_target_property(is_internal_module ${dep} _qt_is_internal_module) if(is_internal_module OR dep MATCHES ".*Platform.*Internal") continue() endif() get_target_property(type ${dep} TYPE) if(type STREQUAL "INTERFACE_LIBRARY") if(dep MATCHES "(.*)Private") set(dep "${CMAKE_MATCH_1}") endif() get_target_property(type ${dep} TYPE) endif() string(REGEX REPLACE "::" "" req ${dep}) if(type STREQUAL "STATIC_LIBRARY") list(APPEND target_libs -l${req}) else() list(APPEND target_requires ${req}) endif() endforeach() string(APPEND link_options " $, >") qt_path_join(path_suffix "${INSTALL_LIBDIR}" pkgconfig) qt_path_join(build_dir "${QT_BUILD_DIR}" "${path_suffix}") qt_path_join(install_dir "${QT_INSTALL_DIR}" "${path_suffix}") set(step_prefix "preliminary_pc_for_${pkgconfig_file}") qt_path_join(template_pc "${QT_CMAKE_DIR}" PkgConfigLibrary.pc.in) qt_path_join(pc_step1_path "${build_dir}" ${step_prefix}_step1.pc) qt_path_join(pc_step2_path "${build_dir}" ${step_prefix}_$_step2.pc) configure_file("${template_pc}" "${pc_step1_path}" @ONLY) file(GENERATE OUTPUT "${pc_step2_path}" INPUT "${pc_step1_path}") if(QT_GENERATOR_IS_MULTI_CONFIG) set(configs ${CMAKE_CONFIGURATION_TYPES}) set(rels ${configs}) list(FILTER rels INCLUDE REGEX "(Release|RelWithDebInfo|MinSizeRel)") if(rels) list(GET rels 0 release) endif() else() set(configs ${CMAKE_BUILD_TYPE}) set(release ${configs}) endif() foreach(config ${configs}) if(config STREQUAL "Debug" AND CMAKE_DEBUG_POSTFIX) set(postfix ${CMAKE_DEBUG_POSTFIX}) elseif(NOT config STREQUAL release) string(TOLOWER "_${config}" postfix) else() set(postfix "") endif() set(extra_args "") if(NOT postfix STREQUAL "") list(APPEND extra_args "-DPOSTFIX=${postfix}") endif() qt_path_join(pc_step2_path "${build_dir}" ${step_prefix}_${config}_step2.pc) qt_path_join(final_pc_path "${build_dir}" ${pkgconfig_file}${postfix}.pc) add_custom_command( OUTPUT "${final_pc_path}" DEPENDS "${pc_step2_path}" "${QT_CMAKE_DIR}/QtFinishPkgConfigFile.cmake" COMMAND ${CMAKE_COMMAND} "-DIN_FILE=${pc_step2_path}" "-DOUT_FILE=${final_pc_path}" ${extra_args} -P "${QT_CMAKE_DIR}/QtFinishPkgConfigFile.cmake" VERBATIM COMMENT "Generating pc file for target ${target}" ) # This is inspired by https://gitlab.kitware.com/cmake/cmake/-/issues/20842 target_sources(${module} PRIVATE "${final_pc_path}") qt_install(FILES "${final_pc_path}" DESTINATION "${install_dir}") endforeach() endfunction()