diff options
author | Alexandru Croitor <alexandru.croitor@qt.io> | 2020-07-30 19:17:09 +0200 |
---|---|---|
committer | Alexandru Croitor <alexandru.croitor@qt.io> | 2020-07-31 14:29:45 +0200 |
commit | 9c0f448f5a4e2e96e9b801c751c0a145c0eb6dad (patch) | |
tree | 504356a5fa4c369cdcb1c862518e99911f301d7c /cmake | |
parent | 26c742c1e1c96740646bb1896df52bad2fbe105d (diff) |
CMake: Fix generated content of prl files (again)
Apply the same kind of transformations to the contents of the prl
files as we do for pri files. Mainly, transform system library paths
that are absolute, into link flags to make them relocatable across
systems.
Also change the Qt frameworks to be linked via the -framework flags
instead of via absolute paths.
Implementation notes
Move the common required functions for both QtFinishPrlFile and
QtGenerateLibPri into a common QtGenerateLibHelpers.cmake file.
Make sure it's listed as a dependency for the custom commands.
Also make sure to pass the necessary input values like possible
library prefixes and suffixes, as well as the link flag.
Task-number: QTBUG-85240
Task-number: QTBUG-85801
Change-Id: I36f24207f92a1d2ed3ed2d81bb96e4e62d927b6e
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
Diffstat (limited to 'cmake')
-rw-r--r-- | cmake/QtBaseGlobalTargets.cmake | 1 | ||||
-rw-r--r-- | cmake/QtBuild.cmake | 20 | ||||
-rw-r--r-- | cmake/QtFinishPrlFile.cmake | 38 | ||||
-rw-r--r-- | cmake/QtGenerateLibHelpers.cmake | 90 | ||||
-rw-r--r-- | cmake/QtGenerateLibPri.cmake | 74 |
5 files changed, 131 insertions, 92 deletions
diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake index fd3a1ea3bb..1e5de239d6 100644 --- a/cmake/QtBaseGlobalTargets.cmake +++ b/cmake/QtBaseGlobalTargets.cmake @@ -360,6 +360,7 @@ qt_copy_or_install(FILES cmake/QtFileConfigure.txt.in cmake/QtGenerateExtPri.cmake cmake/QtGenerateLibPri.cmake + cmake/QtGenerateLibHelpers.cmake cmake/QtPlatformSupport.cmake cmake/QtPlatformAndroid.cmake cmake/QtPostProcess.cmake diff --git a/cmake/QtBuild.cmake b/cmake/QtBuild.cmake index 9fd5b3c244..e20985c2a3 100644 --- a/cmake/QtBuild.cmake +++ b/cmake/QtBuild.cmake @@ -949,7 +949,9 @@ QT.${config_module_name}_private.disabled_features = ${disabled_private_features ${CMAKE_STATIC_LIBRARY_SUFFIX}) add_custom_command( OUTPUT "${private_pri_file_path}" - DEPENDS ${inputs} "${QT_CMAKE_DIR}/QtGenerateLibPri.cmake" + DEPENDS ${inputs} + "${QT_CMAKE_DIR}/QtGenerateLibPri.cmake" + "${QT_CMAKE_DIR}/QtGenerateLibHelpers.cmake" COMMAND ${CMAKE_COMMAND} "-DIN_FILES=${inputs}" "-DOUT_FILE=${private_pri_file_path}" "-DLIBRARY_PREFIXES=${library_prefixes}" "-DLIBRARY_SUFFIXES=${library_suffixes}" @@ -1393,7 +1395,9 @@ CONFIG += ${private_config_joined} ${CMAKE_STATIC_LIBRARY_SUFFIX}) add_custom_command( OUTPUT "${qmodule_pri_target_path}" - DEPENDS ${inputs} "${QT_CMAKE_DIR}/QtGenerateLibPri.cmake" + DEPENDS ${inputs} + "${QT_CMAKE_DIR}/QtGenerateLibPri.cmake" + "${QT_CMAKE_DIR}/QtGenerateLibHelpers.cmake" COMMAND ${CMAKE_COMMAND} "-DIN_FILES=${inputs}" "-DOUT_FILE=${qmodule_pri_target_path}" "-DLIBRARY_PREFIXES=${library_prefixes}" "-DLIBRARY_SUFFIXES=${library_suffixes}" @@ -3398,7 +3402,11 @@ QMAKE_PRL_LIBS_FOR_CMAKE = ${prl_libs} CONTENT "FINAL_PRL_FILE_PATH = ${final_prl_file_path}") - set(library_suffixes ${CMAKE_SHARED_LIBRARY_SUFFIX} ${CMAKE_STATIC_LIBRARY_SUFFIX}) + set(library_prefixes ${CMAKE_SHARED_LIBRARY_PREFIX} ${CMAKE_STATIC_LIBRARY_PREFIX}) + set(library_suffixes + ${CMAKE_SHARED_LIBRARY_SUFFIX} + ${CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES} + ${CMAKE_STATIC_LIBRARY_SUFFIX}) if(QT_GENERATOR_IS_MULTI_CONFIG) set(configs ${CMAKE_CONFIGURATION_TYPES}) @@ -3421,13 +3429,17 @@ QMAKE_PRL_LIBS_FOR_CMAKE = ${prl_libs} "${prl_meta_info_name_prefix}${config}${prl_meta_info_name_suffix}") add_custom_command( OUTPUT "${prl_step2_path}" - DEPENDS "${prl_step1_path}" "${prl_meta_info_path}" + DEPENDS "${prl_step1_path}" + "${prl_meta_info_path}" "${QT_CMAKE_DIR}/QtFinishPrlFile.cmake" + "${QT_CMAKE_DIR}/QtGenerateLibHelpers.cmake" COMMAND ${CMAKE_COMMAND} "-DIN_FILE=${prl_step1_path}" "-DIN_META_FILE=${prl_meta_info_path}" "-DOUT_FILE=${prl_step2_path}" + "-DLIBRARY_PREFIXES=${library_prefixes}" "-DLIBRARY_SUFFIXES=${library_suffixes}" + "-DLINK_LIBRARY_FLAG=${CMAKE_LINK_LIBRARY_FLAG}" "-DQT_BUILD_LIBDIR=${QT_BUILD_DIR}/${INSTALL_LIBDIR}" -P "${QT_CMAKE_DIR}/QtFinishPrlFile.cmake" VERBATIM diff --git a/cmake/QtFinishPrlFile.cmake b/cmake/QtFinishPrlFile.cmake index d6901e168f..4b350b9339 100644 --- a/cmake/QtFinishPrlFile.cmake +++ b/cmake/QtFinishPrlFile.cmake @@ -3,28 +3,26 @@ # - Replaces occurrences of the build libdir with $$[QT_INSTALL_LIBDIR]. # - Strips version number suffixes from absolute paths, because qmake's lflag # merging does not handle them correctly. +# - Transforms absolute library paths into link flags +# aka from "/usr/lib/x86_64-linux-gnu/libcups.so" to "-lcups" +# - Replaces Qt absolute framework paths into a combination of -F$$[QT_INSTALL_LIBS] and +# -framework QtFoo +# - Prepends '-l' to values that are not absolute paths, and don't start with either '-l' or +# '-framework'. # # This file is to be used in CMake script mode with the following variables set: # IN_FILE: path to the preliminary .prl file # OUT_FILE: path to the final .prl file that's going to be installed # QT_BUILD_LIBDIR: path to Qt's libdir when building (those paths get replaced) # LIBRARY_SUFFIXES: list of known library extensions, e.g. .so;.a on Linux +# LIBRARY_PREFIXES: list of known library prefies, e.g. the "lib" in "libz" on on Linux +# LINK_LIBRARY_FLAG: flag used to link a shared library to an executable, e.g. -l on UNIX -function(strip_library_version_suffix out_var file_path) - get_filename_component(dir "${file_path}" DIRECTORY) - get_filename_component(basename "${file_path}" NAME_WE) - get_filename_component(ext "${file_path}" EXT) - foreach(libsuffix ${LIBRARY_SUFFIXES}) - if(ext MATCHES "^${libsuffix}(\\.[0-9]+)+") - set(ext ${libsuffix}) - break() - endif() - endforeach() - set(${out_var} "${dir}/${basename}${ext}" PARENT_SCOPE) -endfunction() +include("${CMAKE_CURRENT_LIST_DIR}/QtGenerateLibHelpers.cmake") file(STRINGS "${IN_FILE}" lines) set(content "") +set(qt_framework_search_path_inserted FALSE) foreach(line ${lines}) if(line MATCHES "^RCC_OBJECTS = (.*)") set(rcc_objects ${CMAKE_MATCH_1}) @@ -35,12 +33,22 @@ foreach(line ${lines}) continue() endif() if(IS_ABSOLUTE "${lib}") - strip_library_version_suffix(lib "${lib}") file(RELATIVE_PATH relative_lib "${QT_BUILD_LIBDIR}" "${lib}") if(IS_ABSOLUTE "${relative_lib}" OR (relative_lib MATCHES "^\\.\\.")) - list(APPEND adjusted_libs "${lib}") + qt_transform_absolute_library_paths_to_link_flags(lib_with_link_flag "${lib}") + list(APPEND adjusted_libs "${lib_with_link_flag}") else() - list(APPEND adjusted_libs "$$[QT_INSTALL_LIBS]/${relative_lib}") + # Transform Qt framework paths into -framework flags. + if(relative_lib MATCHES "^(Qt(.+))\\.framework/") + if(NOT qt_framework_search_path_inserted) + set(qt_framework_search_path_inserted TRUE) + list(APPEND adjusted_libs "-F$$[QT_INSTALL_LIBS]") + endif() + list(APPEND adjusted_libs "-framework" "${CMAKE_MATCH_1}") + else() + qt_strip_library_version_suffix(relative_lib "${relative_lib}") + list(APPEND adjusted_libs "$$[QT_INSTALL_LIBS]/${relative_lib}") + endif() endif() else() if(NOT lib MATCHES "^-l" AND NOT lib MATCHES "^-framework") diff --git a/cmake/QtGenerateLibHelpers.cmake b/cmake/QtGenerateLibHelpers.cmake new file mode 100644 index 0000000000..06de484ac4 --- /dev/null +++ b/cmake/QtGenerateLibHelpers.cmake @@ -0,0 +1,90 @@ +# Given "/usr/lib/x86_64-linux-gnu/libcups.so" +# Returns "cups" or an empty string if the file is not an absolute library path. +# Aka it strips the "lib" prefix, the .so extension and the base path. +function(qt_get_library_name_without_prefix_and_suffix out_var file_path) + set(out_value "") + if(IS_ABSOLUTE "${file_path}") + get_filename_component(basename "${file_path}" NAME_WE) + get_filename_component(ext "${file_path}" EXT) + foreach(libsuffix ${LIBRARY_SUFFIXES}) + # Handle weird prefix extensions like in the case of + # "/usr/lib/x86_64-linux-gnu/libglib-2.0.so" + # it's ".0.so". + if(ext MATCHES "^(\\.[0-9]+)*${libsuffix}(\\.[0-9]+)*") + set(is_linkable_library TRUE) + set(weird_numbered_extension "${CMAKE_MATCH_1}") + break() + endif() + endforeach() + if(is_linkable_library) + set(out_value "${basename}") + if(LIBRARY_PREFIXES) + foreach(libprefix ${LIBRARY_PREFIXES}) + # Strip any library prefix like "lib" for a library that we will use with a link + # flag. + if(libprefix AND out_value MATCHES "^${libprefix}(.+)") + set(out_value "${CMAKE_MATCH_1}") + break() + endif() + endforeach() + endif() + if(weird_numbered_extension) + set(out_value "${out_value}${weird_numbered_extension}") + endif() + endif() + endif() + + # Reverse the dependency order to be in sync with what qmake generated .pri files + # have. + list(REVERSE out_list) + + set(${out_var} "${out_value}" PARENT_SCOPE) +endfunction() + +# Given "/usr/lib/x86_64-linux-gnu/libcups.so" +# Returns "-lcups" or an empty string if the file is not an absolute library path. +function(qt_get_library_with_link_flag out_var file_path) + qt_get_library_name_without_prefix_and_suffix(lib_name "${file_path}") + + set(out_value "") + if(lib_name) + set(out_value "${lib_name}") + if(LINK_LIBRARY_FLAG) + string(PREPEND out_value "${LINK_LIBRARY_FLAG}") + endif() + endif() + + set(${out_var} "${out_value}" PARENT_SCOPE) +endfunction() + +# Given a list of potential library paths, returns a transformed list where absolute library paths +# are replaced with library link flags. +function(qt_transform_absolute_library_paths_to_link_flags out_var library_path_list) + set(out_list "") + foreach(library_path ${library_path_list}) + qt_get_library_with_link_flag(lib_name_with_link_flag "${library_path}") + if(lib_name_with_link_flag) + list(APPEND out_list "${lib_name_with_link_flag}") + else() + list(APPEND out_list "${library_path}") + endif() + endforeach() + set(${out_var} "${out_list}" PARENT_SCOPE) +endfunction() + +function(qt_strip_library_version_suffix out_var file_path) + get_filename_component(dir "${file_path}" DIRECTORY) + get_filename_component(basename "${file_path}" NAME_WE) + get_filename_component(ext "${file_path}" EXT) + foreach(libsuffix ${LIBRARY_SUFFIXES}) + if(ext MATCHES "^${libsuffix}(\\.[0-9]+)+") + set(ext ${libsuffix}) + break() + endif() + endforeach() + set(final_value "${basename}${ext}") + if(dir) + set(final_value "${dir}/${final_value}") + endif() + set(${out_var} "${final_value}" PARENT_SCOPE) +endfunction() diff --git a/cmake/QtGenerateLibPri.cmake b/cmake/QtGenerateLibPri.cmake index 0e62536a1a..d4e0d04682 100644 --- a/cmake/QtGenerateLibPri.cmake +++ b/cmake/QtGenerateLibPri.cmake @@ -33,79 +33,7 @@ function(qmake_list out_var) set(${out_var} ${result} PARENT_SCOPE) endfunction() -# Given "/usr/lib/x86_64-linux-gnu/libcups.so" -# Returns "cups" or an empty string if the file is not an absolute library path. -# Aka it strips the "lib" prefix, the .so extension and the base path. -function(qt_get_library_name_without_prefix_and_suffix out_var file_path) - set(out_value "") - if(IS_ABSOLUTE "${file_path}") - get_filename_component(basename "${file_path}" NAME_WE) - get_filename_component(ext "${file_path}" EXT) - foreach(libsuffix ${LIBRARY_SUFFIXES}) - # Handle weird prefix extensions like in the case of - # "/usr/lib/x86_64-linux-gnu/libglib-2.0.so" - # it's ".0.so". - if(ext MATCHES "^(\\.[0-9]+)*${libsuffix}(\\.[0-9]+)*") - set(is_linkable_library TRUE) - set(weird_numbered_extension "${CMAKE_MATCH_1}") - break() - endif() - endforeach() - if(is_linkable_library) - set(out_value "${basename}") - if(LIBRARY_PREFIXES) - foreach(libprefix ${LIBRARY_PREFIXES}) - # Strip any library prefix like "lib" for a library that we will use with a link - # flag. - if(libprefix AND out_value MATCHES "^${libprefix}(.+)") - set(out_value "${CMAKE_MATCH_1}") - break() - endif() - endforeach() - endif() - if(weird_numbered_extension) - set(out_value "${out_value}${weird_numbered_extension}") - endif() - endif() - endif() - - # Reverse the dependency order to be in sync with what qmake generated .pri files - # have. - list(REVERSE out_list) - - set(${out_var} "${out_value}" PARENT_SCOPE) -endfunction() - -# Given "/usr/lib/x86_64-linux-gnu/libcups.so" -# Returns "-lcups" or an empty string if the file is not an absolute library path. -function(qt_get_library_with_link_flag out_var file_path) - qt_get_library_name_without_prefix_and_suffix(lib_name "${file_path}") - - set(out_value "") - if(lib_name) - set(out_value "${lib_name}") - if(LINK_LIBRARY_FLAG) - string(PREPEND out_value "${LINK_LIBRARY_FLAG}") - endif() - endif() - - set(${out_var} "${out_value}" PARENT_SCOPE) -endfunction() - -# Given a list of potential library paths, returns a transformed list where absolute library paths -# are replaced with library link flags. -function(qt_transform_absolute_library_paths_to_link_flags out_var library_path_list) - set(out_list "") - foreach(library_path ${library_path_list}) - qt_get_library_with_link_flag(lib_name_with_link_flag "${library_path}") - if(lib_name_with_link_flag) - list(APPEND out_list "${lib_name_with_link_flag}") - else() - list(APPEND out_list "${library_path}") - endif() - endforeach() - set(${out_var} "${out_list}" PARENT_SCOPE) -endfunction() +include("${CMAKE_CURRENT_LIST_DIR}/QtGenerateLibHelpers.cmake") list(POP_FRONT IN_FILES in_pri_file) file(READ ${in_pri_file} content) |