From f02786f7eea8c88f7cd4761638ae53bcf13d94fe Mon Sep 17 00:00:00 2001 From: Martchus Date: Sun, 18 Sep 2016 18:32:00 +0200 Subject: [PATCH 22/33] Pull dependencies of static libraries in CMake modules When doing a static build of Qt, the dependencies of the Qt libraries and plugins itself must be specified when linking the final application. --- .../data/cmake/Qt5BasicConfig.cmake.in | 148 ++++++++++++++---- .../data/cmake/Qt5PluginTarget.cmake.in | 11 +- qmake/generators/makefile.cpp | 16 +- 3 files changed, 133 insertions(+), 42 deletions(-) diff --git a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in index 27f4c277d6..358945b758 100644 --- a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in +++ b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in @@ -49,35 +49,52 @@ but not all the files it references. endmacro() !!IF !equals(TEMPLATE, aux) -macro(_populate_$${CMAKE_MODULE_NAME}_target_properties Configuration LIB_LOCATION IMPLIB_LOCATION) - set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${Configuration}) +macro(_populate_$${CMAKE_MODULE_NAME}_target_properties TARGET_CONFIG LIB_LOCATION IMPLIB_LOCATION) + set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${TARGET_CONFIG}) !!IF isEmpty(CMAKE_DLL_DIR_IS_ABSOLUTE) set(imported_location \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_DLL_DIR}${LIB_LOCATION}\") !!ELSE set(imported_location \"$${CMAKE_DLL_DIR}${LIB_LOCATION}\") !!ENDIF + _qt5_$${CMAKE_MODULE_NAME}_check_file_exists(${imported_location}) + +!!IF !isEmpty(CMAKE_STATIC_TYPE) + if (_Qt5$${CMAKE_MODULE_NAME}_LIB_DEPENDENCIES) + set(_list_sep \";\") + endif() + set_target_properties(Qt5::$${CMAKE_MODULE_NAME} PROPERTIES + \"INTERFACE_LINK_LIBRARIES_${TARGET_CONFIG}\" \"${_Qt5$${CMAKE_MODULE_NAME}_LIB_DEPENDENCIES}${_list_sep}${_Qt5$${CMAKE_MODULE_NAME}_STATIC_${TARGET_CONFIG}_LIB_DEPENDENCIES}\" + \"IMPORTED_LOCATION_${TARGET_CONFIG}\" ${imported_location} +!!IF !isEmpty(CMAKE_LIB_SONAME) + \"IMPORTED_SONAME_${TARGET_CONFIG}\" \"$${CMAKE_LIB_SONAME}\" +!!ENDIF + # For backward compatibility with CMake < 2.8.12 + \"IMPORTED_LINK_INTERFACE_LIBRARIES_${TARGET_CONFIG}\" \"${_Qt5$${CMAKE_MODULE_NAME}_LIB_DEPENDENCIES}${_list_sep}${_Qt5$${CMAKE_MODULE_NAME}_STATIC_${TARGET_CONFIG}_LIB_DEPENDENCIES}\" + ) +!!ELSE set_target_properties(Qt5::$${CMAKE_MODULE_NAME} PROPERTIES - \"INTERFACE_LINK_LIBRARIES\" \"${_Qt5$${CMAKE_MODULE_NAME}_LIB_DEPENDENCIES}\" - \"IMPORTED_LOCATION_${Configuration}\" ${imported_location} + \"INTERFACE_LINK_LIBRARIES_${TARGET_CONFIG}\" \"${_Qt5$${CMAKE_MODULE_NAME}_LIB_DEPENDENCIES}\" + \"IMPORTED_LOCATION_${TARGET_CONFIG}\" ${imported_location} !!IF !isEmpty(CMAKE_LIB_SONAME) - \"IMPORTED_SONAME_${Configuration}\" \"$${CMAKE_LIB_SONAME}\" + \"IMPORTED_SONAME_${TARGET_CONFIG}\" \"$${CMAKE_LIB_SONAME}\" !!ENDIF # For backward compatibility with CMake < 2.8.12 - \"IMPORTED_LINK_INTERFACE_LIBRARIES_${Configuration}\" \"${_Qt5$${CMAKE_MODULE_NAME}_LIB_DEPENDENCIES}\" + \"IMPORTED_LINK_INTERFACE_LIBRARIES_${TARGET_CONFIG}\" \"${_Qt5$${CMAKE_MODULE_NAME}_LIB_DEPENDENCIES}\" ) +!!ENDIF !!IF !isEmpty(CMAKE_WINDOWS_BUILD) !!IF isEmpty(CMAKE_LIB_DIR_IS_ABSOLUTE) set(imported_implib \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_LIB_DIR}${IMPLIB_LOCATION}\") !!ELSE - set(imported_implib \"IMPORTED_IMPLIB_${Configuration}\" \"$${CMAKE_LIB_DIR}${IMPLIB_LOCATION}\") + set(imported_implib \"IMPORTED_IMPLIB_${TARGET_CONFIG}\" \"$${CMAKE_LIB_DIR}${IMPLIB_LOCATION}\") !!ENDIF _qt5_$${CMAKE_MODULE_NAME}_check_file_exists(${imported_implib}) if(NOT \"${IMPLIB_LOCATION}\" STREQUAL \"\") set_target_properties(Qt5::$${CMAKE_MODULE_NAME} PROPERTIES - \"IMPORTED_IMPLIB_${Configuration}\" ${imported_implib} + \"IMPORTED_IMPLIB_${TARGET_CONFIG}\" ${imported_implib} ) endif() !!ENDIF @@ -217,13 +234,47 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME}) !!IF !isEmpty(CMAKE_STATIC_TYPE) add_library(Qt5::$${CMAKE_MODULE_NAME} STATIC IMPORTED) set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} PROPERTY IMPORTED_LINK_INTERFACE_LANGUAGES "CXX") + macro(_process_prl_file PRL_FILE_LOCATION CONFIGURATION) + if (EXISTS \"${PRL_FILE_LOCATION}\") + file(STRINGS \"${PRL_FILE_LOCATION}\" prl_strings REGEX \"QMAKE_PRL_LIBS_FOR_CMAKE\") + string(REGEX REPLACE \"QMAKE_PRL_LIBS_FOR_CMAKE *= *([^\\n]*)\" \"\\\\1\" static_depends ${prl_strings}) + string(REGEX REPLACE \"\\\\$\\\\$\\\\[QT_INSTALL_LIBS\\\\]\" \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/lib\" static_depends \"${static_depends}\") + string(REPLACE \"-framework;\" \"-framework \" static_depends \"${static_depends}\") + if (_Qt5$${CMAKE_MODULE_NAME}_STATIC_${CONFIGURATION}_LIB_DEPENDENCIES) + set(_list_sep \";\") + endif() + set(_Qt5$${CMAKE_MODULE_NAME}_STATIC_${CONFIGURATION}_LIB_DEPENDENCIES \"${_Qt5$${CMAKE_MODULE_NAME}_STATIC_${CONFIGURATION}_LIB_DEPENDENCIES}${_list_sep}${static_depends}\") + endif() + endmacro() + + macro(_populate_plugin_target_dependencies_from_prl_file PLUGIN_TARGET_NAME PRL_FILE_LOCATION CONFIGURATION LIB_DIRECTORY LIB_LOCATION) + file(STRINGS "${PRL_FILE_LOCATION}" prl_strings REGEX "QMAKE_PRL_LIBS_FOR_CMAKE") + string(REGEX REPLACE \"QMAKE_PRL_LIBS_FOR_CMAKE *= *([^\n]*)\" \"\\\\1\" static_depends ${prl_strings}) + string(REGEX REPLACE \"\\\\$\\\\$\\\\[QT_INSTALL_LIBS\\\\]\" \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/lib\" static_depends \"${static_depends}\") + set_property(TARGET ${PLUGIN_TARGET_NAME} PROPERTY + INTERFACE_LINK_LIBRARIES ${static_depends} + ) + endmacro() + +!!IF isEmpty(CMAKE_LIB_DIR_IS_ABSOLUTE) + _process_prl_file(\"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_PRL_FILE_LOCATION_DEBUG}\" DEBUG) !!ELSE + _process_prl_file(\"$${CMAKE_LIB_DIR}$${CMAKE_PRL_FILE_LOCATION_DEBUG}\" DEBUG) +!!ENDIF +!!IF isEmpty(CMAKE_LIB_DIR_IS_ABSOLUTE) + _process_prl_file(\"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_PRL_FILE_LOCATION_RELEASE}\" RELEASE) +!!ELSE + _process_prl_file(\"$${CMAKE_LIB_DIR}$${CMAKE_PRL_FILE_LOCATION_RELEASE}\" RELEASE) +!!ENDIF + +!!ELSE // !isEmpty(CMAKE_STATIC_TYPE) !!IF equals(TEMPLATE, aux) add_library(Qt5::$${CMAKE_MODULE_NAME} INTERFACE IMPORTED) !!ELSE add_library(Qt5::$${CMAKE_MODULE_NAME} SHARED IMPORTED) !!ENDIF -!!ENDIF +!!ENDIF // !isEmpty(CMAKE_STATIC_TYPE) + !!IF !equals(TEMPLATE, aux) !!IF !isEmpty(CMAKE_BUILD_IS_FRAMEWORK) set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} PROPERTY FRAMEWORK 1) @@ -235,6 +286,56 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME}) set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} PROPERTY INTERFACE_COMPILE_DEFINITIONS $${MODULE_DEFINES}) + # Find plugin targets + file(GLOB pluginTargetsMaybe \"${CMAKE_CURRENT_LIST_DIR}/*Qt5$${CMAKE_MODULE_NAME}_*.cmake\") + unset(pluginTargets) + if(pluginTargetsMaybe) + foreach(pluginTarget ${pluginTargetsMaybe}) + file(STRINGS ${pluginTarget} matched REGEX Qt5$${CMAKE_MODULE_NAME}_PLUGINS) + if(matched) + list(APPEND pluginTargets ${pluginTarget}) + endif() + endforeach() + endif() + + macro(_populate_$${CMAKE_MODULE_NAME}_plugin_properties TARGET_NAME PLUGIN_TARGET_NAME PLUGIN_NAME CONFIG PLUGIN_LOCATION) + set_property(TARGET ${PLUGIN_TARGET_NAME} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${CONFIG}) + +!!IF isEmpty(CMAKE_PLUGIN_DIR_IS_ABSOLUTE) + set(imported_location \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_PLUGIN_DIR}${PLUGIN_LOCATION}\") +!!ELSE + set(imported_location \"$${CMAKE_PLUGIN_DIR}${PLUGIN_LOCATION}\") +!!ENDIF + _qt5_$${CMAKE_MODULE_NAME}_check_file_exists(${imported_location}) + set_target_properties(${PLUGIN_TARGET_NAME} PROPERTIES + \"IMPORTED_LOCATION_${CONFIG}\" ${imported_location} + ) +!!IF !isEmpty(CMAKE_STATIC_TYPE) + set_property(TARGET ${TARGET_NAME} APPEND PROPERTY STATIC_PLUGINS ${PLUGIN_NAME}) + get_filename_component(_PLUGIN_DIR ${PLUGIN_LOCATION} PATH) + get_filename_component(_PLUGIN_DIR_NAME ${_PLUGIN_DIR} NAME) + get_filename_component(_PLUGIN_NAME ${PLUGIN_LOCATION} NAME) + string(REGEX REPLACE \"^lib(.*)\\\\.a\" \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/lib/qt/plugins/${_PLUGIN_DIR_NAME}/\\\\1.static.prl\" PLUGIN_PRL_FILE_LOCATION ${_PLUGIN_NAME}) + if(NOT EXISTS ${PLUGIN_PRL_FILE_LOCATION}) + string(REGEX REPLACE \"^lib(.*)\\\\.a\" \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/lib/qt/plugins/${_PLUGIN_DIR_NAME}/\\\\1.prl\" PLUGIN_PRL_FILE_LOCATION ${_PLUGIN_NAME}) + endif() + if(NOT EXISTS ${PLUGIN_PRL_FILE_LOCATION}) + string(REGEX REPLACE \"^lib(.*)\\\\.a\" \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/lib/qt/plugins/${_PLUGIN_DIR_NAME}/lib\\\\1.prl\" PLUGIN_PRL_FILE_LOCATION ${_PLUGIN_NAME}) + endif() + if(NOT EXISTS ${PLUGIN_PRL_FILE_LOCATION}) + message(FATAL_ERROR "The prl file containing dependencies of static plugin ${PLUGIN_TARGET_NAME} of ${TARGET_NAME} could not be found.") + endif() + _populate_plugin_target_dependencies_from_prl_file(${PLUGIN_TARGET_NAME} ${PLUGIN_PRL_FILE_LOCATION} ${CONFIG} \"lib/qt/plugins\" ${PLUGIN_LOCATION}) +!!ENDIF + + endmacro() + + if(pluginTargets) + foreach(pluginTarget ${pluginTargets}) + include(${pluginTarget}) + endforeach() + endif() + set(_Qt5$${CMAKE_MODULE_NAME}_PRIVATE_DIRS_EXIST TRUE) foreach (_Qt5$${CMAKE_MODULE_NAME}_PRIVATE_DIR ${Qt5$${CMAKE_MODULE_NAME}_OWN_PRIVATE_INCLUDE_DIRS}) if (NOT EXISTS ${_Qt5$${CMAKE_MODULE_NAME}_PRIVATE_DIR}) @@ -325,9 +426,11 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME}) !!ELSE \"$${CMAKE_IMPLIB_FILE_LOCATION_RELEASE}\" ) !!ENDIF - _populate_$${CMAKE_MODULE_NAME}_target_properties(RELEASE \"$${CMAKE_LIB_FILE_LOCATION_RELEASE}\" \"$${CMAKE_IMPLIB_FILE_LOCATION_RELEASE}\" ) -!!ENDIF // CMAKE_STATIC_WINDOWS_BUILD + _populate_$${CMAKE_MODULE_NAME}_target_properties(Qt5::$${CMAKE_MODULE_NAME} RELEASE \"$${CMAKE_LIB_FILE_LOCATION_RELEASE}\" \"$${CMAKE_IMPLIB_FILE_LOCATION_RELEASE}\" ) endif() +!!ENDIF // CMAKE_STATIC_TYPE + + !!ENDIF // CMAKE_RELEASE_TYPE !!ENDIF // CMAKE_FIND_OTHER_LIBRARY_BUILD @@ -338,29 +441,6 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME}) ) !!ENDIF // TEMPLATE != aux - file(GLOB pluginTargets \"${CMAKE_CURRENT_LIST_DIR}/Qt5$${CMAKE_MODULE_NAME}_*Plugin.cmake\") - - macro(_populate_$${CMAKE_MODULE_NAME}_plugin_properties Plugin Configuration PLUGIN_LOCATION) - set_property(TARGET Qt5::${Plugin} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${Configuration}) - -!!IF isEmpty(CMAKE_PLUGIN_DIR_IS_ABSOLUTE) - set(imported_location \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_PLUGIN_DIR}${PLUGIN_LOCATION}\") -!!ELSE - set(imported_location \"$${CMAKE_PLUGIN_DIR}${PLUGIN_LOCATION}\") -!!ENDIF - _qt5_$${CMAKE_MODULE_NAME}_check_file_exists(${imported_location}) - set_target_properties(Qt5::${Plugin} PROPERTIES - \"IMPORTED_LOCATION_${Configuration}\" ${imported_location} - ) - endmacro() - - if (pluginTargets) - foreach(pluginTarget ${pluginTargets}) - include(${pluginTarget}) - endforeach() - endif() - - !!IF !isEmpty(CMAKE_MODULE_EXTRAS) include(\"${CMAKE_CURRENT_LIST_DIR}/Qt5$${CMAKE_MODULE_NAME}ConfigExtras.cmake\") !!ENDIF diff --git a/mkspecs/features/data/cmake/Qt5PluginTarget.cmake.in b/mkspecs/features/data/cmake/Qt5PluginTarget.cmake.in index 5baf0fdb10..ec5f3cc437 100644 --- a/mkspecs/features/data/cmake/Qt5PluginTarget.cmake.in +++ b/mkspecs/features/data/cmake/Qt5PluginTarget.cmake.in @@ -1,11 +1,14 @@ - -add_library(Qt5::$$CMAKE_PLUGIN_NAME MODULE IMPORTED) +# Some Qt modules also load plugin target in extra config, so check whether the target already exists +if(NOT TARGET Qt5::$$CMAKE_PLUGIN_NAME) + add_library(Qt5::$$CMAKE_PLUGIN_NAME MODULE IMPORTED) !!IF !isEmpty(CMAKE_RELEASE_TYPE) -_populate_$${CMAKE_MODULE_NAME}_plugin_properties($$CMAKE_PLUGIN_NAME RELEASE \"$${CMAKE_PLUGIN_LOCATION_RELEASE}\") + _populate_$${CMAKE_MODULE_NAME}_plugin_properties(Qt5::$$CMAKE_MODULE_NAME Qt5::$$CMAKE_PLUGIN_NAME $$CMAKE_PLUGIN_NAME RELEASE \"$${CMAKE_PLUGIN_LOCATION_RELEASE}\") !!ENDIF !!IF !isEmpty(CMAKE_DEBUG_TYPE) -_populate_$${CMAKE_MODULE_NAME}_plugin_properties($$CMAKE_PLUGIN_NAME DEBUG \"$${CMAKE_PLUGIN_LOCATION_DEBUG}\") + _populate_$${CMAKE_MODULE_NAME}_plugin_properties(Qt5::$$CMAKE_MODULE_NAME Qt5::$$CMAKE_PLUGIN_NAME $$CMAKE_PLUGIN_NAME DEBUG \"$${CMAKE_PLUGIN_LOCATION_DEBUG}\") !!ENDIF list(APPEND Qt5$${CMAKE_MODULE_NAME}_PLUGINS Qt5::$$CMAKE_PLUGIN_NAME) + +endif() diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index dd86df8b91..fc7a0927a9 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -994,10 +994,18 @@ MakefileGenerator::writePrlFile(QTextStream &t) libs << "QMAKE_LIBS"; //obvious one if(project->isActiveConfig("staticlib")) libs << "QMAKE_LIBS_PRIVATE"; - t << "QMAKE_PRL_LIBS ="; - for (ProStringList::Iterator it = libs.begin(); it != libs.end(); ++it) - t << qv(project->values((*it).toKey())); - t << endl; + QStringList libNames; + QStringList libNamesCMake; + for (const auto &lib : libs) { + for (const auto &libName : project->values(lib.toKey())) { + libNames << QMakeEvaluator::quoteValue(libName); + QString libNameCMake(libName.toQString()); + libNameCMake.replace(QChar('\\'), QLatin1String("\\\\")); + libNamesCMake << libNameCMake; + } + } + t << "QMAKE_PRL_LIBS = " << libNames.join(QChar(' ')) << endl; + t << "QMAKE_PRL_LIBS_FOR_CMAKE = " << libNamesCMake.join(QChar(';')) << endl; } } -- 2.19.0