KGC_TEST/KGCAPP/3rdparty/qwindowkit/qmsetup/cmake/modules/Deploy.cmake

403 lines
12 KiB
CMake

#[[
Warning: This module depends on `qmcorecmd` after installation.
]] #
if(NOT QMSETUP_CORECMD_EXECUTABLE)
message(FATAL_ERROR "QMSETUP_CORECMD_EXECUTABLE not defined. Add find_package(qmsetup) to CMake first.")
endif()
if(NOT DEFINED QMSETUP_APPLOCAL_DEPS_PATHS)
set(QMSETUP_APPLOCAL_DEPS_PATHS)
endif()
if(NOT DEFINED QMSETUP_APPLOCAL_DEPS_PATHS_DEBUG)
set(QMSETUP_APPLOCAL_DEPS_PATHS_DEBUG ${QMSETUP_APPLOCAL_DEPS_PATHS})
endif()
if(NOT DEFINED QMSETUP_APPLOCAL_DEPS_PATHS_RELEASE)
set(QMSETUP_APPLOCAL_DEPS_PATHS_RELEASE ${QMSETUP_APPLOCAL_DEPS_PATHS_RELEASE})
endif()
if(NOT DEFINED QMSETUP_APPLOCAL_DEPS_PATHS_RELWITHDEBINFO)
set(QMSETUP_APPLOCAL_DEPS_PATHS_RELWITHDEBINFO ${QMSETUP_APPLOCAL_DEPS_PATHS})
endif()
if(NOT DEFINED QMSETUP_APPLOCAL_DEPS_PATHS_MINSIZEREL)
set(QMSETUP_APPLOCAL_DEPS_PATHS_MINSIZEREL ${QMSETUP_APPLOCAL_DEPS_PATHS_RELEASE})
endif()
include_guard(DIRECTORY)
#[[
Record searching paths for Windows Executables, must be called before calling `qm_win_applocal_deps`
or `qm_deploy_directory` if your project supports Windows.
qm_win_record_deps(<target>)
]] #
function(qm_win_record_deps _target)
if(NOT WIN32)
return()
endif()
set(_paths)
get_target_property(_link_libraries ${_target} LINK_LIBRARIES)
foreach(_item IN LISTS _link_libraries)
if(NOT TARGET ${_item})
continue()
endif()
get_target_property(_imported ${_item} IMPORTED)
if(_imported)
get_target_property(_path ${_item} LOCATION)
if(NOT _path OR NOT ${_path} MATCHES "\\.dll$")
continue()
endif()
set(_path "$<TARGET_PROPERTY:${_item},LOCATION_$<CONFIG>>")
else()
get_target_property(_type ${_item} TYPE)
if(NOT ${_type} MATCHES "SHARED_LIBRARY")
continue()
endif()
set(_path "$<TARGET_FILE:${_item}>")
endif()
list(APPEND _paths ${_path})
endforeach()
if(NOT _paths)
return()
endif()
set(_deps_file "${CMAKE_CURRENT_BINARY_DIR}/${_target}_deps_$<CONFIG>.txt")
file(GENERATE OUTPUT ${_deps_file} CONTENT "$<JOIN:${_paths},\n>")
set_target_properties(${_target} PROPERTIES QMSETUP_DEPENDENCIES_FILE ${_deps_file})
endfunction()
#[[
Automatically copy dependencies for Windows Executables after build.
qm_win_applocal_deps(<target>
[CUSTOM_TARGET <target>]
[FORCE] [VERBOSE]
[EXTRA_SEARCHING_PATHS <path...>]
[EXTRA_TARGETS <target...>]
[OUTPUT_DIR <dir>]
[EXCLUDE <pattern...>]
)
]] #
function(qm_win_applocal_deps _target)
if(NOT WIN32)
return()
endif()
set(options FORCE VERBOSE)
set(oneValueArgs TARGET CUSTOM_TARGET OUTPUT_DIR)
set(multiValueArgs EXTRA_SEARCHING_PATHS EXTRA_TARGETS EXCLUDE)
cmake_parse_arguments(FUNC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
# Get output directory and deploy target
set(_out_dir)
set(_deploy_target)
if(FUNC_CUSTOM_TARGET)
set(_deploy_target ${FUNC_CUSTOM_TARGET})
if(NOT TARGET ${_deploy_target})
add_custom_target(${_deploy_target})
endif()
else()
set(_deploy_target ${_target})
endif()
if(FUNC_OUTPUT_DIR)
set(_out_dir ${FUNC_OUTPUT_DIR})
else()
set(_out_dir "$<TARGET_FILE_DIR:${_target}>")
endif()
if(NOT _out_dir)
message(FATAL_ERROR "qm_win_applocal_deps: cannot determine output directory.")
endif()
# Get dep files
set(_dep_files)
_qm_win_get_all_dep_files(_dep_files ${_target})
foreach(_item IN LISTS FUNC_EXTRA_TARGETS)
_qm_win_get_all_dep_files(_dep_files ${_item})
endforeach()
# Prepare command
set(_args)
if(FUNC_FORCE)
list(APPEND _args -f)
endif()
if(FUNC_VERBOSE)
list(APPEND _args -V)
endif()
# Add extra searching paths
foreach(_item IN LISTS FUNC_EXTRA_SEARCHING_PATHS)
list(APPEND _args "-L${_item}")
endforeach()
# Add global extra searching paths
if(CMAKE_BUILD_TYPE)
string(TOUPPER ${CMAKE_BUILD_TYPE} _build_type_upper)
if(QMSETUP_APPLOCAL_DEPS_PATHS_${_build_type_upper})
foreach(_item IN LISTS QMSETUP_APPLOCAL_DEPS_PATHS_${_build_type_upper})
get_filename_component(_item ${_item} ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})
list(APPEND _args "-L${_item}")
endforeach()
elseif(QMSETUP_APPLOCAL_DEPS_PATHS)
foreach(_item IN LISTS QMSETUP_APPLOCAL_DEPS_PATHS)
get_filename_component(_item ${_item} ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})
list(APPEND _args "-L${_item}")
endforeach()
endif()
else()
foreach(_item IN LISTS QMSETUP_APPLOCAL_DEPS_PATHS)
get_filename_component(_item ${_item} ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})
list(APPEND _args "-L${_item}")
endforeach()
endif()
foreach(_item IN LISTS _dep_files)
list(APPEND _args "-@${_item}")
endforeach()
foreach(_item IN LISTS FUNC_EXCLUDE)
list(APPEND _args -e ${_item})
endforeach()
list(APPEND _args "$<TARGET_FILE:${_target}>")
add_custom_command(TARGET ${_deploy_target} POST_BUILD
COMMAND ${QMSETUP_CORECMD_EXECUTABLE} deploy ${_args}
WORKING_DIRECTORY ${_out_dir}
VERBATIM
)
endfunction()
#[[
Add deploy command when install project, not available in debug mode.
qm_deploy_directory(<install_dir>
[FORCE] [STANDARD] [VERBOSE]
[LIBRARY_DIR <dir>]
[EXTRA_PLUGIN_PATHS <path>...]
[EXTRA_SEARCHING_PATHS <path>...]
[PLUGINS <plugin>...]
[PLUGIN_DIR <dir>]
[QML <qml>...]
[QML_DIR <dir>]
[WIN_TARGETS <target>...]
[COMMENT <comment>]
)
PLUGINS: Qt plugins, in format of `<category>/<name>`
PLUGIN_DIR: Qt plugins destination
EXTRA_PLUGIN_PATHS: Extra Qt plugins searching paths
QML: Qt qml directories
QML_DIR: Qt qml destination
LIBRARY_DIR: Extra library destination
EXTRA_SEARCHING_PATHS: Extra library searching paths
]] #
function(qm_deploy_directory _install_dir)
set(options FORCE STANDARD VERBOSE)
set(oneValueArgs LIBRARY_DIR PLUGIN_DIR QML_DIR COMMENT)
set(multiValueArgs EXTRA_PLUGIN_PATHS PLUGINS QML WIN_TARGETS EXTRA_SEARCHING_PATHS)
cmake_parse_arguments(FUNC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
# Get qmake
if((FUNC_PLUGINS OR FUNC_QML) AND NOT DEFINED QT_QMAKE_EXECUTABLE)
if(TARGET Qt${QT_VERSION_MAJOR}::qmake)
get_target_property(QT_QMAKE_EXECUTABLE Qt${QT_VERSION_MAJOR}::qmake IMPORTED_LOCATION)
elseif((FUNC_PLUGINS AND NOT FUNC_EXTRA_PLUGIN_PATHS) OR FUNC_QML)
message(FATAL_ERROR "qm_deploy_directory: qmake not defined. Add find_package(Qt5 COMPONENTS Core) to CMake to enable.")
endif()
endif()
# Set values
qm_set_value(_lib_dir FUNC_LIBRARY_DIR "${_install_dir}/${QMSETUP_SHARED_LIBRARY_CATEGORY}")
qm_set_value(_plugin_dir FUNC_PLUGIN_DIR "${_install_dir}/plugins")
qm_set_value(_qml_dir FUNC_QML_DIR "${_install_dir}/qml")
get_filename_component(_lib_dir ${_lib_dir} ABSOLUTE BASE_DIR ${_install_dir})
get_filename_component(_plugin_dir ${_plugin_dir} ABSOLUTE BASE_DIR ${_install_dir})
# Prepare commands
set(_args
-i "${_install_dir}"
-m "${QMSETUP_CORECMD_EXECUTABLE}"
--plugindir "${_plugin_dir}"
--libdir "${_lib_dir}"
--qmldir "${_qml_dir}"
)
if(QT_QMAKE_EXECUTABLE)
list(APPEND _args --qmake "${QT_QMAKE_EXECUTABLE}")
endif()
# Add Qt plugins
foreach(_item IN LISTS FUNC_PLUGINS)
list(APPEND _args --plugin "${_item}")
endforeach()
# Add QML modules
foreach(_item IN LISTS FUNC_QML)
list(APPEND _args --qml "${_item}")
endforeach()
# Add extra plugin paths
foreach(_item IN LISTS FUNC_EXTRA_PLUGIN_PATHS)
list(APPEND _args --extra "${_item}")
endforeach()
# Add extra searching paths
foreach(_item IN LISTS FUNC_EXTRA_SEARCHING_PATHS)
list(APPEND _args -L "${_item}")
endforeach()
# Add global extra searching paths
if(CMAKE_BUILD_TYPE)
string(TOUPPER ${CMAKE_BUILD_TYPE} _build_type_upper)
if(QMSETUP_APPLOCAL_DEPS_PATHS_${_build_type_upper})
foreach(_item IN LISTS QMSETUP_APPLOCAL_DEPS_PATHS_${_build_type_upper})
get_filename_component(_item ${_item} ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})
list(APPEND _args -L "${_item}")
endforeach()
elseif(QMSETUP_APPLOCAL_DEPS_PATHS)
foreach(_item IN LISTS QMSETUP_APPLOCAL_DEPS_PATHS)
get_filename_component(_item ${_item} ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})
list(APPEND _args -L "${_item}")
endforeach()
endif()
else()
foreach(_item IN LISTS QMSETUP_APPLOCAL_DEPS_PATHS)
get_filename_component(_item ${_item} ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})
list(APPEND _args -L "${_item}")
endforeach()
endif()
if(WIN32)
set(_dep_files)
if(FUNC_WIN_TARGETS)
_qm_win_get_all_dep_files(_dep_files ${FUNC_WIN_TARGETS})
endif()
foreach(_item IN LISTS _dep_files)
list(APPEND _args -@ "${_item}")
endforeach()
set(_script_quoted "cmd /c \"${QMSETUP_MODULES_DIR}/scripts/windeps.bat\"")
else()
set(_script_quoted "bash \"${QMSETUP_MODULES_DIR}/scripts/unixdeps.sh\"")
endif()
# Add options
if(FUNC_FORCE)
list(APPEND _args "-f")
endif()
if(FUNC_STANDARD)
list(APPEND _args "-s")
endif()
if(FUNC_VERBOSE)
list(APPEND _args "-V")
endif()
set(_args_quoted)
foreach(_item IN LISTS _args)
set(_args_quoted "${_args_quoted}\"${_item}\" ")
endforeach()
set(_comment_code)
if(FUNC_COMMENT)
set(_comment_code "message(STATUS \"${FUNC_COMMENT}\")")
endif()
# Add install command
install(CODE "
${_comment_code}
execute_process(
COMMAND ${_script_quoted} ${_args_quoted}
WORKING_DIRECTORY \"${_install_dir}\"
COMMAND_ERROR_IS_FATAL ANY
)
")
endfunction()
# ----------------------------------
# Private functions
# ----------------------------------
function(_qm_win_get_all_dep_files _out)
# Get searching paths
macro(get_recursive_dynamic_dependencies _current_target _result)
get_target_property(_deps ${_current_target} LINK_LIBRARIES)
if(_deps)
foreach(_dep IN LISTS _deps)
if(NOT TARGET ${_dep})
continue()
endif()
get_target_property(_type ${_dep} TYPE)
if(_type STREQUAL "SHARED_LIBRARY")
list(APPEND ${_result} ${_dep})
endif()
get_recursive_dynamic_dependencies(${_dep} ${_result})
endforeach()
endif()
endmacro()
set(_visited_targets ${ARGN})
foreach(_target ${ARGN})
set(_all_deps)
get_recursive_dynamic_dependencies(${_target} _all_deps)
foreach(_cur_dep IN LISTS _all_deps)
if(${_cur_dep} IN_LIST _visited_targets)
continue()
endif()
list(APPEND _visited_targets ${_cur_dep})
endforeach()
endforeach()
set(_dep_files)
foreach(_target IN LISTS _visited_targets)
# Add file
get_target_property(_file ${_target} QMSETUP_DEPENDENCIES_FILE)
if(NOT _file)
continue()
endif()
list(APPEND _dep_files ${_file})
endforeach()
set(${_out} ${_dep_files} PARENT_SCOPE)
endfunction()