Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'cmake/delayed_configure_files.cmake')
-rw-r--r--cmake/delayed_configure_files.cmake115
1 files changed, 115 insertions, 0 deletions
diff --git a/cmake/delayed_configure_files.cmake b/cmake/delayed_configure_files.cmake
new file mode 100644
index 000000000..c75200564
--- /dev/null
+++ b/cmake/delayed_configure_files.cmake
@@ -0,0 +1,115 @@
+# Copyright 2022 The Mumble Developers. All rights reserved.
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file at the root of the
+# Mumble source tree or at <https://www.mumble.info/LICENSE>.
+
+# This function allows to delay calls to configure_file to the post-build phase. This can become necessary, if one wants to
+# use the result of generator expressions for the substitutions performed via configure_file. Generator expressions are only
+# evaluated at build time, while configure_file runs at configure time. To work around this issue, this function will create
+# an auxiliary target that generates a new cmake script at build time and this cmake script in turn will call configure_file.
+# The variables set in that cmake script are passed as arguments to this function. Since the auxiliary script is generated
+# at build time, generator expressions can be used in the variable definitions.
+#
+# Parameters:
+# PYTHON_INTERPRETER <path> Path to a working Python interpreter. Mandatory argument.
+# FILES <inFile=outFile> ... Set of files to configure as key-value-pairs (in-file=out-file). Mandatory argument.
+# TARGET <target> If given, it is made sure that <target> is fully built, before the configure_file action happens
+# SCRIPT_NAME <name> The name of the auxiliary cmake script. If not provided, a default name is generated
+# PASSTHROUGH_VARIABLES <var> ... Set of existing variables to pass-through to the generated script so that they can be used
+# in the configured file(s).
+# VARIABLES <name=value> ... Set of additional variables defined as key-value-pairs. The definition of <value> may make
+# use of generator expressions.
+# @ONLY Passes the @ONLY parameter to the generated configure_file invocations
+function(delayed_configure_files)
+ set(options "@ONLY")
+ set(oneValueArgs TARGET SCRIPT_NAME PYTHON_INTERPRETER)
+ set(multiValueArgs FILES PASSTHROUGH_VARIABLES VARIABLES)
+
+ cmake_parse_arguments(DELAYED_CONFIGURE_FILES "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ if(DELAYED_CONFIGURE_FILES_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "Unrecognized arguments to delayed_configure_file: \"${DELAYED_CONFIGURE_FILES_UNPARSED_ARGUMENTS}\"")
+ endif()
+ # Check required args
+ if(NOT DELAYED_CONFIGURE_FILES_FILES)
+ message(FATAL_ERROR "Called delayed_configure_files without the FILES parameter")
+ endif()
+ if(DELAYED_CONFIGURE_FILES_TARGET)
+ if(NOT TARGET ${DELAYED_CONFIGURE_FILES_TARGET})
+ message(FATAL_ERROR "delayed_configure_files: Provided target \"${DELAYED_CONFIGURE_FILES_TARGET}\" is not actually a (valid) target")
+ endif()
+ endif()
+ if(NOT DELAYED_CONFIGURE_FILES_PYTHON_INTERPRETER)
+ message(FATAL_ERROR "Called delayed_configure_files without the PYTHON_INTERPRETER parameter")
+ endif()
+
+
+ # Generate a free target name
+ set(AUX_TARGET_NUM 1)
+ set(AUX_TARGET_BASENAME "delayed_configure_files_target_")
+ while(TARGET "${AUX_TARGET_BASENAME}${AUX_TARGET_NUM}")
+ math(EXPR AUX_TARGET_NUM "${AUX_TARGET_NUM} + 1")
+ endwhile()
+ set(AUX_TARGET_NAME "${AUX_TARGET_BASENAME}${AUX_TARGET_NUM}")
+
+
+ # Handle defaults
+ if(NOT DELAYED_CONFIGURE_FILES_SCRIPT_NAME)
+ set(DELAYED_CONFIGURE_FILES_SCRIPT_NAME "configure_files_${AUX_TARGET_NUM}.cmake")
+ endif()
+
+ if(DELAYED_CONFIGURE_FILES_@ONLY)
+ set(AT_ONLY "--at-only")
+ else()
+ set(AT_ONLY "")
+ endif()
+
+
+ if(DELAYED_CONFIGURE_FILES_VARIABLES)
+ set(VARIABLES ${DELAYED_CONFIGURE_FILES_VARIABLES})
+ else()
+ set(VARIABLES "")
+ endif()
+ if(DELAYED_CONFIGURE_FILES_PASSTHROUGH_VARIABLES)
+ foreach(CURRENT_VAR IN LISTS DELAYED_CONFIGURE_FILES_PASSTHROUGH_VARIABLES)
+ if(NOT DEFINED ${CURRENT_VAR})
+ message(FATAL_ERROR "delayed_configure_files: Can't passthrough non-existing variable \"${CURRENT_VAR}\"")
+ endif()
+
+ list(APPEND VARIABLES "${CURRENT_VAR}=${${CURRENT_VAR}}")
+ endforeach()
+ endif()
+
+ if(NOT VARIABLES STREQUAL "")
+ set(VARIABLES --variables ${VARIABLES})
+ endif()
+
+
+
+ # Create a command to generate an intermediary cmake script that will take care of configuring the respective
+ # files, once executed
+ add_custom_command(
+ OUTPUT "${DELAYED_CONFIGURE_FILES_SCRIPT_NAME}"
+ COMMAND "${DELAYED_CONFIGURE_FILES_PYTHON_INTERPRETER}"
+ ARGS "${CMAKE_SOURCE_DIR}/scripts/generate_configure_cmake_script.py"
+ --files ${DELAYED_CONFIGURE_FILES_FILES} ${VARIABLES}
+ --output "${DELAYED_CONFIGURE_FILES_SCRIPT_NAME}"
+ ${AT_ONLY}
+ COMMENT "Generating delayed configure script ${DELAYED_CONFIGURE_FILES_SCRIPT_NAME}"
+ )
+
+ # Create a target that will execute the generated cmake script. Make sure that this target will be
+ # added to the default build target, ensuring that it is always executed.
+ add_custom_target(
+ ${AUX_TARGET_NAME} ALL
+ DEPENDS "${DELAYED_CONFIGURE_FILES_SCRIPT_NAME}"
+ COMMAND "${CMAKE_COMMAND}" -P "${DELAYED_CONFIGURE_FILES_SCRIPT_NAME}"
+ COMMENT "Executing delayed configure script ${DELAYED_CONFIGURE_FILES_SCRIPT_NAME}"
+ )
+
+ if(DELAYED_CONFIGURE_FILES_TARGET)
+ # Make our auxiliary target depend on the provided main target to ensure that the main target is always built
+ # before our auxiliary target executes.
+ add_dependencies(${AUX_TARGET_NAME} ${DELAYED_CONFIGURE_FILES_TARGET})
+ endif()
+endfunction()