diff options
author | Alexandru Croitor <alexandru.croitor@qt.io> | 2020-10-28 18:05:24 +0100 |
---|---|---|
committer | Alexandru Croitor <alexandru.croitor@qt.io> | 2020-10-29 12:11:53 +0100 |
commit | bae96f1792da1fe0f3ca4b738096c0c1a27eb862 (patch) | |
tree | 16c849a77372948f16897ed94ac3782dc60731b4 /cmake | |
parent | 3a1bc4bad5757d72e5af8b4abe236e3cfac9621d (diff) |
CMake: Fix generation of prl files for non-qtbase modules
Previously we determined if a library represented by an absolute path
is a Qt module by checking if it's located in the build dir of the
current repo.
That is not sufficient for non-qtbase prefix builds, where
a Qt module might link against both a module in the current
build dir and in the prefix dir.
Detect such cases, and rewrite the absolute paths to relocatable paths
(either framework flags or paths starting with $$[QT_INSTALL_LIBS].
This should fix building examples with qmake that use QtQuick.
Fixes: QTBUG-87840
Change-Id: Icaf8f1a7c66292c80662fd0d5771a5a1628a9899
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Diffstat (limited to 'cmake')
-rw-r--r-- | cmake/QtFinishPrlFile.cmake | 22 | ||||
-rw-r--r-- | cmake/QtGenerateLibHelpers.cmake | 23 | ||||
-rw-r--r-- | cmake/QtPrlHelpers.cmake | 8 |
3 files changed, 47 insertions, 6 deletions
diff --git a/cmake/QtFinishPrlFile.cmake b/cmake/QtFinishPrlFile.cmake index 93fd558bab..7de3bd48f3 100644 --- a/cmake/QtFinishPrlFile.cmake +++ b/cmake/QtFinishPrlFile.cmake @@ -7,13 +7,15 @@ # 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'. +# - Prepends '-l' to values that are not absolute paths, and don't start with a dash +# aka, '-lfoo', '-framework', '-pthread'. # # 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) +# QT_LIB_DIRS: list of paths where Qt libraries are located. +# This includes the install prefix and the current repo build dir. +# These paths get replaced with relocatable paths or linker / framework flags. # 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 @@ -32,12 +34,19 @@ foreach(line ${lines}) if("${lib}" STREQUAL "") continue() endif() + + # Check if the absolute path represents a Qt module located either in Qt's + # $prefix/lib dir, or in the build dir of the repo. if(IS_ABSOLUTE "${lib}") - file(RELATIVE_PATH relative_lib "${QT_BUILD_LIBDIR}" "${lib}") - if(IS_ABSOLUTE "${relative_lib}" OR (relative_lib MATCHES "^\\.\\.")) + qt_internal_path_is_relative_to_qt_lib_path( + "${lib}" "${QT_LIB_DIRS}" lib_is_a_qt_module relative_lib) + if(NOT lib_is_a_qt_module) + # It's not a Qt module, extract the library name and prepend an -l to make + # it relocatable. qt_transform_absolute_library_paths_to_link_flags(lib_with_link_flag "${lib}") list(APPEND adjusted_libs "${lib_with_link_flag}") else() + # Is a Qt module. # Transform Qt framework paths into -framework flags. if(relative_lib MATCHES "^(Qt(.+))\\.framework/") if(NOT qt_framework_search_path_inserted) @@ -46,11 +55,14 @@ foreach(line ${lines}) endif() list(APPEND adjusted_libs "-framework" "${CMAKE_MATCH_1}") else() + # Not a framework, transform the Qt module into relocatable relative path. qt_strip_library_version_suffix(relative_lib "${relative_lib}") list(APPEND adjusted_libs "$$[QT_INSTALL_LIBS]/${relative_lib}") endif() endif() else() + # Not absolute path, most likely a library name or a linker flag. + # If linker flag (like -framework, -lfoo, -pthread, keep it as-is). if(NOT lib MATCHES "^-") string(PREPEND lib "-l") endif() diff --git a/cmake/QtGenerateLibHelpers.cmake b/cmake/QtGenerateLibHelpers.cmake index 06de484ac4..dedcdc7950 100644 --- a/cmake/QtGenerateLibHelpers.cmake +++ b/cmake/QtGenerateLibHelpers.cmake @@ -88,3 +88,26 @@ function(qt_strip_library_version_suffix out_var file_path) endif() set(${out_var} "${final_value}" PARENT_SCOPE) endfunction() + +# Checks if `input_path` is relative to at least one path given in the list of `qt_lib_paths`. +# Sets TRUE or FALSE in `out_var_is_relative`. +# Assigns the relative path to `out_var_relative_path` if the path is relative, otherwise assigns +# the original path. +function(qt_internal_path_is_relative_to_qt_lib_path + input_path qt_lib_paths out_var_is_relative out_var_relative_path) + set(is_relative "FALSE") + set(relative_path_value "${input_path}") + + foreach(qt_lib_path ${qt_lib_paths}) + file(RELATIVE_PATH relative_path "${qt_lib_path}" "${input_path}") + if(IS_ABSOLUTE "${relative_path}" OR (relative_path MATCHES "^\\.\\.")) + set(is_relative "FALSE") + else() + set(is_relative "TRUE") + set(relative_path_value "${relative_path}") + break() + endif() + endforeach() + set(${out_var_is_relative} "${is_relative}" PARENT_SCOPE) + set(${out_var_relative_path} "${relative_path_value}" PARENT_SCOPE) +endfunction() diff --git a/cmake/QtPrlHelpers.cmake b/cmake/QtPrlHelpers.cmake index 932565f318..35d321420c 100644 --- a/cmake/QtPrlHelpers.cmake +++ b/cmake/QtPrlHelpers.cmake @@ -270,6 +270,12 @@ QMAKE_PRL_VERSION = ${PROJECT_VERSION} set(configs ${CMAKE_BUILD_TYPE}) endif() + set(qt_lib_dirs "${QT_BUILD_DIR}/${INSTALL_LIBDIR}") + if(QT_WILL_INSTALL) + list(APPEND qt_lib_dirs + "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_LIBDIR}") + endif() + foreach(config ${configs}) # Output file for dependency tracking, and which will contain the final content. qt_path_join(prl_step2_path @@ -296,7 +302,7 @@ QMAKE_PRL_VERSION = ${PROJECT_VERSION} "-DLIBRARY_PREFIXES=${library_prefixes}" "-DLIBRARY_SUFFIXES=${library_suffixes}" "-DLINK_LIBRARY_FLAG=${CMAKE_LINK_LIBRARY_FLAG}" - "-DQT_BUILD_LIBDIR=${QT_BUILD_DIR}/${INSTALL_LIBDIR}" + "-DQT_LIB_DIRS=${qt_lib_dirs}" -P "${QT_CMAKE_DIR}/QtFinishPrlFile.cmake" VERBATIM COMMENT "Generating prl file for target ${target}" |