Add function to add and compile executables at configure time
qt_internal_add_configure_time_executable compiles the executable at configure time and exposes it to the CMake source tree. This is useful when need to run a small C++ program at configure time. Task-number: QTBUG-87480 Change-Id: I031efe797c8afa0721d75b46d4f36f67276bf46e Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
This commit is contained in:
parent
f0a40991fa
commit
ac74b60c9c
@ -223,6 +223,7 @@ qt_copy_or_install(FILES
|
|||||||
cmake/QtCompilerFlags.cmake
|
cmake/QtCompilerFlags.cmake
|
||||||
cmake/QtCompilerOptimization.cmake
|
cmake/QtCompilerOptimization.cmake
|
||||||
cmake/QtConfigDependencies.cmake.in
|
cmake/QtConfigDependencies.cmake.in
|
||||||
|
cmake/QtConfigureTimeExecutableCMakeLists.txt.in
|
||||||
cmake/QtDeferredDependenciesHelpers.cmake
|
cmake/QtDeferredDependenciesHelpers.cmake
|
||||||
cmake/QtDbusHelpers.cmake
|
cmake/QtDbusHelpers.cmake
|
||||||
cmake/QtDocsHelpers.cmake
|
cmake/QtDocsHelpers.cmake
|
||||||
|
21
cmake/QtConfigureTimeExecutableCMakeLists.txt.in
Normal file
21
cmake/QtConfigureTimeExecutableCMakeLists.txt.in
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
project(@configure_time_target@ LANGUAGES CXX)
|
||||||
|
|
||||||
|
set(packages "@packages@")
|
||||||
|
set(defines @defines@)
|
||||||
|
set(compile_options @compile_options@)
|
||||||
|
set(link_options @link_options@)
|
||||||
|
|
||||||
|
foreach(package IN LISTS packages)
|
||||||
|
find_package(${package} REQUIRED)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
add_executable(@configure_time_target@ @win32@ @macosx_bundle@ @sources@)
|
||||||
|
set_target_properties(@configure_time_target@ PROPERTIES
|
||||||
|
INCLUDE_DIRECTORIES "@include_directories@"
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_options(@configure_time_target@ PRIVATE ${compile_options})
|
||||||
|
target_compile_definitions(@configure_time_target@ PRIVATE ${defines})
|
||||||
|
target_link_options(@configure_time_target@ PRIVATE ${link_options})
|
@ -295,3 +295,166 @@ Q_IMPORT_PLUGIN($<JOIN:${class_names},)\nQ_IMPORT_PLUGIN(>)
|
|||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
# This function compiles the target at configure time the very first time and creates the custom
|
||||||
|
# ${target}_build that re-runs compilation at build time if necessary. The resulting executable is
|
||||||
|
# imported under the provided target name. This function should only be used to compile tiny
|
||||||
|
# executables with system dependencies only.
|
||||||
|
# One-value Arguments:
|
||||||
|
# CMAKELISTS_TEMPLATE
|
||||||
|
# The CMakeLists.txt templated that is used to configure the project
|
||||||
|
# for an executable. By default the predefined template from the Qt installation is used.
|
||||||
|
# INSTALL_DIRECTORY
|
||||||
|
# installation directory of the executable. Ignored if NO_INSTALL is set.
|
||||||
|
# OUTPUT_NAME
|
||||||
|
# the output name of an executable
|
||||||
|
# CONFIG
|
||||||
|
# the name of configuration that tool needs to be build with.
|
||||||
|
# Multi-value Arguments:
|
||||||
|
# PACKAGES
|
||||||
|
# list of system packages are required to successfully build the project.
|
||||||
|
# INCLUDES
|
||||||
|
# list of include directories are required to successfully build the project.
|
||||||
|
# DEFINES
|
||||||
|
# list of definitions are required to successfully build the project.
|
||||||
|
# COMPILE_OPTIONS
|
||||||
|
# list of compiler options are required to successfully build the project.
|
||||||
|
# LINK_OPTIONS
|
||||||
|
# list of linker options are required to successfully build the project.
|
||||||
|
# SOURCES
|
||||||
|
# list of project sources.
|
||||||
|
# CMAKE_FLAGS
|
||||||
|
# specify flags of the form -DVAR:TYPE=VALUE to be passed to the cmake command-line used to
|
||||||
|
# drive the test build.
|
||||||
|
# Options:
|
||||||
|
# WIN32
|
||||||
|
# reflects the corresponding add_executable argument.
|
||||||
|
# MACOSX_BUNDLE
|
||||||
|
# reflects the corresponding add_executable argument.
|
||||||
|
# NO_INSTALL
|
||||||
|
# avoids installing the tool.
|
||||||
|
function(qt_internal_add_configure_time_executable target)
|
||||||
|
set(one_value_args
|
||||||
|
CMAKELISTS_TEMPLATE
|
||||||
|
INSTALL_DIRECTORY
|
||||||
|
OUTPUT_NAME
|
||||||
|
CONFIG
|
||||||
|
)
|
||||||
|
set(multi_value_args
|
||||||
|
PACKAGES
|
||||||
|
INCLUDES
|
||||||
|
DEFINES
|
||||||
|
COMPILE_OPTIONS
|
||||||
|
LINK_OPTIONS
|
||||||
|
SOURCES
|
||||||
|
CMAKE_FLAGS
|
||||||
|
)
|
||||||
|
set(option_args WIN32 MACOSX_BUNDLE NO_INSTALL)
|
||||||
|
cmake_parse_arguments(arg "${option_args}" "${one_value_args}" "${multi_value_args}" ${ARGN})
|
||||||
|
|
||||||
|
set(target_binary_dir "${CMAKE_CURRENT_BINARY_DIR}/configure_time_bins")
|
||||||
|
if(arg_CONFIG)
|
||||||
|
set(CMAKE_TRY_COMPILE_CONFIGURATION "${arg_CONFIG}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
|
||||||
|
if(is_multi_config AND CMAKE_TRY_COMPILE_CONFIGURATION)
|
||||||
|
set(configuration_path "${CMAKE_TRY_COMPILE_CONFIGURATION}/")
|
||||||
|
set(config_build_arg "--config" "${CMAKE_TRY_COMPILE_CONFIGURATION}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(configure_time_target "${target}")
|
||||||
|
if(arg_OUTPUT_NAME)
|
||||||
|
set(configure_time_target "${arg_OUTPUT_NAME}")
|
||||||
|
endif()
|
||||||
|
set(target_binary "${configure_time_target}${CMAKE_EXECUTABLE_SUFFIX}")
|
||||||
|
set(target_binary_path
|
||||||
|
"${target_binary_dir}/${configuration_path}${target_binary}")
|
||||||
|
get_filename_component(target_binary_path "${target_binary_path}" ABSOLUTE)
|
||||||
|
|
||||||
|
if(NOT DEFINED arg_SOURCES)
|
||||||
|
message(FATAL_ERROR "No SOURCES given to target: ${target}")
|
||||||
|
endif()
|
||||||
|
set(sources "${arg_SOURCES}")
|
||||||
|
|
||||||
|
# Timestamp file is required because CMake ignores 'add_custom_command' if we use only the
|
||||||
|
# binary file as the OUTPUT.
|
||||||
|
set(timestamp_file "${target_binary_path}_timestamp")
|
||||||
|
add_custom_command(OUTPUT "${target_binary_path}" "${timestamp_file}"
|
||||||
|
COMMAND
|
||||||
|
${CMAKE_COMMAND} --build "${target_binary_dir}" ${config_build_arg}
|
||||||
|
COMMAND
|
||||||
|
${CMAKE_COMMAND} -E touch "${timestamp_file}"
|
||||||
|
DEPENDS
|
||||||
|
${sources}
|
||||||
|
COMMENT
|
||||||
|
"Compiling ${target}"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(${target}_build ALL
|
||||||
|
DEPENDS
|
||||||
|
"${target_binary_path}"
|
||||||
|
"${timestamp_file}"
|
||||||
|
)
|
||||||
|
|
||||||
|
if(NOT EXISTS "${target_binary_path}")
|
||||||
|
foreach(arg IN LISTS multi_value_args)
|
||||||
|
string(TOLOWER "${arg}" template_arg_name)
|
||||||
|
set(${template_arg_name} "")
|
||||||
|
if(DEFINED arg_${arg})
|
||||||
|
set(${template_arg_name} "${arg_${arg}}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
foreach(arg IN LISTS option_args)
|
||||||
|
string(TOLOWER "${arg}" template_arg_name)
|
||||||
|
set(${template_arg_name} "")
|
||||||
|
if(arg_${arg})
|
||||||
|
set(${template_arg_name} "${arg}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
file(MAKE_DIRECTORY "${target_binary_dir}")
|
||||||
|
set(template "${QT_CMAKE_DIR}/QtConfigureTimeExecutableCMakeLists.txt.in")
|
||||||
|
if(DEFINED arg_CMAKELISTS_TEMPLATE)
|
||||||
|
set(template "${arg_CMAKELISTS_TEMPLATE}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(cmake_flags_arg)
|
||||||
|
if(arg_CMAKE_FLAGS)
|
||||||
|
set(cmake_flags_arg CMAKE_FLAGS ${arg_CMAKE_FLAGS})
|
||||||
|
endif()
|
||||||
|
configure_file("${template}" "${target_binary_dir}/CMakeLists.txt" @ONLY)
|
||||||
|
try_compile(result
|
||||||
|
"${target_binary_dir}"
|
||||||
|
"${target_binary_dir}"
|
||||||
|
${target}
|
||||||
|
${cmake_flags_arg}
|
||||||
|
OUTPUT_VARIABLE try_compile_output
|
||||||
|
)
|
||||||
|
|
||||||
|
if(NOT result)
|
||||||
|
message(FATAL_ERROR "Unable to build ${target}: ${try_compile_output}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_executable(${target} IMPORTED GLOBAL)
|
||||||
|
add_executable(${QT_CMAKE_EXPORT_NAMESPACE}::${target} ALIAS ${target})
|
||||||
|
set_target_properties(${target} PROPERTIES
|
||||||
|
_qt_internal_configure_time_target TRUE
|
||||||
|
IMPORTED_LOCATION "${target_binary_path}")
|
||||||
|
|
||||||
|
if(NOT arg_NO_INSTALL)
|
||||||
|
set(install_dir "${INSTALL_BINDIR}")
|
||||||
|
if(arg_INSTALL_DIRECTORY)
|
||||||
|
set(install_dir "${arg_INSTALL_DIRECTORY}")
|
||||||
|
endif()
|
||||||
|
set_target_properties(${target} PROPERTIES
|
||||||
|
_qt_internal_configure_time_target_install_location
|
||||||
|
"${install_dir}/${target_binary}"
|
||||||
|
)
|
||||||
|
qt_path_join(target_install_dir ${QT_INSTALL_DIR} ${install_dir})
|
||||||
|
qt_copy_or_install(PROGRAMS "${target_binary_path}" DESTINATION "${target_install_dir}")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
@ -508,6 +508,24 @@ endif()
|
|||||||
|
|
||||||
set(properties_retrieved TRUE)
|
set(properties_retrieved TRUE)
|
||||||
|
|
||||||
|
get_target_property(is_configure_time_target ${target} _qt_internal_configure_time_target)
|
||||||
|
if(is_configure_time_target)
|
||||||
|
get_target_property(configure_time_target_install_location ${target}
|
||||||
|
_qt_internal_configure_time_target_install_location)
|
||||||
|
if(configure_time_target_install_location)
|
||||||
|
string(APPEND content "
|
||||||
|
# Import configure-time executable ${full_target}
|
||||||
|
if(NOT TARGET ${full_target})
|
||||||
|
add_executable(${full_target} IMPORTED)
|
||||||
|
set_property(TARGET ${full_target} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${default_cfg})
|
||||||
|
set_target_properties(${full_target} PROPERTIES IMPORTED_LOCATION_${uc_default_cfg}
|
||||||
|
\"$\\{PACKAGE_PREFIX_DIR}/${configure_time_target_install_location}\")
|
||||||
|
set_property(TARGET ${full_target} PROPERTY IMPORTED_GLOBAL TRUE)
|
||||||
|
endif()
|
||||||
|
\n")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# Non-prefix debug-and-release builds: add check for the existence of the debug binary of
|
# Non-prefix debug-and-release builds: add check for the existence of the debug binary of
|
||||||
# the target. It is not built by default.
|
# the target. It is not built by default.
|
||||||
if(NOT QT_WILL_INSTALL AND QT_FEATURE_debug_and_release)
|
if(NOT QT_WILL_INSTALL AND QT_FEATURE_debug_and_release)
|
||||||
@ -521,7 +539,7 @@ if(NOT EXISTS \"$\\{_qt_imported_location}\")
|
|||||||
list(REMOVE_ITEM _qt_imported_configs DEBUG)
|
list(REMOVE_ITEM _qt_imported_configs DEBUG)
|
||||||
set_property(TARGET ${full_target} PROPERTY IMPORTED_CONFIGURATIONS $\\{_qt_imported_configs})
|
set_property(TARGET ${full_target} PROPERTY IMPORTED_CONFIGURATIONS $\\{_qt_imported_configs})
|
||||||
set_property(TARGET ${full_target} PROPERTY IMPORTED_LOCATION_DEBUG)
|
set_property(TARGET ${full_target} PROPERTY IMPORTED_LOCATION_DEBUG)
|
||||||
endif()\n\n")
|
endif()\n")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -605,3 +605,45 @@ function(qt_internal_find_tool out_var target_name tools_target)
|
|||||||
endif()
|
endif()
|
||||||
set(${out_var} "TRUE" PARENT_SCOPE)
|
set(${out_var} "TRUE" PARENT_SCOPE)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
# This function adds an internal tool that should be compiled at configure time.
|
||||||
|
# TOOLS_TARGET
|
||||||
|
# Specifies the module this tool belongs to. The Qt6${TOOLS_TARGET}Tools module
|
||||||
|
# will then expose targets for this tool. Ignored if NO_INSTALL is set.
|
||||||
|
function(qt_internal_add_configure_time_tool target_name)
|
||||||
|
set(one_value_args INSTALL_DIRECTORY TOOLS_TARGET)
|
||||||
|
set(multi_value_args)
|
||||||
|
set(option_args NO_INSTALL)
|
||||||
|
cmake_parse_arguments(arg "${option_args}" "${one_value_args}" "${multi_value_args}" ${ARGN})
|
||||||
|
|
||||||
|
qt_internal_find_tool(will_build_tools ${target_name} "${arg_TOOLS_TARGET}")
|
||||||
|
if(NOT will_build_tools)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
qt_tool_target_to_name(name ${target_name})
|
||||||
|
set(extra_args "")
|
||||||
|
if(arg_NO_INSTALL OR NOT arg_TOOLS_TARGET)
|
||||||
|
list(APPEND extra_args "NO_INSTALL")
|
||||||
|
else()
|
||||||
|
set(install_dir "${INSTALL_BINDIR}")
|
||||||
|
if(arg_INSTALL_DIRECTORY)
|
||||||
|
set(install_dir "${arg_INSTALL_DIRECTORY}")
|
||||||
|
endif()
|
||||||
|
set(extra_args "INSTALL_DIRECTORY" "${install_dir}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
qt_internal_add_configure_time_executable(${target_name}
|
||||||
|
OUTPUT_NAME ${name}
|
||||||
|
${extra_args}
|
||||||
|
${arg_UNPARSED_ARGUMENTS}
|
||||||
|
)
|
||||||
|
|
||||||
|
if(NOT arg_NO_INSTALL AND arg_TOOLS_TARGET)
|
||||||
|
qt_internal_add_targets_to_additional_targets_export_file(
|
||||||
|
TARGETS ${target_name}
|
||||||
|
TARGET_EXPORT_NAMES ${QT_CMAKE_EXPORT_NAMESPACE}::${name}
|
||||||
|
EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${arg_TOOLS_TARGET}Tools
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user