CMake: Add Linux support to qt_deploy_runtime_dependencies
Before this change, qt_deploy_runtime_dependencies supported Windows and macOS only. We add a generic deployment method implemented in cmake-language with file(GET_RUNTIME_DEPENDENCIES). This deployment method is now enabled for shared builds on Linux. The file(GRD) command requires that the EXECUTABLE argument points to the executable in the build directory. Only libraries in Qt's installation directory are considered for deployment. This includes Qt's own libraries and also things like libicu*.so we're shipping with the installer. Unlike macdeployqt and windeployqt, the generic qt_deploy_runtime_dependencies does not yet support deploying translations. We will catch up on this in a later commit. Change-Id: Iea23abcdba774d4c1885c8d2c243eb3e48fb7fae Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
This commit is contained in:
parent
6329fed0a8
commit
c9c04291f5
@ -39,22 +39,32 @@ endfunction()
|
||||
#
|
||||
# The conditions are based on the various properties set in qt_import_plugins.
|
||||
|
||||
# All the TARGET_PROPERTY genexes are evaluated in the context of the currently linked target.
|
||||
# All the TARGET_PROPERTY genexes are evaluated in the context of the currently linked target,
|
||||
# unless the TARGET argument is given.
|
||||
#
|
||||
# The genex is saved into out_var.
|
||||
function(__qt_internal_get_static_plugin_condition_genex
|
||||
plugin_target_unprefixed
|
||||
out_var)
|
||||
set(options)
|
||||
set(oneValueArgs TARGET)
|
||||
set(multiValueArgs)
|
||||
cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
set(plugin_target "${QT_CMAKE_EXPORT_NAMESPACE}::${plugin_target_unprefixed}")
|
||||
set(plugin_target_versionless "Qt::${plugin_target_unprefixed}")
|
||||
|
||||
get_target_property(_plugin_type "${plugin_target}" QT_PLUGIN_TYPE)
|
||||
|
||||
set(target_infix "")
|
||||
if(arg_TARGET)
|
||||
set(target_infix "${arg_TARGET},")
|
||||
endif()
|
||||
|
||||
set(_default_plugins_are_enabled
|
||||
"$<NOT:$<STREQUAL:$<GENEX_EVAL:$<TARGET_PROPERTY:QT_DEFAULT_PLUGINS>>,0>>")
|
||||
set(_manual_plugins_genex "$<GENEX_EVAL:$<TARGET_PROPERTY:QT_PLUGINS>>")
|
||||
set(_no_plugins_genex "$<GENEX_EVAL:$<TARGET_PROPERTY:QT_NO_PLUGINS>>")
|
||||
"$<NOT:$<STREQUAL:$<GENEX_EVAL:$<TARGET_PROPERTY:${target_infix}QT_DEFAULT_PLUGINS>>,0>>")
|
||||
set(_manual_plugins_genex "$<GENEX_EVAL:$<TARGET_PROPERTY:${target_infix}QT_PLUGINS>>")
|
||||
set(_no_plugins_genex "$<GENEX_EVAL:$<TARGET_PROPERTY:${target_infix}QT_NO_PLUGINS>>")
|
||||
|
||||
# Plugin genex marker for prl processing.
|
||||
set(_is_plugin_marker_genex "$<BOOL:QT_IS_PLUGIN_GENEX>")
|
||||
@ -81,7 +91,7 @@ function(__qt_internal_get_static_plugin_condition_genex
|
||||
">,"
|
||||
# Excludes both plugins targeted by EXCLUDE_BY_TYPE and not included in
|
||||
# INCLUDE_BY_TYPE.
|
||||
"$<STREQUAL:,$<GENEX_EVAL:$<TARGET_PROPERTY:QT_PLUGINS_${_plugin_type}>>>"
|
||||
"$<STREQUAL:,$<GENEX_EVAL:$<TARGET_PROPERTY:${target_infix}QT_PLUGINS_${_plugin_type}>>>"
|
||||
">"
|
||||
)
|
||||
|
||||
@ -90,7 +100,7 @@ function(__qt_internal_get_static_plugin_condition_genex
|
||||
"$<IN_LIST:"
|
||||
"${plugin_target},"
|
||||
"$<GENEX_EVAL:"
|
||||
"$<TARGET_PROPERTY:QT_PLUGINS_${_plugin_type}>"
|
||||
"$<TARGET_PROPERTY:${target_infix}QT_PLUGINS_${_plugin_type}>"
|
||||
">"
|
||||
">"
|
||||
)
|
||||
@ -98,7 +108,7 @@ function(__qt_internal_get_static_plugin_condition_genex
|
||||
"$<IN_LIST:"
|
||||
"${plugin_target_versionless},"
|
||||
"$<GENEX_EVAL:"
|
||||
"$<TARGET_PROPERTY:QT_PLUGINS_${_plugin_type}>"
|
||||
"$<TARGET_PROPERTY:${target_infix}QT_PLUGINS_${_plugin_type}>"
|
||||
">"
|
||||
">"
|
||||
)
|
||||
@ -106,7 +116,7 @@ function(__qt_internal_get_static_plugin_condition_genex
|
||||
# No point in linking the plugin initialization source file into static libraries. The
|
||||
# initialization symbol will be discarded by the linker when the static lib is linked into an
|
||||
# executable or shared library, because nothing is referencing the global static symbol.
|
||||
set(type_genex "$<TARGET_PROPERTY:TYPE>")
|
||||
set(type_genex "$<TARGET_PROPERTY:${target_infix}TYPE>")
|
||||
set(no_static_genex "$<NOT:$<STREQUAL:${type_genex},STATIC_LIBRARY>>")
|
||||
|
||||
# Complete condition that defines whether a static plugin is linked
|
||||
@ -308,6 +318,25 @@ function(__qt_internal_collect_plugin_init_libraries plugin_targets out_var)
|
||||
set("${out_var}" "${plugin_inits_to_link}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Collect a list of genexes to deploy plugin libraries.
|
||||
function(__qt_internal_collect_plugin_library_files target plugin_targets out_var)
|
||||
set(library_files "")
|
||||
|
||||
foreach(plugin_target ${plugin_targets})
|
||||
set(plugin_target_versioned "${QT_CMAKE_EXPORT_NAMESPACE}::${plugin_target}")
|
||||
__qt_internal_get_static_plugin_condition_genex(
|
||||
"${plugin_target}"
|
||||
plugin_condition
|
||||
TARGET ${target}
|
||||
)
|
||||
|
||||
set(target_genex "$<${plugin_condition}:${plugin_target_versioned}>")
|
||||
list(APPEND library_files "$<$<BOOL:${target_genex}>:$<TARGET_FILE:${target_genex}>>")
|
||||
endforeach()
|
||||
|
||||
set("${out_var}" "${library_files}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Collects all plugin targets discovered by walking the dependencies of ${target}.
|
||||
#
|
||||
# Walks immediate dependencies and their transitive dependencies.
|
||||
@ -387,6 +416,29 @@ function(__qt_internal_collect_plugin_targets_from_dependencies_of_plugins targe
|
||||
set("${out_var}" "${plugin_targets}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(__qt_internal_generate_plugin_deployment_info target plugin_targets)
|
||||
get_target_property(marked_for_deployment ${target} _qt_marked_for_deployment)
|
||||
if(NOT marked_for_deployment)
|
||||
return()
|
||||
endif()
|
||||
|
||||
__qt_internal_collect_plugin_library_files(${target} "${plugin_targets}" plugins_files)
|
||||
set(plugins_files "$<FILTER:${plugins_files},EXCLUDE,^$>")
|
||||
|
||||
_qt_internal_get_deploy_impl_dir(deploy_impl_dir)
|
||||
set(file_path "${deploy_impl_dir}/${target}-plugins")
|
||||
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
|
||||
if(is_multi_config)
|
||||
string(APPEND file_path "-$<CONFIG>")
|
||||
endif()
|
||||
string(APPEND file_path ".cmake")
|
||||
|
||||
file(GENERATE
|
||||
OUTPUT ${file_path}
|
||||
CONTENT "set(__QT_DEPLOY_PLUGINS ${plugins_files})"
|
||||
)
|
||||
endfunction()
|
||||
|
||||
# Main logic of finalizer mode.
|
||||
function(__qt_internal_apply_plugin_imports_finalizer_mode target)
|
||||
# Process a target only once.
|
||||
@ -395,6 +447,9 @@ function(__qt_internal_apply_plugin_imports_finalizer_mode target)
|
||||
return()
|
||||
endif()
|
||||
|
||||
__qt_internal_collect_plugin_targets_from_dependencies("${target}" plugin_targets)
|
||||
__qt_internal_generate_plugin_deployment_info(${target} "${plugin_targets}")
|
||||
|
||||
# By default if the project hasn't explicitly opted in or out, use finalizer mode.
|
||||
# The precondition for this is that qt_finalize_target was called (either explicitly by the user
|
||||
# or auto-deferred by CMake 3.19+).
|
||||
@ -408,7 +463,6 @@ function(__qt_internal_apply_plugin_imports_finalizer_mode target)
|
||||
return()
|
||||
endif()
|
||||
|
||||
__qt_internal_collect_plugin_targets_from_dependencies("${target}" plugin_targets)
|
||||
__qt_internal_collect_plugin_init_libraries("${plugin_targets}" init_libraries)
|
||||
__qt_internal_collect_plugin_libraries("${plugin_targets}" plugin_libraries)
|
||||
|
||||
|
@ -105,6 +105,108 @@ if(NOT __QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
|
||||
endfunction()
|
||||
endif()
|
||||
|
||||
# Copied from QtCMakeHelpers.cmake
|
||||
function(_qt_internal_re_escape out_var str)
|
||||
string(REGEX REPLACE "([][+.*()^])" "\\\\\\1" regex "${str}")
|
||||
set(${out_var} ${regex} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(_qt_internal_generic_deployqt)
|
||||
set(no_value_options
|
||||
VERBOSE
|
||||
)
|
||||
set(single_value_options
|
||||
EXECUTABLE
|
||||
LIB_DIR
|
||||
PLUGINS_DIR
|
||||
)
|
||||
set(multi_value_options
|
||||
ADDITIONAL_EXECUTABLES
|
||||
ADDITIONAL_LIBRARIES
|
||||
ADDITIONAL_MODULES
|
||||
)
|
||||
cmake_parse_arguments(PARSE_ARGV 0 arg
|
||||
"${no_value_options}" "${single_value_options}" "${multi_value_options}"
|
||||
)
|
||||
|
||||
if(arg_VERBOSE OR __QT_DEPLOY_VERBOSE)
|
||||
set(verbose TRUE)
|
||||
endif()
|
||||
|
||||
# Make input file paths absolute
|
||||
foreach(var IN ITEMS EXECUTABLE ADDITIONAL_EXECUTABLES ADDITIONAL_LIBRARIES ADDITIONAL_MODULES)
|
||||
string(PREPEND var arg_)
|
||||
set(abspaths "")
|
||||
foreach(path IN LISTS ${var})
|
||||
get_filename_component(abspath "${path}" REALPATH BASE_DIR "${QT_DEPLOY_PREFIX}")
|
||||
list(APPEND abspaths "${abspath}")
|
||||
endforeach()
|
||||
set(${var} "${abspaths}")
|
||||
endforeach()
|
||||
|
||||
# We need to get the runtime dependencies of plugins too.
|
||||
list(APPEND arg_ADDITIONAL_MODULES ${__QT_DEPLOY_PLUGINS})
|
||||
|
||||
set(file_args "")
|
||||
if(arg_EXECUTABLE OR arg_ADDITIONAL_EXECUTABLES)
|
||||
list(APPEND file_args EXECUTABLES ${arg_EXECUTABLE} ${arg_ADDITIONAL_EXECUTABLES})
|
||||
endif()
|
||||
if(arg_ADDITIONAL_LIBRARIES)
|
||||
list(APPEND file_args LIBRARIES ${arg_ADDITIONAL_LIBRARIES})
|
||||
endif()
|
||||
if(arg_ADDITIONAL_MODULES)
|
||||
list(APPEND file_args MODULES ${arg_ADDITIONAL_MODULES})
|
||||
endif()
|
||||
|
||||
# Compile a list of regular expressions that represent the Qt installation prefixes.
|
||||
set(prefix_regexes)
|
||||
foreach(path IN LISTS __QT_DEPLOY_QT_INSTALL_PREFIX
|
||||
__QT_DEPLOY_QT_ADDITIONAL_PACKAGES_PREFIX_PATH)
|
||||
_qt_internal_re_escape(path_rex "${path}")
|
||||
list(APPEND prefix_regexes "^${path_rex}")
|
||||
endforeach()
|
||||
|
||||
# Get the runtime dependencies recursively, restricted to Qt's installation prefix.
|
||||
file(GET_RUNTIME_DEPENDENCIES
|
||||
${file_args}
|
||||
POST_INCLUDE_REGEXES ${prefix_regexes}
|
||||
POST_EXCLUDE_REGEXES ".*"
|
||||
RESOLVED_DEPENDENCIES_VAR resolved
|
||||
UNRESOLVED_DEPENDENCIES_VAR unresolved
|
||||
CONFLICTING_DEPENDENCIES_PREFIX conflicting
|
||||
)
|
||||
if(verbose)
|
||||
message("file(GET_RUNTIME_DEPENDENCIES ${file_args})")
|
||||
foreach(file IN LISTS resolved)
|
||||
message(" resolved: ${file}")
|
||||
endforeach()
|
||||
foreach(file IN LISTS unresolved)
|
||||
message(" unresolved: ${file}")
|
||||
endforeach()
|
||||
foreach(file IN LISTS conflicting_FILENAMES)
|
||||
message(" conflicting: ${file}")
|
||||
message(" with ${conflicting_${file}}")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# Deploy the Qt libraries.
|
||||
file(INSTALL ${resolved}
|
||||
DESTINATION "${QT_DEPLOY_PREFIX}/${arg_LIB_DIR}"
|
||||
FOLLOW_SYMLINK_CHAIN
|
||||
)
|
||||
|
||||
# Deploy the Qt plugins.
|
||||
foreach(file_path IN LISTS __QT_DEPLOY_PLUGINS)
|
||||
file(RELATIVE_PATH destination
|
||||
"${__QT_DEPLOY_QT_INSTALL_PREFIX}/${__QT_DEPLOY_QT_INSTALL_PLUGINS}"
|
||||
"${file_path}"
|
||||
)
|
||||
get_filename_component(destination "${destination}" DIRECTORY)
|
||||
string(PREPEND destination "${QT_DEPLOY_PREFIX}/${arg_PLUGINS_DIR}/")
|
||||
file(INSTALL ${file_path} DESTINATION ${destination})
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# This function is currently in Technical Preview.
|
||||
# Its signature and behavior might change.
|
||||
function(qt6_deploy_runtime_dependencies)
|
||||
@ -202,6 +304,8 @@ function(qt6_deploy_runtime_dependencies)
|
||||
list(APPEND tool_options --verbose 2)
|
||||
elseif(__QT_DEPLOY_SYSTEM_NAME STREQUAL Darwin)
|
||||
list(APPEND tool_options -verbose=3)
|
||||
else()
|
||||
list(APPEND tool_options VERBOSE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@ -228,10 +332,28 @@ function(qt6_deploy_runtime_dependencies)
|
||||
# for debugging purposes. It may be removed at any time without warning.
|
||||
list(APPEND tool_options ${__qt_deploy_tool_extra_options})
|
||||
|
||||
if(__QT_DEPLOY_TOOL STREQUAL "GRD")
|
||||
message(STATUS "Running generic Qt deploy tool on ${arg_EXECUTABLE}")
|
||||
|
||||
# Forward the ADDITIONAL_* arguments.
|
||||
foreach(file_type EXECUTABLES LIBRARIES MODULES)
|
||||
if("${arg_ADDITIONAL_${file_type}}" STREQUAL "")
|
||||
continue()
|
||||
endif()
|
||||
list(APPEND tool_options ADDITIONAL_${file_type} ${arg_ADDITIONAL_${file_type}})
|
||||
endforeach()
|
||||
|
||||
_qt_internal_generic_deployqt(
|
||||
EXECUTABLE "${arg_EXECUTABLE}"
|
||||
LIB_DIR "${arg_LIB_DIR}"
|
||||
PLUGINS_DIR "${arg_PLUGINS_DIR}"
|
||||
${tool_options}
|
||||
)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Both windeployqt and macdeployqt don't differentiate between the different
|
||||
# types of binaries, so we merge the lists and treat them all the same.
|
||||
# A purely CMake-based implementation would need to treat them differently
|
||||
# because of how file(GET_RUNTIME_DEPENDENCIES) works.
|
||||
set(additional_binaries
|
||||
${arg_ADDITIONAL_EXECUTABLES}
|
||||
${arg_ADDITIONAL_LIBRARIES}
|
||||
|
@ -2437,6 +2437,8 @@ function(_qt_internal_setup_deploy_support)
|
||||
set(safe_target_file
|
||||
"$<TARGET_FILE:$<IF:${have_deploy_tool},${target_if_exists},${target}>>")
|
||||
set(__QT_DEPLOY_TOOL "$<IF:${have_deploy_tool},${safe_target_file},${fallback}>")
|
||||
elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT CMAKE_CROSSCOMPILING)
|
||||
set(__QT_DEPLOY_TOOL "GRD")
|
||||
else()
|
||||
# Android is handled as a build target, not via this install-based approach.
|
||||
# Therefore, we don't consider androiddeployqt here.
|
||||
@ -2480,6 +2482,10 @@ set(__QT_DEPLOY_GENERATOR_IS_MULTI_CONFIG \"${is_multi_config}\")
|
||||
set(__QT_DEPLOY_ACTIVE_CONFIG \"$<CONFIG>\")
|
||||
set(__QT_NO_CREATE_VERSIONLESS_FUNCTIONS \"${QT_NO_CREATE_VERSIONLESS_FUNCTIONS}\")
|
||||
set(__QT_DEFAULT_MAJOR_VERSION \"${QT_DEFAULT_MAJOR_VERSION}\")
|
||||
set(__QT_DEPLOY_QT_ADDITIONAL_PACKAGES_PREFIX_PATH \"${QT_ADDITIONAL_PACKAGES_PREFIX_PATH}\")
|
||||
set(__QT_DEPLOY_QT_INSTALL_PREFIX \"${QT6_INSTALL_PREFIX}\")
|
||||
set(__QT_DEPLOY_QT_INSTALL_PLUGINS \"${QT6_INSTALL_PLUGINS}\")
|
||||
set(__QT_DEPLOY_PLUGINS \"\")
|
||||
|
||||
# Define the CMake commands to be made available during deployment.
|
||||
set(__qt_deploy_support_files
|
||||
@ -2593,6 +2599,21 @@ function(qt6_generate_deploy_script)
|
||||
message(FATAL_ERROR "CONTENT must be specified")
|
||||
endif()
|
||||
|
||||
# Check whether manual finalization is needed.
|
||||
if(CMAKE_VERSION VERSION_LESS "3.19")
|
||||
get_target_property(is_immediately_finalized ${arg_TARGET} _qt_is_immediately_finalized)
|
||||
if(is_immediately_finalized)
|
||||
message(WARNING
|
||||
"Deployment of plugins for target '${arg_TARGET}' will not work. "
|
||||
"Either, upgrade CMake to version 3.19 or newer, or call "
|
||||
"qt_finalize_target(${arg_TARGET}) after generating the deployment script."
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Mark the target as "to be deployed".
|
||||
set_property(TARGET ${arg_TARGET} PROPERTY _qt_marked_for_deployment ON)
|
||||
|
||||
# Create a file name that will be unique for this target and the combination
|
||||
# of arguments passed to this command. This allows the project to call us
|
||||
# multiple times with different arguments for the same target (e.g. to
|
||||
@ -2610,12 +2631,15 @@ function(qt6_generate_deploy_script)
|
||||
set(file_name "${deploy_impl_dir}/deploy_${target_id}_${short_hash}")
|
||||
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
|
||||
if(is_multi_config)
|
||||
string(APPEND file_name "-$<CONFIG>")
|
||||
set(config_infix "-$<CONFIG>")
|
||||
else()
|
||||
set(config_infix "")
|
||||
endif()
|
||||
string(APPEND file_name ".cmake")
|
||||
string(APPEND file_name "${config_infix}.cmake")
|
||||
set(${arg_FILENAME_VARIABLE} "${file_name}" PARENT_SCOPE)
|
||||
|
||||
set(boiler_plate "include(${QT_DEPLOY_SUPPORT})
|
||||
include(\"\${CMAKE_CURRENT_LIST_DIR}/${arg_TARGET}-plugins${config_infix}.cmake\" OPTIONAL)
|
||||
")
|
||||
list(TRANSFORM arg_CONTENT REPLACE "\\$" "\$")
|
||||
file(GENERATE OUTPUT ${file_name} CONTENT "${boiler_plate}${arg_CONTENT}")
|
||||
@ -2694,7 +2718,17 @@ qt6_deploy_runtime_dependencies(
|
||||
qt6_deploy_runtime_dependencies(
|
||||
EXECUTABLE $<TARGET_FILE:${arg_TARGET}>
|
||||
GENERATE_QT_CONF
|
||||
)")
|
||||
)
|
||||
")
|
||||
|
||||
elseif(UNIX AND NOT APPLE AND NOT ANDROID AND QT6_IS_SHARED_LIBS_BUILD)
|
||||
qt6_generate_deploy_script(${generate_args}
|
||||
CONTENT "
|
||||
qt6_deploy_runtime_dependencies(
|
||||
EXECUTABLE $<TARGET_FILE:${arg_TARGET}>
|
||||
GENERATE_QT_CONF
|
||||
)
|
||||
")
|
||||
|
||||
elseif(NOT arg_NO_UNSUPPORTED_PLATFORM_ERROR AND NOT QT_INTERNAL_NO_UNSUPPORTED_PLATFORM_ERROR)
|
||||
# Currently we don't deploy runtime dependencies if cross-compiling or using a static Qt.
|
||||
|
@ -48,8 +48,12 @@ which should come after the application's target has been installed using
|
||||
|
||||
The deployment script will call \l{qt_deploy_runtime_dependencies()} with a
|
||||
suitable set of options for the standard install layout.
|
||||
Currently, this is only implemented for macOS app bundles built on a macOS
|
||||
host and Windows executables built on a Windows host.
|
||||
Currently, this is only implemented for
|
||||
\list
|
||||
\li macOS app bundles built on a macOS host,
|
||||
\li Linux executables built on a Linux host,
|
||||
\li and Windows executables built on a Windows host.
|
||||
\endlist
|
||||
Cross-building a Windows executable on a Linux host, as well as similar
|
||||
scenarios, are not currently supported.
|
||||
Calling \c{qt_generate_deploy_app_script()} in such a case will result
|
||||
|
@ -328,7 +328,8 @@ set(deploy_args
|
||||
# other platforms, because there is no support for runtime dependency deployment
|
||||
# on those platforms.
|
||||
# With static builds the runtime dependencies are just skipped, but the test should still pass.
|
||||
if((WIN32 OR (APPLE AND NOT IOS)))
|
||||
if(WIN32 OR (APPLE AND NOT IOS)
|
||||
OR (UNIX AND NOT APPLE AND NOT ANDROID AND NOT CMAKE_CROSSCOMPILING))
|
||||
_qt_internal_test_expect_pass(${deploy_args})
|
||||
else()
|
||||
_qt_internal_test_expect_fail(${deploy_args})
|
||||
|
@ -12,7 +12,12 @@ qt6_standard_project_setup()
|
||||
function(create_test_executable target)
|
||||
cmake_parse_arguments(arg "" "" "" ${ARGN})
|
||||
|
||||
qt_add_executable(${target} main.cpp)
|
||||
if(CMAKE_VERSION VERSION_LESS "3.19")
|
||||
qt_add_executable(${target} MANUAL_FINALIZATION main.cpp)
|
||||
else()
|
||||
qt_add_executable(${target} main.cpp)
|
||||
endif()
|
||||
|
||||
set_target_properties(${target} PROPERTIES
|
||||
# We explicitly don't set WIN32_EXECUTABLE to ensure we see errors from stderr when
|
||||
# something fails and not having to use DebugView.
|
||||
@ -34,10 +39,16 @@ function(create_test_executable target)
|
||||
)
|
||||
install(SCRIPT ${deploy_script})
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS "3.19")
|
||||
qt_finalize_target(${target})
|
||||
endif()
|
||||
|
||||
if(APPLE AND NOT IOS)
|
||||
set(installed_app_location "${CMAKE_INSTALL_PREFIX}/${target}.app/Contents/MacOS/${target}")
|
||||
elseif(WIN32)
|
||||
set(installed_app_location "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/${target}.exe")
|
||||
elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT CMAKE_CROSSCOMPILING)
|
||||
set(installed_app_location "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/${target}")
|
||||
endif()
|
||||
|
||||
# There's no nice way to get the location of an installed binary, so we need to construct
|
||||
|
Loading…
x
Reference in New Issue
Block a user