summaryrefslogtreecommitdiffstats
path: root/cmake/QtBuildPathsHelpers.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake/QtBuildPathsHelpers.cmake')
-rw-r--r--cmake/QtBuildPathsHelpers.cmake247
1 files changed, 247 insertions, 0 deletions
diff --git a/cmake/QtBuildPathsHelpers.cmake b/cmake/QtBuildPathsHelpers.cmake
new file mode 100644
index 0000000000..6431fa1937
--- /dev/null
+++ b/cmake/QtBuildPathsHelpers.cmake
@@ -0,0 +1,247 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+macro(qt_internal_setup_default_install_prefix)
+ # Detect non-prefix builds: either when the qtbase install prefix is set to the binary dir
+ # or when a developer build is explicitly enabled and no install prefix (or staging prefix)
+ # is specified.
+ # This detection only happens when building qtbase, and later is propagated via the generated
+ # QtBuildInternalsExtra.cmake file.
+ if(PROJECT_NAME STREQUAL "QtBase" AND NOT QT_INTERNAL_BUILD_STANDALONE_PARTS)
+ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+ # Handle both FEATURE_ and QT_FEATURE_ cases when they are specified on the command line
+ # explicitly. It's possible for one to be set, but not the other, because
+ # qtbase/configure.cmake is not processed by this point.
+ if((FEATURE_developer_build
+ OR QT_FEATURE_developer_build
+ OR FEATURE_no_prefix
+ OR QT_FEATURE_no_prefix
+ )
+ AND NOT CMAKE_STAGING_PREFIX)
+ # Handle non-prefix builds by setting the CMake install prefix to point to qtbase's
+ # build dir. While building another repo (like qtsvg) the CMAKE_PREFIX_PATH should
+ # be set on the command line to point to the qtbase build dir.
+ set(__qt_default_prefix "${QtBase_BINARY_DIR}")
+ else()
+ if(CMAKE_HOST_WIN32)
+ set(__qt_default_prefix "C:/Qt/")
+ else()
+ set(__qt_default_prefix "/usr/local/")
+ endif()
+ string(APPEND __qt_default_prefix
+ "Qt-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
+ endif()
+ set(CMAKE_INSTALL_PREFIX ${__qt_default_prefix} CACHE PATH
+ "Install path prefix, prepended onto install directories." FORCE)
+ unset(__qt_default_prefix)
+ endif()
+ if(CMAKE_STAGING_PREFIX)
+ set(__qt_prefix "${CMAKE_STAGING_PREFIX}")
+ else()
+ set(__qt_prefix "${CMAKE_INSTALL_PREFIX}")
+ endif()
+ if(__qt_prefix STREQUAL QtBase_BINARY_DIR)
+ set(__qt_will_install_value OFF)
+ else()
+ set(__qt_will_install_value ON)
+ endif()
+ set(QT_WILL_INSTALL ${__qt_will_install_value} CACHE BOOL
+ "Boolean indicating if doing a Qt prefix build (vs non-prefix build)." FORCE)
+ unset(__qt_prefix)
+ unset(__qt_will_install_value)
+ endif()
+endmacro()
+
+function(qt_internal_setup_build_and_install_paths)
+ # Compute the values of QT_BUILD_DIR, QT_INSTALL_DIR, QT_CONFIG_BUILD_DIR, QT_CONFIG_INSTALL_DIR
+ # taking into account whether the current build is a prefix build or a non-prefix build,
+ # and whether it is a superbuild or non-superbuild.
+ # A third case is when another module or standalone tests/examples are built against a
+ # super-built Qt.
+ # The layout for the third case is the same as for non-superbuilds.
+ #
+ # These values should be prepended to file paths in commands or properties,
+ # in order to correctly place generated Config files, generated Targets files,
+ # executables / libraries, when copying / installing files, etc.
+ #
+ # The build dir variables will always be absolute paths.
+ # The QT_INSTALL_DIR variable will have a relative path in a prefix build,
+ # which means that it can be empty, so use qt_join_path to prevent accidental absolute paths.
+ if(QT_SUPERBUILD)
+ # In this case, we always copy all the build products in qtbase/{bin,lib,...}
+ if(QT_WILL_INSTALL)
+ set(QT_BUILD_DIR "${QtBase_BINARY_DIR}")
+ set(QT_INSTALL_DIR "")
+ else()
+ if("${CMAKE_STAGING_PREFIX}" STREQUAL "")
+ set(QT_BUILD_DIR "${QtBase_BINARY_DIR}")
+ set(QT_INSTALL_DIR "${QtBase_BINARY_DIR}")
+ else()
+ set(QT_BUILD_DIR "${CMAKE_STAGING_PREFIX}")
+ set(QT_INSTALL_DIR "${CMAKE_STAGING_PREFIX}")
+ endif()
+ endif()
+ else()
+ if(QT_WILL_INSTALL)
+ # In the usual prefix build case, the build dir is the current module build dir,
+ # and the install dir is the prefix, so we don't set it.
+ set(QT_BUILD_DIR "${CMAKE_BINARY_DIR}")
+ set(QT_INSTALL_DIR "")
+ else()
+ # When doing a non-prefix build, both the build dir and install dir are the same,
+ # pointing to the qtbase build dir.
+ set(QT_BUILD_DIR "${QT_STAGING_PREFIX}")
+ set(QT_INSTALL_DIR "${QT_BUILD_DIR}")
+ endif()
+ endif()
+
+ set(__config_path_part "${INSTALL_LIBDIR}/cmake")
+ set(QT_CONFIG_BUILD_DIR "${QT_BUILD_DIR}/${__config_path_part}")
+ set(QT_CONFIG_INSTALL_DIR "${QT_INSTALL_DIR}")
+ if(QT_CONFIG_INSTALL_DIR)
+ string(APPEND QT_CONFIG_INSTALL_DIR "/")
+ endif()
+ string(APPEND QT_CONFIG_INSTALL_DIR ${__config_path_part})
+
+ set(QT_BUILD_DIR "${QT_BUILD_DIR}" PARENT_SCOPE)
+ set(QT_INSTALL_DIR "${QT_INSTALL_DIR}" PARENT_SCOPE)
+ set(QT_CONFIG_BUILD_DIR "${QT_CONFIG_BUILD_DIR}" PARENT_SCOPE)
+ set(QT_CONFIG_INSTALL_DIR "${QT_CONFIG_INSTALL_DIR}" PARENT_SCOPE)
+endfunction()
+
+function(qt_configure_process_path name default docstring)
+ # Values are computed once for qtbase, and then exported and reused for other projects.
+ if(NOT PROJECT_NAME STREQUAL "QtBase")
+ return()
+ endif()
+
+ # No value provided, set the default.
+ if(NOT DEFINED "${name}")
+ set("${name}" "${default}" CACHE STRING "${docstring}")
+ else()
+ get_filename_component(given_path_as_abs "${${name}}" ABSOLUTE BASE_DIR
+ "${CMAKE_INSTALL_PREFIX}")
+ file(RELATIVE_PATH rel_path "${CMAKE_INSTALL_PREFIX}"
+ "${given_path_as_abs}")
+
+ # If absolute path given, check that it's inside the prefix (error out if not).
+ # TODO: Figure out if we need to support paths that are outside the prefix.
+ #
+ # If relative path given, it's relative to the install prefix (rather than the binary dir,
+ # which is what qmake does for some reason).
+ # In both cases, store the value as a relative path.
+ if("${rel_path}" STREQUAL "")
+ # file(RELATIVE_PATH) returns an empty string if the given absolute paths are equal
+ set(rel_path ".")
+ elseif(rel_path MATCHES "^\.\./")
+ # INSTALL_SYSCONFDIR is allowed to be outside the prefix.
+ if(NOT name STREQUAL "INSTALL_SYSCONFDIR")
+ message(FATAL_ERROR
+ "Path component '${name}' is outside computed install prefix: ${rel_path} ")
+ return()
+ endif()
+ set("${name}" "${${name}}" CACHE STRING "${docstring}" FORCE)
+ else()
+ set("${name}" "${rel_path}" CACHE STRING "${docstring}" FORCE)
+ endif()
+ endif()
+endfunction()
+
+macro(qt_internal_setup_configure_install_paths)
+ # Install locations:
+ qt_configure_process_path(INSTALL_BINDIR "bin" "Executables [PREFIX/bin]")
+ qt_configure_process_path(INSTALL_INCLUDEDIR "include" "Header files [PREFIX/include]")
+ qt_configure_process_path(INSTALL_LIBDIR "lib" "Libraries [PREFIX/lib]")
+ qt_configure_process_path(INSTALL_MKSPECSDIR "mkspecs" "Mkspecs files [PREFIX/mkspecs]")
+ qt_configure_process_path(INSTALL_ARCHDATADIR "." "Arch-dependent data [PREFIX]")
+ qt_configure_process_path(INSTALL_PLUGINSDIR
+ "${INSTALL_ARCHDATADIR}/plugins"
+ "Plugins [ARCHDATADIR/plugins]")
+
+ if(NOT INSTALL_MKSPECSDIR MATCHES "(^|/)mkspecs")
+ message(FATAL_ERROR "INSTALL_MKSPECSDIR must end with '/mkspecs'")
+ endif()
+
+ if (WIN32)
+ set(_default_libexec "${INSTALL_ARCHDATADIR}/bin")
+ else()
+ set(_default_libexec "${INSTALL_ARCHDATADIR}/libexec")
+ endif()
+
+ qt_configure_process_path(
+ INSTALL_LIBEXECDIR
+ "${_default_libexec}"
+ "Helper programs [ARCHDATADIR/bin on Windows, ARCHDATADIR/libexec otherwise]")
+ qt_configure_process_path(INSTALL_QMLDIR
+ "${INSTALL_ARCHDATADIR}/qml"
+ "QML imports [ARCHDATADIR/qml]")
+ qt_configure_process_path(INSTALL_DATADIR "." "Arch-independent data [PREFIX]")
+ qt_configure_process_path(INSTALL_DOCDIR "${INSTALL_DATADIR}/doc" "Documentation [DATADIR/doc]")
+ qt_configure_process_path(INSTALL_TRANSLATIONSDIR "${INSTALL_DATADIR}/translations"
+ "Translations [DATADIR/translations]")
+ if(APPLE)
+ set(QT_DEFAULT_SYS_CONF_DIR "/Library/Preferences/Qt")
+ else()
+ set(QT_DEFAULT_SYS_CONF_DIR "etc/xdg")
+ endif()
+ qt_configure_process_path(
+ INSTALL_SYSCONFDIR
+ "${QT_DEFAULT_SYS_CONF_DIR}"
+ "Settings used by Qt programs [PREFIX/etc/xdg]/[/Library/Preferences/Qt]")
+ qt_configure_process_path(INSTALL_EXAMPLESDIR "examples" "Examples [PREFIX/examples]")
+ qt_configure_process_path(INSTALL_TESTSDIR "tests" "Tests [PREFIX/tests]")
+ qt_configure_process_path(INSTALL_DESCRIPTIONSDIR
+ "${INSTALL_ARCHDATADIR}/modules"
+ "Module description files directory")
+endmacro()
+
+macro(qt_internal_set_cmake_install_libdir)
+ # Ensure that GNUInstallDirs's CMAKE_INSTALL_LIBDIR points to the same lib dir that Qt was
+ # configured with. Currently this is important for QML plugins, which embed an rpath based
+ # on that value.
+ set(CMAKE_INSTALL_LIBDIR "${INSTALL_LIBDIR}")
+endmacro()
+
+macro(qt_internal_set_qt_cmake_dir)
+ set(QT_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}")
+endmacro()
+
+macro(qt_internal_set_qt_apple_support_files_path)
+ # This is analogous to what we have in QtConfig.cmake.in. It's copied here so that iOS
+ # tests can be built in tree.
+ if(APPLE)
+ if(NOT CMAKE_SYSTEM_NAME OR CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+ set(__qt_internal_cmake_apple_support_files_path "${QT_CMAKE_DIR}/macos")
+ elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
+ set(__qt_internal_cmake_apple_support_files_path "${QT_CMAKE_DIR}/ios")
+ elseif(CMAKE_SYSTEM_NAME STREQUAL "visionOS")
+ set(__qt_internal_cmake_apple_support_files_path "${QT_CMAKE_DIR}/visionos")
+ endif()
+ endif()
+endmacro()
+
+macro(qt_internal_set_qt_staging_prefix)
+ if(NOT "${CMAKE_STAGING_PREFIX}" STREQUAL "")
+ set(QT_STAGING_PREFIX "${CMAKE_STAGING_PREFIX}")
+ else()
+ set(QT_STAGING_PREFIX "${CMAKE_INSTALL_PREFIX}")
+ endif()
+endmacro()
+
+macro(qt_internal_setup_paths_and_prefixes)
+ qt_internal_setup_configure_install_paths()
+
+ qt_internal_set_qt_staging_prefix()
+
+ # Depends on QT_STAGING_PREFIX being set.
+ qt_internal_setup_build_and_install_paths()
+
+ qt_get_relocatable_install_prefix(QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX)
+
+ # Depends on INSTALL_LIBDIR being set.
+ qt_internal_set_cmake_install_libdir()
+
+ qt_internal_set_qt_cmake_dir()
+
+ qt_internal_set_qt_apple_support_files_path()
+endmacro()