summaryrefslogtreecommitdiffstats
path: root/cmake/QtInstallHelpers.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake/QtInstallHelpers.cmake')
-rw-r--r--cmake/QtInstallHelpers.cmake176
1 files changed, 128 insertions, 48 deletions
diff --git a/cmake/QtInstallHelpers.cmake b/cmake/QtInstallHelpers.cmake
index 30962b84e2..deab48cda5 100644
--- a/cmake/QtInstallHelpers.cmake
+++ b/cmake/QtInstallHelpers.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
# Wraps install() command. In a prefix build, simply passes along arguments to install().
# In a non-prefix build, handles association of targets to export names, and also calls export().
function(qt_install)
@@ -18,14 +21,18 @@ function(qt_install)
install(${ARGV})
endif()
- # Exit early if this is a prefix build.
- if(QT_WILL_INSTALL)
- return()
- endif()
-
- # In a non-prefix build, when install(EXPORT) is called,
- # also call export(EXPORT) to generate build tree target files.
+ # When install(EXPORT) is called, also call export(EXPORT)
+ # to generate build tree target files.
if(NOT is_install_targets AND arg_EXPORT)
+ # For prefixed builds (both top-level and per-repo) export build tree CMake Targets files so
+ # they can be used in CMake ExternalProjects. One such case is examples built as
+ # ExternalProjects as part of the Qt build.
+ # In a top-level build the exported config files are placed under qtbase/lib/cmake.
+ # In a per-repo build, they will be placed in each repo's build dir/lib/cmake.
+ if(QT_WILL_INSTALL)
+ qt_path_join(arg_DESTINATION "${QT_BUILD_DIR}" "${arg_DESTINATION}")
+ endif()
+
set(namespace_option "")
if(arg_NAMESPACE)
set(namespace_option NAMESPACE ${arg_NAMESPACE})
@@ -88,61 +95,70 @@ function(qt_copy_or_install)
qt_non_prefix_copy(COPY ${argv_copy} ${copy_arguments})
endfunction()
-# Hacky way to remove the install target in non-prefix builds.
-# We need to associate targets with export names, and that is only possible to do with the
-# install(TARGETS) command. But in a non-prefix build, we don't want to install anything.
-# To make sure that developers don't accidentally run make install, replace the generated
-# cmake_install.cmake file with an empty file. To do this, always create a new temporary file
-# at CMake configuration step, and use it as an input to a custom command that replaces the
-# cmake_install.cmake file with an empty one. This means we will always replace the file on
-# every reconfiguration, but not when doing null builds.
-function(qt_remove_install_target)
- # On superbuilds we only do this for qtbase - it will correctly remove the
- # cmake_install.cmake at the root of the repository.
- if(QT_SUPERBUILD)
- if(NOT (PROJECT_NAME STREQUAL "QtBase"))
+# Create a versioned hard-link for the given target, or a program
+# E.g. "bin/qmake6" -> "bin/qmake".
+#
+# One-value Arguments:
+# WORKING_DIRECTORY
+# The directory where the original file is already placed.
+# SUFFIX
+# The program file extension, only used for PROGRAMS
+# Multi-value Arguments:
+# TARGETS
+# List of targets for which the versioned link will be created.
+# If targets are given, BASE_NAME and SUFFIX will be derived from it.
+# PROGRAMS
+# List of program file names for which the versioned link will be created.
+#
+#
+# NOTE: This assumes that TARGETS, or PROGRAMS are already installed in the
+# WORKING_DIRECTORY.
+#
+# In a multi-config build, create the link for the main config only.
+function(qt_internal_install_versioned_link)
+ if(NOT QT_WILL_INSTALL)
return()
- endif()
endif()
- set(file_in "${CMAKE_BINARY_DIR}/.remove_cmake_install_in.txt")
- set(file_generated "${CMAKE_BINARY_DIR}/.remove_cmake_install_generated.txt")
- set(cmake_install_file "${CMAKE_BINARY_DIR}/cmake_install.cmake")
- file(WRITE ${file_in} "")
+ if(NOT QT_CREATE_VERSIONED_HARD_LINK)
+ return()
+ endif()
- add_custom_command(OUTPUT ${file_generated}
- COMMAND ${CMAKE_COMMAND} -E copy ${file_in} ${file_generated}
- COMMAND ${CMAKE_COMMAND} -E remove ${cmake_install_file}
- COMMAND ${CMAKE_COMMAND} -E touch ${cmake_install_file}
- COMMENT "Removing cmake_install.cmake"
- MAIN_DEPENDENCY ${file_in})
+ set(options)
+ set(oneValueArgs "WORKING_DIRECTORY;SUFFIX")
+ set(multiValueArgs "TARGETS;PROGRAMS")
+ cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
- add_custom_target(remove_cmake_install ALL DEPENDS ${file_generated})
-endfunction()
+ if(arg_TARGETS)
+ foreach(target "${arg_TARGETS}")
+ _qt_internal_create_versioned_link_or_copy("${arg_WORKING_DIRECTORY}"
+ $<TARGET_FILE_BASE_NAME:${target}>
+ $<TARGET_FILE_SUFFIX:${target}>)
+ endforeach()
+ endif()
-function(qt_set_up_nonprefix_build)
- if(NOT QT_WILL_INSTALL)
- qt_remove_install_target()
+ if(arg_PROGRAMS)
+ foreach(program "${arg_PROGRAMS}")
+ _qt_internal_create_versioned_link_or_copy("${arg_WORKING_DIRECTORY}"
+ "${program}"
+ "${arg_SUFFIX}")
+ endforeach()
endif()
endfunction()
-# Create a versioned hard-link for the given target.
-# E.g. "bin/qmake6" -> "bin/qmake".
-# If no hard link can be created, make a copy instead.
+# Generate a script for creating a hard-link between the base_name, and
+# base_name${PROJECT_VERSION_MAJOR}.
#
-# In a multi-config build, create the link for the main config only.
-function(qt_internal_install_versioned_link install_dir target)
- if(NOT QT_WILL_INSTALL)
- return()
- endif()
-
+# If no hard link can be created, make a copy instead.
+function(_qt_internal_create_versioned_link_or_copy install_dir base_name suffix)
qt_path_join(install_base_file_path "$\{qt_full_install_prefix}"
- "${install_dir}" "$<TARGET_FILE_BASE_NAME:${target}>")
- set(original "${install_base_file_path}$<TARGET_FILE_SUFFIX:${target}>")
- set(linkname "${install_base_file_path}${PROJECT_VERSION_MAJOR}$<TARGET_FILE_SUFFIX:${target}>")
+ "${install_dir}" "${base_name}")
+ set(original "${install_base_file_path}${suffix}")
+ set(linkname "${install_base_file_path}${PROJECT_VERSION_MAJOR}${suffix}")
set(code "set(qt_full_install_prefix \"$\{CMAKE_INSTALL_PREFIX}\")"
" if(NOT \"$ENV\{DESTDIR}\" STREQUAL \"\")"
)
+
if(CMAKE_HOST_WIN32)
list(APPEND code
" if(qt_full_install_prefix MATCHES \"^[a-zA-Z]:\")"
@@ -167,3 +183,67 @@ function(qt_internal_install_versioned_link install_dir target)
list(JOIN code "\n" code)
install(CODE "${code}")
endfunction()
+
+# Use case is copying files or directories in a non-prefix build with each build, so that changes
+# are available each time, this is useful for some Android templates that are needed for building,
+# apks and need to sync changes each time a build is started
+function(qt_internal_copy_at_build_time)
+ set(flags)
+ set(options TARGET DESTINATION)
+ set(multiopts FILES DIRECTORIES)
+ cmake_parse_arguments(arg "${flags}" "${options}" "${multiopts}" ${ARGN})
+
+ file(MAKE_DIRECTORY "${arg_DESTINATION}")
+
+ unset(outputs)
+ foreach(dir_to_copy IN LISTS arg_DIRECTORIES)
+ get_filename_component(file_name "${dir_to_copy}" NAME)
+ set(destination_file_name "${arg_DESTINATION}/${file_name}")
+
+ file(GLOB_RECURSE all_files_in_dir RELATIVE "${dir_to_copy}" "${dir_to_copy}/*")
+ set(dir_outputs ${all_files_in_dir})
+ set(dir_deps ${all_files_in_dir})
+
+ list(TRANSFORM dir_outputs PREPEND "${destination_file_name}/")
+ list(TRANSFORM dir_deps PREPEND "${dir_to_copy}/")
+
+ add_custom_command(OUTPUT ${dir_outputs}
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${dir_to_copy} "${destination_file_name}"
+ DEPENDS ${dir_deps}
+ COMMENT "Copying directory ${dir_to_copy} to ${arg_DESTINATION}."
+ )
+ list(APPEND outputs ${dir_outputs})
+ endforeach()
+
+ unset(file_outputs)
+ unset(files_to_copy)
+ foreach(path_to_copy IN LISTS arg_FILES)
+ get_filename_component(file_name "${path_to_copy}" NAME)
+ set(destination_file_name "${arg_DESTINATION}/${file_name}")
+
+ list(APPEND file_outputs "${destination_file_name}")
+ list(APPEND files_to_copy "${path_to_copy}")
+ endforeach()
+
+ if(files_to_copy)
+ add_custom_command(OUTPUT ${file_outputs}
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${files_to_copy} ${arg_DESTINATION}
+ DEPENDS ${files_to_copy}
+ COMMENT "Copying files ${files_to_copy} to ${arg_DESTINATION}."
+ )
+ list(APPEND outputs ${file_outputs})
+ endif()
+
+ get_property(count GLOBAL PROPERTY _qt_internal_copy_at_build_time_count)
+ if(NOT count)
+ set(count 0)
+ endif()
+
+ add_custom_target(qt_internal_copy_at_build_time_${count} DEPENDS ${outputs})
+ if(arg_TARGET)
+ add_dependencies(${arg_TARGET} qt_internal_copy_at_build_time_${count})
+ endif()
+
+ math(EXPR count "${count} + 1")
+ set_property(GLOBAL PROPERTY _qt_internal_copy_at_build_time_count ${count})
+endfunction()