commit 23fbf002410537c706ae6a36374593ac1f4d2b6a Author: Ivan Pelipenko Date: Tue Aug 25 21:25:35 2020 +0300 Initial commit diff --git a/DeployMacros.cmake b/DeployMacros.cmake new file mode 100644 index 0000000..854ffb7 --- /dev/null +++ b/DeployMacros.cmake @@ -0,0 +1,1076 @@ +#[[ + +Important! You should include this file +in your top-level CMakeLists.txt + + + + +set_version( [MAJOR ] [MINOR ] [REVISION ] [SUFFIX ] [BUILD ] [OUTPUT ]) + +Set target version, optionally creates file + +Create variable _VERSION with full version name + +If OUTPUT then generate header with +version macros - _VERSION_ +Also create macro _VERSION_NAME with full string version and +macro _MAKE_VERSION(major, minor, revision) that returns +byte-packed integer version. +Attention: macro _VERSION is byte-packed integer version! + + + + +set_lang( [ [...] ]) + +Set target translations, e.g. "ru" "fr" + + + + +import_version( ) + +Copy all version components and languages from + + + + +import_deploy_properties( ) + +Copy all deploy properties from + + + + +set_deploy_property( [SHARED | STATIC] NAME [NAME [...] ]) + +Set target deploy property, where NAME one of: + * LABEL - application icon name + * FULLNAME - package name in format "*.*.*" + * COMPANY - company name + * ICON - icon file path + * INFO - additional info + +Specify SHARED or STATIC if your target is library +You can setup several properties in one command + + + + +make_rc( ) + +Generate Windows *.rc file from deploy properties +and return file path to +On other platforms this variable set to empty + +You should set version and deploy properties +before call this macro, see +"set_version()" and "set_deploy_property()" + + + + +deploy_target( [DEPLOY_DIR ] + [DESTINATION ] + [RESOURCES [ ...] ] + [PLUGINS [ ...] ] + [FILES [ ...] ] + [LIBS [ ...] ] + [OPTIONS ...] + [VERBOSE] + [DMG_NO_ZIP] + [DEB_USR_DIR] [DEB_ADD_SERVICE]) + +Create make target "deploy_", depends on target "deploy". +On this target create release package, containing all dependencies: + * .zip on Windows + * .deb on Linux + * .dmg[.zip] on MacOS + * .apk/.aab on Android +If not defined DMG_NO_ZIP then *.dmg.zip will be created on MacOS. + +You should set version and deploy properties +before call this macro, see +"set_version()" and "set_deploy_property()". + +Example: +deploy_target(my_app DESTINATION packages) + + +DEPLOY_DIR - dir where you install + * executable on Windows, Linux + * .app directory with executable on MacOS + +DESTINATION - dir where macro place package + +RESOURCES, PLUGINS and FILES - list of directories and files, copied to: + +| | Windows | Linux | Linux (DEB_USR_DIR) | MacOS | +|-----------|---------|-------------------------|---------------------------|---------------------| +| RESOURCES | root | /opt/COMPANY/target | /usr/share/COMPANY/target | Contents/Resources | +| PLUGINS | root | /opt/COMPANY/target | /usr/lib/COMPANY/target | Contents/PlugIns | +| FILES | root | /opt/COMPANY/target | /usr/bin | Contents/MacOS | +| LIBS | root | /opt/COMPANY/target/lib | /usr/lib | Contents/Frameworks | + +Relative paths are taken from DEPLOY_DIR +Also check library dependencies from PLUGINS and FILES +Important! RESOURCES, PLUGINS, FILES and LIBS lists check +at cmake-time, so if entry ends with "/" it treat +as directory, else - file + + +This macro using "deploy_tool" from PIP, +so make sure it can be executed from shell +OPTIONS allow you to pass custom flags to "deploy_tool" +You can see flags by launch "deploy_tool" without arguments + +Using CMAKE_LDD, CMAKE_OTOOL or CMAKE_OBJDUMP variable, +depends on target platform + +DEPLOY_ADD_LIBPATH variable used as additional +library search path + +If DEB_ADD_SERVICE then -service.deb package will be created. +This package use contents of CMAKE_CURRENT_SOURCE_DIR/debian-service directory: + * CMAKE_CURRENT_SOURCE_DIR/debian-service/DEBIAN/ + * CMAKE_CURRENT_SOURCE_DIR/debian-service/*.service +.service file placed in /opt/COMPANY/target, you should copy it to system with script +You can use "postinst,postrm,preinst,prerm,config" files to configure service + +]] + + +cmake_policy(SET CMP0011 NEW) # don`t affect includer policies +if (POLICY CMP0057) + cmake_policy(SET CMP0057 NEW) # Support if() IN_LIST +endif() +if (POLICY CMP0053) + cmake_policy(SET CMP0053 NEW) +endif() +set(__prop_names "LABEL;FULLNAME;COMPANY;ICON;INFO") +list(APPEND __prop_names "ANDROID_TARGET_SDK;ANDROID_STORE_FILE;ANDROID_STORE_PASSWORD;ANDROID_KEY_PASSWORD;ANDROID_KEY_ALIAS;ANDROID_NEW_LOADER") +set(__version_names "MAJOR;MINOR;REVISION;BUILD;SUFFIX") +include(TargetArch) +if (NOT MY_ARCH) + target_architecture(MY_ARCH) +endif() +if (NOT _dep_exists) + set(_dep_exists 1) + add_custom_target(deploy COMMENT "Deploy") +endif() +set(_modules_dir "${CMAKE_ROOT}/Modules") +if (LIBPROJECT) + set(_modules_dir ${PIP_CMAKE_MODULE_PATH}) +endif() +set(_dt_delim "::") + + +macro(set_version _T) + set(_VERSION_ 2) # macro version + set(_name) + set(_is_name 1) + set(_is_out 0) + set(_out) + #message("set_version \"${_T}\"") + foreach(_i ${ARGN}) + if (_is_out) + set(_is_out 0) + set(_out "${_i}") + elseif ("x${_i}" STREQUAL "xOUTPUT") + set(_is_out 1) + elseif(_is_name) + #message("set_version component \"${_i}\"") + set(_is_name 0) + if (_i IN_LIST __version_names) + else() + message(FATAL_ERROR "Invalid version component \"${_i}\"!") + endif() + set(_name ${_i}) + set(${_T}_VERSION_${_name}) + else() + #message("set_version value \"${_name}\" = \"${_i}\"") + set(_is_name 1) + set(${_T}_VERSION_${_name} ${_i}) + endif() + endforeach() + set(${_T}_VERSION_FULLSUFFIX "${${_T}_VERSION_SUFFIX}") + if (NOT ("x${${_T}_VERSION_FULLSUFFIX}" STREQUAL "x")) + if(NOT ("${${_T}_VERSION_FULLSUFFIX}" MATCHES "_.*")) + set(${_T}_VERSION_FULLSUFFIX "_${${_T}_VERSION_FULLSUFFIX}") + endif() + endif() + if ("x${${_T}_VERSION_MAJOR}" STREQUAL "x") + set(${_T}_VERSION_MAJOR "0") + endif() + if ("x${${_T}_VERSION_MINOR}" STREQUAL "x") + set(${_T}_VERSION_MINOR "0") + endif() + if ("x${${_T}_VERSION_REVISION}" STREQUAL "x") + set(${_T}_VERSION_REVISION "0") + endif() + if ("x${${_T}_VERSION_BUILD}" STREQUAL "x") + set(${_T}_VERSION_BUILD "0") + endif() + set(${_T}_VERSION "${${_T}_VERSION_MAJOR}.${${_T}_VERSION_MINOR}.${${_T}_VERSION_REVISION}${${_T}_VERSION_FULLSUFFIX}") + set(_${_T}_VERSION_WB "${${_T}_VERSION}-${${_T}_VERSION_BUILD}") + if (_out) + set(_${_T}_VERSION_CHANGED 0) + if ((NOT _${_T}_CACHED_VERSION) OR (NOT ("x${_${_T}_CACHED_VERSION}" STREQUAL "x${_${_T}_VERSION_WB}"))) + set(_${_T}_CACHED_VERSION "${_${_T}_VERSION_WB}" CACHE STRING "" FORCE) + set(_${_T}_VERSION_CHANGED 1) + endif() + if ((NOT _${_T}_CACHED_VERSION_VER) OR (NOT ("x${_${_T}_CACHED_VERSION_VER}" STREQUAL "x${_VERSION_}"))) + set(_${_T}_CACHED_VERSION_VER "${_VERSION_}" CACHE STRING "" FORCE) + set(_${_T}_VERSION_CHANGED 1) + endif() + if ((NOT EXISTS "${_out}") OR _${_T}_VERSION_CHANGED) + get_filename_component(_def "${_out}" NAME) + string(MAKE_C_IDENTIFIER "${_T}_${_def}" _def) + string(TOUPPER "${_def}" _def) + string(TOUPPER "${_T}" _TN) + string(TIMESTAMP _cur_date "%d.%m.%Y %H:%M") + file(WRITE "${_out}" +"// This file generated by CMake set_version() version ${_VERSION_} + +#ifndef ${_def} +#define ${_def} + + +// Project + +#define ${_TN}_VERSION_MAJOR ${${_T}_VERSION_MAJOR} +#define ${_TN}_VERSION_MINOR ${${_T}_VERSION_MINOR} +#define ${_TN}_VERSION_REVISION ${${_T}_VERSION_REVISION} +#define ${_TN}_VERSION_BUILD ${${_T}_VERSION_BUILD} +#define ${_TN}_VERSION_SUFFIX \"${${_T}_VERSION_SUFFIX}\" +#define ${_TN}_VERSION_NAME \"${${_T}_VERSION}\" +#define ${_TN}_MAKE_VERSION(major, minor, revision) ((major << 16) | (minor << 8) | revision) +#define ${_TN}_VERSION ${_TN}_MAKE_VERSION(${_TN}_VERSION_MAJOR, ${_TN}_VERSION_MINOR, ${_TN}_VERSION_REVISION) + + +// Tools + +#define ${_TN}_CMAKE_VERSION \"${CMAKE_VERSION}\" +#define ${_TN}_CXX_COMPILER \"${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}\" +#define ${_TN}_BUILD_DATE \"${_cur_date}\" +#define ${_TN}_ARCH \"${MY_ARCH}\" + + +#endif // ${_def} +") + endif() + endif() +endmacro() + + +macro(set_lang _T) + set(${_T}_LANG) + foreach(_i ${ARGN}) + list(APPEND ${_T}_LANG "${_i}") + endforeach() +endmacro() + + +macro(import_version _T _F) + set(_names "${__version_names};FULLSUFFIX") + foreach(_i ${_names}) + set(${_T}_VERSION_${_i} "${${_F}_VERSION_${_i}}") + endforeach() + set(${_T}_VERSION "${${_F}_VERSION}") + set(${_T}_LANG "${${_F}_LANG}") +endmacro() + + +macro(import_deploy_properties _T _F) + foreach(_i ${__prop_names}) + set(${_T}_${_i} "${${_F}_${_i}}") + endforeach() +endmacro() + + +macro(set_deploy_property _T) + set(_name) + set(_is_name 1) + foreach(_i ${ARGN}) + if (("x${_i}" STREQUAL "xSHARED") OR ("x${_i}" STREQUAL "xSTATIC")) + set(${_T}_TYPE "${_i}") + elseif(_is_name) + set(_is_name 0) + if (_i IN_LIST __prop_names) + else() + message(FATAL_ERROR "Invalid property name \"${_i}\"!") + endif() + set(_name ${_i}) + else() + set(_is_name 1) + set(${_T}_${_name} ${_i}) + endif() + endforeach() +endmacro() + + +macro(make_rc _T _out) + if (WIN32) + if ("x${${_T}_VERSION_MAJOR}" STREQUAL "x") + message(FATAL_ERROR "Version for \"${_T}\" not set, use set_version()!") + endif() + string(REPLACE "\"" "\"\"" WINDOWS_RC_FULLNAME "${${_T}_FULLNAME}") + string(REPLACE "\"" "\"\"" WINDOWS_RC_VERSION "${${_T}_VERSION}" ) + string(REPLACE "\"" "\"\"" WINDOWS_RC_LABEL "${${_T}_LABEL}" ) + string(REPLACE "\"" "\"\"" WINDOWS_RC_COMPANY "${${_T}_COMPANY}" ) + string(REPLACE "\"" "\"\"" WINDOWS_RC_INFO "${${_T}_INFO}" ) + if (("x${${_T}_TYPE}" STREQUAL "x") OR ("x${${_T}_TYPE}" STREQUAL "xEXECUTABLE")) + set(WINDOWS_RC_FILETYPE "0x1L") + set(_rc_prefix "") + set(_rc_ext "exe") + elseif ("x${${_T}_TYPE}" STREQUAL "xSHARED") + set(WINDOWS_RC_FILETYPE "0x2L") + set(_rc_prefix "lib") + set(_rc_ext "dll") + elseif ("x${${_T}_TYPE}" STREQUAL "xSTATIC") + set(WINDOWS_RC_FILETYPE "0x7L") + set(_rc_prefix "lib") + set(_rc_ext "a") + endif() + set(_rc_version "${${_T}_VERSION_MAJOR},${${_T}_VERSION_MINOR},${${_T}_VERSION_REVISION},${${_T}_VERSION_BUILD}") + set(_icon) + if (NOT ("x${${_T}_ICON}" STREQUAL "x")) + get_filename_component(WINDOWS_RC_ICON "${${_T}_ICON}" REALPATH BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) + set(_icon "1 ICON \"${WINDOWS_RC_ICON}\"") + endif() + set(_rc_file "${CMAKE_CURRENT_BINARY_DIR}/${_T}_winres.rc") + file(WRITE "${_rc_file}" +"# if defined(UNDER_CE) +# include +# else +# include +# endif +#pragma code_page(65001) +${_icon} +VS_VERSION_INFO VERSIONINFO +FILEVERSION ${_rc_version} +PRODUCTVERSION ${_rc_version} +FILEFLAGSMASK 0x3fL +FILEFLAGS 0x0L +FILEOS 0x40004L +FILETYPE ${WINDOWS_RC_FILETYPE} +FILESUBTYPE 0x0L +BEGIN +BLOCK \"StringFileInfo\" +BEGIN +BLOCK \"041904B0\" +BEGIN +VALUE \"Comments\", \"\\0\" +VALUE \"CompanyName\", \"${WINDOWS_RC_COMPANY}\\0\" +VALUE \"FileDescription\", \"${WINDOWS_RC_INFO}\\0\" +VALUE \"FileVersion\", \"${WINDOWS_RC_VERSION}\\0\" +VALUE \"InternalName\", \"${WINDOWS_RC_FULLNAME}\\0\" +VALUE \"LegalTrademarks\", \"\\0\" +VALUE \"LegalCopyright\", \"${WINDOWS_RC_COMPANY}\\0\" +VALUE \"OriginalFilename\", \"${_rc_prefix}${_T}.${_rc_ext}\\0\" +VALUE \"ProductName\", \"${WINDOWS_RC_LABEL}\\0\" +VALUE \"ProductVersion\", \"${WINDOWS_RC_VERSION}\\0\" +END +END +BLOCK \"VarFileInfo\" +BEGIN +VALUE \"Translation\", 0x0419, 0x04B0, 0x0409, 0x04B0 +END +END +") + set(${_out} ${_rc_file}) + else() + set(${_out}) + endif() +endmacro() + + +# Help macros begin + +macro(__add_file_or_dir _DIR_VAR _FILE_VAR _PATH _RELPATH) + set(_p) + set(_abs 0) + if (IS_ABSOLUTE "${_PATH}") + set(_abs 1) + endif() + if ("${_PATH}" MATCHES "^\$<") + set(_abs 1) + endif() + if (_abs) + set(_p "${_PATH}") + else() + set(_p "${_RELPATH}/${_PATH}") + endif() + if ("${_p}" MATCHES ".*/$") + string(LENGTH "${_p}" __sl) + math(EXPR __sl ${__sl}-1) + string(SUBSTRING "${_p}" 0 ${__sl} _p) + list(APPEND ${_DIR_VAR} "${_p}") + else() + list(APPEND ${_FILE_VAR} "${_p}") + endif() +endmacro() + +set(__win_host 0) +set(__mac_host 0) +if ("x${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "xWindows") + set(__win_host 1) +endif() +if ("x${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "xDarwin") + set(__mac_host 1) +endif() + +macro(__make_win_path _in_path _out_var _is_dir _out_dir) + set(_add "") + if (${_is_dir}) + set(_add "/") + endif() + file(TO_NATIVE_PATH "${_in_path}" ${_out_var}) + string(REPLACE "//" "/" ${_out_var} "${${_out_var}}${_add}") + if (NOT "x${_out_dir}" STREQUAL "x") + string(LENGTH "${${_out_var}}" __sl) + math(EXPR __sl ${__sl}-1) + string(SUBSTRING "${${_out_var}}" 0 ${__sl} __substr) + get_filename_component(${_out_dir} "${__substr}" NAME) + #message("dirname src=\"${${_out_var}}\", len=${__sl} \"${__substr}\" = \"${${_out_dir}}\"") + endif() + string(REPLACE "/" "\\" ${_out_var} "${${_out_var}}") +endmacro() + +macro(__make_dir _cmd _dest) + if (__win_host) + __make_win_path("${_dest}" __d 1 "") + set(${_cmd} ${${_cmd}} COMMAND if not exist "\"${__d}\"" mkdir "\"${__d}\"") + else() + set(${_cmd} ${${_cmd}} COMMAND mkdir ${_VERB} -p "${_dest}") + endif() +endmacro() + +macro(__make_copy _cmd _dirs _files _dest) + if (${_dirs} OR ${_files}) + __make_dir(${_cmd} "${_dest}") + endif() + if (__win_host) + __make_win_path("${_dest}" _wdest 1 "") + foreach(_d ${${_dirs}}) + __make_win_path("${_d}" _wsrc 1 _dirname) + __make_dir(${_cmd} "${_dest}/${_dirname}") + set(${_cmd} ${${_cmd}} COMMAND xcopy /y /r /e "${_wsrc}*" "\"${_wdest}${_dirname}\\\"" ${_WVERB}) + endforeach() + foreach(_f ${${_files}}) + __make_win_path("${_f}" _wsrc 0 "") + set(${_cmd} ${${_cmd}} COMMAND xcopy /y /r "\"${_wsrc}\"" "\"${_wdest}\"" ${_WVERB}) + endforeach() + else() + foreach(_d ${${_dirs}}) + set(${_cmd} ${${_cmd}} COMMAND cp ${_VERB} -rf "${_d}" "${_dest}/") + endforeach() + foreach(_f ${${_files}}) + set(${_cmd} ${${_cmd}} COMMAND cp ${_VERB} -f "${_f}" "${_dest}/") + endforeach() + endif() +endmacro() + +macro(__gather_deps _T _search_path_var _dep_libs_var _dep_libs_cs_var _added_) + get_target_property(_LL${_T} ${_T} LINK_LIBRARIES) + foreach (_L${_T} ${_LL${_T}}) + if (TARGET ${_L${_T}}) + get_target_property(_II${_T} ${_L${_T}} IMPORTED) + if (NOT _II${_T}) + #message("depend on ${_L${_T}}") + get_target_property(_LT${_T} ${_L${_T}} TYPE) + if (("x${_LT${_T}}" STREQUAL "xSHARED_LIBRARY") OR ("x${_LT${_T}}" STREQUAL "xSTATIC_LIBRARY")) + if (NOT _L${_T} IN_LIST ${_added_}) + list(APPEND ${_added_} ${_L${_T}}) + __gather_deps(${_L${_T}} ${_search_path_var} ${_dep_libs_var} ${_dep_libs_cs_var} ${_added_}) + if ("x${_LT${_T}}" STREQUAL "xSHARED_LIBRARY") + if (NOT DEFINED ANDROID_PLATFORM) + set(${_search_path_var} "${${_search_path_var}}${_dt_delim}$") + endif() + set(${_dep_libs_cs_var} "${${_dep_libs_cs_var}}${_dt_delim}$/$") + set(${_dep_libs_var} "${${_dep_libs_var}}" "$/$") + endif() + endif() + endif() + endif() + endif() + endforeach() +endmacro() + +set(__macos_privacy_text "Application request permission") +set(__macos_privacies + "NFCReaderUsageDescription + ${__macos_privacy_text} + NSAppleMusicUsageDescription + ${__macos_privacy_text} + NSBluetoothPeripheralUsageDescription + ${__macos_privacy_text} + NSCalendarsUsageDescription + ${__macos_privacy_text} + NSCameraUsageDescription + ${__macos_privacy_text} + NSContactsUsageDescription + ${__macos_privacy_text} + NSFaceIDUsageDescription + ${__macos_privacy_text} + NSHealthShareUsageDescription + ${__macos_privacy_text} + NSHealthUpdateUsageDescription + ${__macos_privacy_text} + NSHomeKitUsageDescription + ${__macos_privacy_text} + NSLocationAlwaysUsageDescription + ${__macos_privacy_text} + NSLocationWhenInUseUsageDescription + ${__macos_privacy_text} + NSMicrophoneUsageDescription + ${__macos_privacy_text} + NSMotionUsageDescription + ${__macos_privacy_text} + NSPhotoLibraryAddUsageDescription + ${__macos_privacy_text} + NSPhotoLibraryUsageDescription + ${__macos_privacy_text} + NSRemindersUsageDescription + ${__macos_privacy_text} + NSVideoSubscriberAccountUsageDescription + ${__macos_privacy_text}" + ) +set(__gradle_lang_start +" defaultConfig { + resConfigs ") +set(__gradle_sign +" signingConfigs { + debug { + storeFile file(DEBUG_STORE_FILE) + } + release { + storeFile file(RELEASE_STORE_FILE) + storePassword RELEASE_STORE_PASSWORD + keyPassword RELEASE_KEY_PASSWORD + keyAlias RELEASE_KEY_ALIAS + } + } + + buildTypes { + debug { + signingConfig signingConfigs.debug + } + release { + signingConfig signingConfigs.release + } + }") + +# Help macros end + + +macro(deploy_target _T) + set(_DESTINATION "${CMAKE_INSTALL_PREFIX}") + set(_DEPLOY_DIR "${CMAKE_INSTALL_PREFIX}") + set(_RES_DIRS) + set(_RES_FILES) + set(_PLUG_DIRS) + set(_PLUG_FILES) + set(_FILE_DIRS) + set(_FILE_FILES) + set(_LIBS_DIRS) + set(_LIBS_FILES) + set(_VERB) + set(_WVERB 1> NUL) + set(_OPTIONS) + set(_ZIP_DMG 1) + set(_DEB_OPT 1) + set(_DEB_SERVICE 0) + set(_cur_arg) + set(__args "DESTINATION;DEPLOY_DIR;RESOURCES;PLUGINS;FILES;LIBS;OPTIONS;VERBOSE;DMG_NO_ZIP;DEB_USR_DIR;DEB_ADD_SERVICE") + foreach(_i ${ARGN}) + if (_i IN_LIST __args) + set(_cur_arg "${_i}") + if ("${_cur_arg}" STREQUAL "VERBOSE") + set(_VERB -v) + set(_WVERB) + elseif("${_cur_arg}" STREQUAL "DMG_NO_ZIP") + set(_ZIP_DMG 0) + elseif("${_cur_arg}" STREQUAL "DEB_USR_DIR") + set(_DEB_OPT 0) + elseif("${_cur_arg}" STREQUAL "DEB_ADD_SERVICE") + set(_DEB_SERVICE 1) + endif() + elseif ("${_cur_arg}" STREQUAL "DESTINATION") + set(_cur_arg) + set(_DESTINATION "${_i}/") + elseif ("${_cur_arg}" STREQUAL "DEPLOY_DIR") + set(_cur_arg) + set(_DEPLOY_DIR "${_i}/") + elseif ("${_cur_arg}" STREQUAL "RESOURCES") + __add_file_or_dir(_RES_DIRS _RES_FILES "${_i}" "${_DEPLOY_DIR}") + elseif ("${_cur_arg}" STREQUAL "PLUGINS") + __add_file_or_dir(_PLUG_DIRS _PLUG_FILES "${_i}" "${_DEPLOY_DIR}") + elseif ("${_cur_arg}" STREQUAL "FILES") + __add_file_or_dir(_FILE_DIRS _FILE_FILES "${_i}" "${_DEPLOY_DIR}") + elseif ("${_cur_arg}" STREQUAL "LIBS") + __add_file_or_dir(_LIBS_DIRS _LIBS_FILES "${_i}" "${_DEPLOY_DIR}") + elseif ("${_cur_arg}" STREQUAL "OPTIONS") + list(APPEND _OPTIONS "${_i}") + endif() + #message("-i = ${_i}") + endforeach() + get_filename_component(_ICON_NAME "${${_T}_ICON}" NAME) + get_filename_component(_ICON_FN "${${_T}_ICON}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + set(_TV "${_T}_${${_T}_VERSION}") + set(_DEP_LIBPATH) + set(_DEP_LIBS_CS) + set(_DEP_LIBS) + set(_add_search_path) + set(_added_) + set(_ADD_DEPS ${_PLUG_DIRS} ${_PLUG_FILES} ${_FILE_DIRS} ${_FILE_FILES} ${_LIBS_DIRS} ${_LIBS_FILES}) + __gather_deps(${_T} _add_search_path _DEP_LIBS _DEP_LIBS_CS _added_) + foreach (_L ${DEPLOY_ADD_LIBPATH}) + set(_add_search_path "${_add_search_path}${_dt_delim}${_L}") + endforeach() + #message("app depend ${_T} libpath ${_add_search_path}") + set(_CMD_) + set(_deployed) + if ("x${CMAKE_SYSTEM_NAME}" STREQUAL "xLinux") + set(_os_id "") + set(_os_ver "") + set(_paths "/usr/lib" "/etc") + if (CMAKE_CROSSCOMPILING) + set(_paths "${CMAKE_PREFIX_PATH}/lib" "${CMAKE_PREFIX_PATH}/../etc") + endif() + find_file(_release_file NAMES os-release lsb-release PATHS ${_paths} NO_DEFAULT_PATH) + if (NOT "x${_release_file}" STREQUAL "x") + file(STRINGS "${_release_file}" _lines) + foreach(_l ${_lines}) + if ("${_l}" MATCHES "VERSION_ID=.*") + string(SUBSTRING "${_l}" 11 -1 _os_ver) + string(REPLACE "\"" "" _os_ver "${_os_ver}") + #message("VERSION_ID ${_os_ver}") + elseif ("${_l}" MATCHES "ID=.*") + string(SUBSTRING "${_l}" 3 -1 _os_id) + string(REPLACE "\"" "" _os_id "${_os_id}") + #message("ID ${_os_id}") + endif() + endforeach() + endif() + set(_build "${${_T}_VERSION_BUILD}") + if (NOT "x${_build}" STREQUAL "x") + set(_build "-${_build}") + endif() + string(TOLOWER "${_os_id}${_os_ver}" _TARGET_OS) + if ("x${_TARGET_OS}" STREQUAL "x") + set(_TARGET_OS "linux") + endif() + string(REPLACE "_" "-" _DEBNAME "${_T}") + set(_DEBVERSION "${${_T}_VERSION_MAJOR}.${${_T}_VERSION_MINOR}.${${_T}_VERSION_REVISION}${_build}${${_T}_VERSION_FULLSUFFIX}+${_TARGET_OS}") + string(REPLACE "_" "-" _DEBVERSION "${_DEBVERSION}") + string(TOLOWER "${_DEBNAME}" _DEBNAME) + set(_DEB_ARCH) + if("_${MY_ARCH}" STREQUAL "_arm64") + set(_DEB_ARCH "arm64") + elseif("_${MY_ARCH}" STREQUAL "_armv7") + set(_DEB_ARCH "armhf") + elseif("_${MY_ARCH}" STREQUAL "_i386") + set(_DEB_ARCH "i386") + elseif("_${MY_ARCH}" STREQUAL "_x86_64") + set(_DEB_ARCH "amd64") + elseif("_${MY_ARCH}" STREQUAL "_ppc") + set(_DEB_ARCH "PowerPC") + elseif("_${MY_ARCH}" STREQUAL "_ppc64") + set(_DEB_ARCH "PPC64") + elseif("_${MY_ARCH}" STREQUAL "_ia64") + set(_DEB_ARCH "ia64") + endif() + set(_DEB "${_TV}_deb_${_DEB_ARCH}") + set(_AGD "${_DEPLOY_DIR}/${_DEB}") + set(_C_echof ">" "${_AGD}/DEBIAN/control") + set(_C_echo ">>" "${_AGD}/DEBIAN/control") + set(_D_echof ">" "${_AGD}/usr/share/applications/${_DEBNAME}.desktop") + set(_D_echo ">>" "${_AGD}/usr/share/applications/${_DEBNAME}.desktop") + set(_bin_path "${_AGD}/usr/bin") + set(_lib_path "${_AGD}/usr/lib") + set(_pli_path "${_AGD}/usr/lib/${${_T}_COMPANY}/${_T}") + set(_res_path "${_AGD}/usr/share/${${_T}_COMPANY}/${_T}") + set(_ico_path "${_AGD}/usr/share/pixmaps") + set(_app_bin_path "/usr/bin") + set(_app_ico_path "/usr/share/pixmaps") + if(_DEB_OPT) + set(_bin_path "${_AGD}/opt/${${_T}_COMPANY}/${_T}") + set(_lib_path "${_AGD}/opt/${${_T}_COMPANY}/${_T}/lib") + set(_pli_path "${_AGD}/opt/${${_T}_COMPANY}/${_T}") + set(_res_path "${_AGD}/opt/${${_T}_COMPANY}/${_T}") + set(_ico_path "${_AGD}/opt/${${_T}_COMPANY}/${_T}/pixmaps") + set(_app_bin_path "/opt/${${_T}_COMPANY}/${_T}") + set(_app_ico_path "/opt/${${_T}_COMPANY}/${_T}/pixmaps") + endif() + set(_CMD_ ${_CMD_} COMMAND mkdir ${_VERB} -p "${_bin_path}") + set(_CMD_ ${_CMD_} COMMAND mkdir ${_VERB} -p "${_lib_path}") + set(_CMD_ ${_CMD_} COMMAND mkdir ${_VERB} -p "${_pli_path}") + set(_CMD_ ${_CMD_} COMMAND mkdir ${_VERB} -p "${_res_path}") + set(_CMD_ ${_CMD_} COMMAND mkdir ${_VERB} -p "${_ico_path}") + set(_CMD_ ${_CMD_} COMMAND mkdir ${_VERB} -p "${_AGD}/usr/share/applications") + __make_copy(_CMD_ _FILE_DIRS _FILE_FILES ${_bin_path}) + __make_copy(_CMD_ _PLUG_DIRS _PLUG_FILES ${_pli_path}) + __make_copy(_CMD_ _RES_DIRS _RES_FILES ${_res_path}) + __make_copy(_CMD_ _LIBS_DIRS _LIBS_FILES ${_lib_path}) + set(_CMD_ ${_CMD_} COMMAND cp ${_VERB} -f "${_DEPLOY_DIR}/${_T}" "${_bin_path}/") + if (_DEP_LIBS) + set(_CMD_ ${_CMD_} COMMAND cp ${_VERB} -f "${_DEP_LIBS}" "${_lib_path}/") + endif() + if (_ICON_NAME) + set(_CMD_ ${_CMD_} COMMAND cp ${_VERB} -f "${_ICON_FN}" "${_ico_path}/") + endif() + if(_DEB_OPT) + set(_CMD_ ${_CMD_} COMMAND mkdir ${_VERB} -p "${_AGD}/usr/bin") + set(_CMD_ ${_CMD_} COMMAND ln -srf ${_VERB} "${_bin_path}/${_T}" "${_AGD}/usr/bin/${_T}") + endif() + + file(GLOB _files "${CMAKE_CURRENT_SOURCE_DIR}/debian/DEBIAN/*") + foreach (_f ${_files}) + set(_CMD_ ${_CMD_} COMMAND cp ${_VERB} -f "${_f}" "${_AGD}/DEBIAN/") + endforeach() + + file(GLOB _files "${_AGD}/DEBIAN/p*inst" "${_AGD}/DEBIAN/p*rm" "${_AGD}/DEBIAN/config") + foreach (_f ${_files}) + set(_CMD_ ${_CMD_} COMMAND chmod 0755 ${_VERB} "${_f}") + endforeach() + + if (NOT CMAKE_LDD) + find_program(CMAKE_LDD ldd) + endif() + set(_dt_opts -l "${CMAKE_LDD}") + if (CMAKE_CROSSCOMPILING) + set(_dt_searchdirs "${CMAKE_PREFIX_PATH}/lib") + if (NOT "x${CMAKE_LIBRARY_ARCHITECTURE}" STREQUAL "x") + set(_dt_searchdirs "${_dt_searchdirs}${_dt_delim}${CMAKE_PREFIX_PATH}/lib/${CMAKE_LIBRARY_ARCHITECTURE}") + set(_dt_searchdirs "${_dt_searchdirs}${_dt_delim}${CMAKE_PREFIX_PATH}/../lib/${CMAKE_LIBRARY_ARCHITECTURE}") + endif() + set(_dt_opts -L "${CMAKE_READELF}" --dpkg-workdir "${CMAKE_DPKG_WORKDIR}" -s "${_dt_searchdirs}") + endif() + set(_deb_name "${_TV}_${_TARGET_OS}_${_DEB_ARCH}.deb") + #message("VER = \"${_DEBVERSION}\"") + #message("DEB = \"${_deb_name}\"") + list(APPEND _CMD_ COMMAND echo "Package: ${_DEBNAME}" ${_C_echof}) + list(APPEND _CMD_ COMMAND echo "Version: ${_DEBVERSION}" ${_C_echo}) + list(APPEND _CMD_ COMMAND echo "Architecture: ${_DEB_ARCH}" ${_C_echo}) + list(APPEND _CMD_ COMMAND echo "Maintainer: ${${_T}_COMPANY} <>" ${_C_echo}) + list(APPEND _CMD_ COMMAND ${PIP_DEPLOY_TOOL} ${_OPTIONS} --prefix "Depends: " --dependencies ${_dt_opts} -a "${_DEP_LIBS_CS}" -o "${_lib_path}" ${_DEPLOY_DIR}/${_T} ${_ADD_DEPS} ${_C_echo}) + list(APPEND _CMD_ COMMAND echo "Conflicts:" ${_C_echo}) + list(APPEND _CMD_ COMMAND echo "Replaces:" ${_C_echo}) + list(APPEND _CMD_ COMMAND echo "Section: misc" ${_C_echo}) + list(APPEND _CMD_ COMMAND echo "Priority: optional" ${_C_echo}) + list(APPEND _CMD_ COMMAND echo "Description: ${${_T}_INFO}" ${_C_echo}) + + list(APPEND _CMD_ COMMAND echo "[Desktop Entry]" ${_D_echof}) + list(APPEND _CMD_ COMMAND echo "Encoding=UTF-8" ${_D_echo}) + list(APPEND _CMD_ COMMAND echo "Type=Application" ${_D_echo}) + list(APPEND _CMD_ COMMAND echo "Name=${${_T}_LABEL}" ${_D_echo}) + list(APPEND _CMD_ COMMAND echo "GenericName=${${_T}_LABEL}" ${_D_echo}) + list(APPEND _CMD_ COMMAND echo "Comment=${${_T}_INFO}" ${_D_echo}) + list(APPEND _CMD_ COMMAND echo "Exec=${_app_bin_path}/${_T}" ${_D_echo}) + list(APPEND _CMD_ COMMAND echo "Icon=${_app_ico_path}/${_ICON_NAME}" ${_D_echo}) + list(APPEND _CMD_ COMMAND echo "Terminal=false" ${_D_echo}) + list(APPEND _CMD_ COMMAND echo "StartupNotify=true" ${_D_echo}) + list(APPEND _CMD_ COMMAND echo "Categories=Utility;" ${_D_echo}) + + add_custom_target(deploy_${_T} + # gather deb dir + COMMAND rm -rf ${_VERB} "${_AGD}" + COMMAND mkdir ${_VERB} -p "${_AGD}/DEBIAN" + ${_CMD_} + + # generate deb + COMMAND cd ${_AGD} "&&" md5deep -rl opt usr ">" DEBIAN/md5sums + COMMAND mkdir ${_VERB} -p ${_DESTINATION} + COMMAND dpkg-deb -Z gzip -b ${_AGD} ${_DESTINATION}/${_deb_name} + VERBATIM + COMMENT "Generating ${_deb_name}" + ) + set(_deployed "deploy_${_T}") + + if (_DEB_SERVICE) + set(_CMD_) + set(_DEB "${_TV}-service_deb_${_DEB_ARCH}") + set(_AGD "${_DEPLOY_DIR}/${_DEB}") + set(_C_echof ">" "${_AGD}/DEBIAN/control") + set(_C_echo ">>" "${_AGD}/DEBIAN/control") + set(_opt_path "${_AGD}/opt/${${_T}_COMPANY}/${_T}") + set(_CMD_ ${_CMD_} COMMAND mkdir ${_VERB} -p "${_opt_path}") + + file(GLOB _files "${CMAKE_CURRENT_SOURCE_DIR}/debian-service/*.service") + foreach (_f ${_files}) + set(_CMD_ ${_CMD_} COMMAND cp ${_VERB} -f "${_f}" "${_opt_path}/") + endforeach() + + set(__deb_dir "${CMAKE_CURRENT_SOURCE_DIR}/debian-service/DEBIAN") + file(GLOB _files "${__deb_dir}/*") + foreach (_f ${_files}) + set(_CMD_ ${_CMD_} COMMAND cp ${_VERB} -f "${_f}" "${_AGD}/DEBIAN/") + endforeach() + + file(GLOB _files RELATIVE "${__deb_dir}" "${__deb_dir}/p*inst" "${__deb_dir}/p*rm" "${__deb_dir}/config") + foreach (_f ${_files}) + set(_CMD_ ${_CMD_} COMMAND chmod 0755 ${_VERB} "${_AGD}/DEBIAN/${_f}") + endforeach() + + set(_deb_name "${_TV}-service_${_TARGET_OS}_${_DEB_ARCH}.deb") + #message("VER = \"${_DEBVERSION}\"") + #message("DEB = \"${_deb_name}\"") + list(APPEND _CMD_ COMMAND echo "Package: ${_DEBNAME}-service" ${_C_echof}) + list(APPEND _CMD_ COMMAND echo "Version: ${_DEBVERSION}" ${_C_echo}) + list(APPEND _CMD_ COMMAND echo "Architecture: ${_DEB_ARCH}" ${_C_echo}) + list(APPEND _CMD_ COMMAND echo "Maintainer: ${${_T}_COMPANY} <>" ${_C_echo}) + list(APPEND _CMD_ COMMAND echo "Depends: ${_DEBNAME} (>= ${_DEBVERSION})" ${_C_echo}) + list(APPEND _CMD_ COMMAND echo "Conflicts:" ${_C_echo}) + list(APPEND _CMD_ COMMAND echo "Replaces:" ${_C_echo}) + list(APPEND _CMD_ COMMAND echo "Section: misc" ${_C_echo}) + list(APPEND _CMD_ COMMAND echo "Priority: optional" ${_C_echo}) + list(APPEND _CMD_ COMMAND echo "Description: ${${_T}_LABEL} service" ${_C_echo}) + + add_custom_target(deploy_${_T}-service + # gather deb dir + COMMAND rm -rf ${_VERB} "${_AGD}" + COMMAND mkdir ${_VERB} -p "${_AGD}/DEBIAN" + ${_CMD_} + + # generate deb + COMMAND mkdir ${_VERB} -p ${_DESTINATION} + COMMAND dpkg-deb -Z gzip -b ${_AGD} ${_DESTINATION}/${_deb_name} + VERBATIM + COMMENT "Generating ${_deb_name}" + ) + list(APPEND _deployed "deploy_${_T}-service") + endif() + + elseif(WIN32) + if (NOT CMAKE_OBJDUMP) + find_program(CMAKE_OBJDUMP objdump) + endif() + set(_AGD "${_DEPLOY_DIR}/${_TV}_win_${MY_ARCH}/") + if (__win_host) + string(REPLACE "/" "\\" CMAKE_OBJDUMP "${CMAKE_OBJDUMP}") + endif() + set(_var_exe "${_DEPLOY_DIR}/${_T}.exe") + set(_var_empty) + __make_dir(_CMD_ "${_AGD}") + __make_dir(_CMD_ "${_DESTINATION}") + __make_copy(_CMD_ _var_empty _var_exe "${_AGD}") + __make_copy(_CMD_ _RES_DIRS _RES_FILES "${_AGD}") + __make_copy(_CMD_ _PLUG_DIRS _PLUG_FILES "${_AGD}") + __make_copy(_CMD_ _FILE_DIRS _FILE_FILES "${_AGD}") + __make_copy(_CMD_ _LIBS_DIRS _LIBS_FILES "${_AGD}") + set(_zip_name "${_TV}_windows_${MY_ARCH}.zip") + add_custom_target(deploy_${_T} + # gather dir + ${_CMD_} + + COMMAND ${PIP_DEPLOY_TOOL} ${_VERB} ${_OPTIONS} -W "\"${CMAKE_OBJDUMP}\"" -P windows,minimal -S windows -q "\"${Qt5_ROOT}\"" -s "\"${CMAKE_PREFIX_PATH}/bin${_dt_delim}${MINGW_BIN}${_add_search_path}\"" -o ${_AGD} -p ${_AGD} "\"${_AGD}${_T}.exe\"" ${_ADD_DEPS} + # zip + COMMAND cd "\"${_DEPLOY_DIR}\"" "&&" zip -q -r "\"${_DESTINATION}/${_zip_name}\"" "\"${_TV}_win_${MY_ARCH}\"" + COMMENT "Generating ${_zip_name}" + ) + set(_deployed "deploy_${_T}") + elseif (APPLE) + set(MACOSX_BUNDLE_GUI_IDENTIFIER "${${_T}_FULLNAME}") + set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${${_T}_VERSION}") + set(MACOSX_BUNDLE_LONG_VERSION_STRING "${${_T}_VERSION}") + set(MACOSX_BUNDLE_ICON_FILE "${_ICON_NAME}") + set(MACOSX_BUNDLE_BUNDLE_NAME "${${_T}_LABEL}") + set(MACOSX_BUNDLE_COPYRIGHT "${${_T}_COMPANY}") + set(MACOSX_BUNDLE_INFO_STRING "${${_T}_INFO}") + set(MACOSX_BUNDLE_BUNDLE_VERSION "6.0") + set(MACOSX_BUNDLE_SIGNATURE "????") + set(MACOSX_BUNDLE_PRIVACIES "${__macos_privacies}") + set_target_properties(${_T} PROPERTIES MACOSX_BUNDLE TRUE) + set_target_properties(${_T} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${_modules_dir}/PIMacOSBundle.plist.in") + set(_AGD "${_DEPLOY_DIR}/${_T}.app") + set(_DMG "${CMAKE_CURRENT_BINARY_DIR}/dmg") + __make_copy(_CMD_ _RES_DIRS _RES_FILES "${_AGD}/Contents/Resources") + __make_copy(_CMD_ _PLUG_DIRS _PLUG_FILES "${_AGD}/Contents/PlugIns") + __make_copy(_CMD_ _FILE_DIRS _FILE_FILES "${_AGD}/Contents/MacOS") + __make_copy(_CMD_ _LIBS_DIRS _LIBS_FILES "${_AGD}/Contents/Frameworks") + if (_ICON_NAME) + set(_CMD_ ${_CMD_} COMMAND cp ${_VERB} -f ${_ICON_FN} ${_AGD}/Contents/Resources) + endif() + if (NOT CMAKE_OTOOL) + set(CMAKE_OTOOL "otool") + endif() + if (NOT CMAKE_PREFIX_PATH) + set(CMAKE_PREFIX_PATH "/usr/local") + endif() + set(_dmg_name "${_TV}_macosx_x64.dmg") + set(_cmd_gen_dmg COMMAND genisoimage -quiet -V "${MACOSX_BUNDLE_BUNDLE_NAME}" -D -R -apple -no-pad -o ${_DESTINATION}/${_dmg_name} ${_DMG}) + if (__mac_host) + set(_cmd_gen_dmg COMMAND hdiutil create ${_DESTINATION}/${_dmg_name} -ov -volname "${MACOSX_BUNDLE_BUNDLE_NAME}" -fs HFS+ -srcfolder ${_DMG}) + endif() + if (_ZIP_DMG) + set(_cmd_gen_dmg ${_cmd_gen_dmg} COMMAND zip -q -r "\"${_DESTINATION}/${_dmg_name}.zip\"" "\"${_DESTINATION}/${_dmg_name}\"") + set(_cmd_gen_dmg ${_cmd_gen_dmg} COMMAND rm "\"${_DESTINATION}/${_dmg_name}\"") + endif() + set(_comment "Generating ${_dmg_name}") + if (_ZIP_DMG) + set(_comment "${_comment}.zip") + endif() + add_custom_target(deploy_${_T} + # gather .app dir + COMMAND mkdir ${_VERB} -p ${_AGD}/Contents/Resources + COMMAND mkdir ${_VERB} -p ${_AGD}/Contents/Frameworks + COMMAND mkdir ${_VERB} -p ${_DESTINATION} + ${_CMD_} + COMMAND ${PIP_DEPLOY_TOOL} ${_VERB} ${_OPTIONS} -M "${CMAKE_OTOOL}" -P cocoa,minimal -S mac -q ${Qt5_ROOT} -s "\"${CMAKE_PREFIX_PATH}/lib${_add_search_path}\"" -o ${_AGD}/Contents/Frameworks -p ${_AGD}/Contents/PlugIns ${_AGD}/Contents/MacOS/${_T} ${_ADD_DEPS} + # prepare dmg dir + COMMAND rm -rf ${_DMG} + COMMAND mkdir ${_VERB} -p ${_DMG} + COMMAND cp -r ${_AGD} ${_DMG} + COMMAND ln ${_VERB} -s /Applications ${_DMG} + # generate dmg + ${_cmd_gen_dmg} + COMMENT "${_comment}" + ) + set(_deployed "deploy_${_T}") + elseif (DEFINED ANDROID_PLATFORM) + set(_res_files) + set(_res_files "${_res_files}\n ") + foreach (_f ${_RES_FILES}) + set(_res_files "${_res_files}\n ${_f}") + endforeach() + set(_res_files "${_res_files}\n ") + foreach (_d ${_RES_DIRS}) + file(GLOB_RECURSE _df "${_d}/*") + #message("FILES ${_d} = ${_df}") + get_filename_component(_dn "${_d}" NAME) + set(_res_files "${_res_files}\n ") + foreach (_f ${_df}) + get_filename_component(_fn "${_f}" NAME) + set(_res_files "${_res_files}\n ${_f}") + endforeach() + set(_res_files "${_res_files}\n ") + endforeach() + set(_res_qrc "${CMAKE_CURRENT_BINARY_DIR}/android_res.qrc") + file(WRITE "${_res_qrc}" "${_res_files}\n") + set(_AT ${_T}_lib) + set(_ATA ${_AT}_${ANDROID_ABI}) + get_target_property(_sources ${_T} SOURCES) + get_target_property(_libs ${_T} LINK_LIBRARIES) + get_target_property(_incs ${_T} INCLUDE_DIRECTORIES) + get_target_property(_defs ${_T} COMPILE_DEFINITIONS) + qt5_add_resources(_res_out "${_res_qrc}") + add_library(${_ATA} SHARED ${_sources} ${_res_out}) + target_link_libraries(${_ATA} ${_libs}) + target_include_directories(${_ATA} PRIVATE ${_incs}) + target_compile_definitions(${_ATA} PRIVATE ${_defs}) + set_target_properties(${_T} PROPERTIES EXCLUDE_FROM_ALL 1) + #message("create new target ${_ATA} ${_sources} ${_libs}") + set(_AGD "${_DEPLOY_DIR}/${_T}.android") + __make_dir(_CMD_ "${_AGD}") + set(_file) + set(_dir "${CMAKE_BINARY_DIR}/android-build/libs" "${CMAKE_CURRENT_SOURCE_DIR}/android/res" "${CMAKE_CURRENT_SOURCE_DIR}/android/src") + __make_copy(_CMD_ _dir _file "${_AGD}") + set(_dir) + set(_file "${Qt5_ROOT}/src/android/templates/res/values/libs.xml") + __make_copy(_CMD_ _dir _file "${_AGD}/res/values") + set(_dir "${Qt5_ROOT}/src/3rdparty/gradle/gradle") + set(_file "${Qt5_ROOT}/src/3rdparty/gradle/gradlew" + "${Qt5_ROOT}/src/3rdparty/gradle/gradlew.bat") + __make_copy(_CMD_ _dir _file "${_AGD}") + #message("bindir = ${CMAKE_CURRENT_SOURCE_DIR}") + set(SDK_ROOT "$ENV{ANDROID_SDK_ROOT}") + if("x${SDK_ROOT}" STREQUAL "x") + set(SDK_ROOT "$ENV{ANDROID_HOME}") + endif() + set(__archs "armeabi-v7a" "arm64-v8a" "x86" "x86_64") + set(QT_ANDROID_ARCHITECTURES) + find_library(_lib_ c++_shared) + foreach (_a ${__archs}) + set(_aname "${_a}") + if ("${_a}" STREQUAL "armeabi-v7a") + set(_aname "arm") + elseif ("${_a}" STREQUAL "arm64-v8a") + set(_aname "arm64") + endif() + set(_exist 0) + if ("${_a}" STREQUAL "${ANDROID_ABI}") + set(_exist 1) + elseif (EXISTS "${CMAKE_BINARY_DIR}/android-build/libs/${_a}") + set(_exist 1) + endif() + if (_exist) + string(REPLACE "${ANDROID_ABI}" "${_a}" _a_prefix "${CMAKE_PREFIX_PATH}") + string(REPLACE "arch-${ANDROID_ARCH_NAME}" "arch-${_aname}" _a_prefix "${_a_prefix}") + list(APPEND QT_ANDROID_ARCHITECTURES " \"${_a}\" : \"${ANDROID_SYSROOT_${_a}}\"") + string(REPLACE "${ANDROID_SYSROOT_${ANDROID_ABI}}" "${ANDROID_SYSROOT_${_a}}" _lib_${_a} "${_lib_}") + #message("search = ${_a_prefix}/lib") + __make_copy(_CMD_ _empty _lib_${_a} "${_AGD}/libs/${_a}") + set(_CMD_ ${_CMD_} COMMAND ${PIP_DEPLOY_TOOL} ${_VERB} ${_OPTIONS} -W "\"${CMAKE_OBJDUMP}\"" -s "${_a_prefix}/lib${_dt_delim}${Qt5_ROOT}/lib${_add_search_path}" -o "\"${_AGD}/libs/${_a}\"" --ignore "\"c${_dt_delim}m${_dt_delim}z${_dt_delim}dl${_dt_delim}log\"" "\"${_AGD}/libs/${_a}/lib${_AT}_${_a}.so\"" ${_ADD_DEPS}) + #message("c++_${_a} -> ${_lib_${_a}}") + endif() + endforeach() + string(REPLACE ";" ",\n" QT_ANDROID_ARCHITECTURES "${QT_ANDROID_ARCHITECTURES}") + set(QT_ANDROID_APPLICATION_BINARY ${_AT}) + set(ANDROID_LABEL "${${_T}_LABEL}") + set(ANDROID_ICON "${${_T}_ICON}") + set(ANDROID_VERSION "${${_T}_VERSION}") + set(ANDROID_BUILD "${${_T}_VERSION_BUILD}") + set(ANDROID_PACKAGE "${${_T}_FULLNAME}") + set(ANDROID_TARGET_SDK "${${_T}_ANDROID_TARGET_SDK}") + set(ANDROID_STORE_FILE "${${_T}_ANDROID_STORE_FILE}") + set(ANDROID_STORE_PASSWORD "${${_T}_ANDROID_STORE_PASSWORD}") + set(ANDROID_KEY_PASSWORD "${${_T}_ANDROID_KEY_PASSWORD}") + set(ANDROID_KEY_ALIAS "${${_T}_ANDROID_KEY_ALIAS}") + if (NOT IS_ABSOLUTE "${ANDROID_STORE_FILE}") + set(ANDROID_STORE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/android/${ANDROID_STORE_FILE}") + endif() + if (${_T}_ANDROID_NEW_LOADER) + set(ANDROID_NEW_LOADER "true") + else() + set(ANDROID_NEW_LOADER "false") + endif() + set(__ANDROID_DEBUG_KEYSTORE__ "${_modules_dir}/android_debug.keystore") + set(QT_DIR ${Qt5_ROOT}) + set(_out_json "${CMAKE_CURRENT_BINARY_DIR}/${_T}_android_deployment_settings.json") + configure_file("${CMAKE_BINARY_DIR}/android_deployment_settings.json.in" "${_out_json}") + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/android/AndroidManifest.xml.in" "${_AGD}/AndroidManifest.xml") + configure_file("${_modules_dir}/gradle.properties.in" "${_AGD}/gradle.properties") + set(_depstr) + foreach (_d ${ANDROID_GRADLE_DEPENDENCIES}) + set(_depstr "${_depstr}\n ${_d}") + endforeach() + set(__gradle_lang) + foreach (_l ${${_T}_LANG}) + if (NOT "x${__gradle_lang}" STREQUAL "x") + set(__gradle_lang "${__gradle_lang}, ") + endif() + set(__gradle_lang "${__gradle_lang}\"${_l}\"") + endforeach() + if ("x${__gradle_lang}" STREQUAL "x") + set(__gradle_lang "\"en\"") + endif() + file(READ "${Qt5_ROOT}/src/android/templates/build.gradle" _file) + string(REPLACE "\ndependencies {" "\ndependencies {${_depstr}" _file "${_file}") + string(REPLACE "\nandroid {" "\nandroid {\n${__gradle_sign}\n${__gradle_lang_start}${__gradle_lang}\n\t}\n" _file "${_file}") + string(REPLACE "['resources']" "['res']" _file "${_file}") + file(WRITE "${_AGD}/build.gradle" "${_file}") + set(_gradle_home) + if (NOT __win_host) + set(_gradle_home "-g" "${CMAKE_BINARY_DIR}") + endif() + set(_CMD_ ${_CMD_} COMMAND "${Qt5_BIN}/androiddeployqt" --aux-mode --android-platform ${ANDROID_PLATFORM} --output "\"${_AGD}\"" --input "\"${_out_json}\"") + set(_CMD_ ${_CMD_} COMMAND "${_AGD}/gradlew" ${_gradle_home} --no-daemon -p "\"${_AGD}\"" assembleDebug) + set(_CMD_ ${_CMD_} COMMAND "${_AGD}/gradlew" ${_gradle_home} --no-daemon -p "\"${_AGD}\"" bundleRelease) + set(_base_name "${_TV}_android_all") + set(_CMD_ ${_CMD_} COMMAND "${CMAKE_COMMAND}" -E copy "${_AGD}/build/outputs/apk/debug/${_T}.android-debug.apk" "${_DESTINATION}/${_base_name}.apk") + if (ANDROID_STORE_FILE) + set(_CMD_ ${_CMD_} COMMAND "${CMAKE_COMMAND}" -E copy "${_AGD}/build/outputs/bundle/release/${_T}.android-release.aab" "${_DESTINATION}/${_base_name}.aab") + endif() + add_custom_target(deploy_${_T} + # gather .app dir + ${_CMD_} + COMMENT "Generating ${_base_name}.apk/aab" + ) + set(_deployed "deploy_${_T}") + endif() + foreach (_d ${_deployed}) + add_dependencies(deploy ${_d}) + endforeach() +endmacro() diff --git a/DownloadGTest.cmake b/DownloadGTest.cmake new file mode 100644 index 0000000..4bf1923 --- /dev/null +++ b/DownloadGTest.cmake @@ -0,0 +1,31 @@ +# Download and unpack googletest at configure time +configure_file(GTestCMakeLists.txt.in googletest-download/CMakeLists.txt) +execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . + RESULT_VARIABLE result + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download ) +if(result) + message(FATAL_ERROR "CMake step for googletest failed: ${result}") +endif() +execute_process(COMMAND ${CMAKE_COMMAND} --build . + RESULT_VARIABLE result + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download ) +if(result) + message(FATAL_ERROR "Build step for googletest failed: ${result}") +endif() + +# Prevent overriding the parent project's compiler/linker +# settings on Windows +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + +# Add googletest directly to our build. This defines +# the gtest and gtest_main targets. +add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src + ${CMAKE_CURRENT_BINARY_DIR}/googletest-build + EXCLUDE_FROM_ALL) + +# The gtest/gtest_main targets carry header search path +# dependencies automatically when using CMake 2.8.11 or +# later. Otherwise we have to add them here ourselves. +if (CMAKE_VERSION VERSION_LESS 2.8.11) + include_directories("${gtest_SOURCE_DIR}/include") +endif() diff --git a/FindMinGW.cmake b/FindMinGW.cmake new file mode 100644 index 0000000..ea0e43a --- /dev/null +++ b/FindMinGW.cmake @@ -0,0 +1,24 @@ +if(${MINGW}) + if(NOT DEFINED MINGW_DIR) + get_filename_component(MINGW_BIN ${CMAKE_CXX_COMPILER} PATH) + get_filename_component(MINGW_DIR ${MINGW_BIN} PATH) + find_path(MINGW_INCLUDE + windows.h + PATHS + ENV INCLUDE + ${MINGW_DIR} + ${MINGW_DIR}/i686-w64-mingw32 + ${MINGW_DIR}/x86_64-w64-mingw32 + PATH_SUFFIXES + include) + #message(STATUS "Find MinGW = ${MINGW_INCLUDE}") + find_library(MINGW_LIB m HINTS ${MINGW_BIN}/../lib ${MINGW_INCLUDE}/../lib) + get_filename_component(MINGW_LIB ${MINGW_LIB} PATH) + if (NOT _MGW_MSG) + set(_MGW_MSG 1 CACHE BOOL "msg_mingw" FORCE) + message(STATUS "Found MinGW binary path = ${MINGW_BIN}") + message(STATUS "Found MinGW include path = ${MINGW_INCLUDE}") + message(STATUS "Found MinGW library path = ${MINGW_LIB}") + endif() + endif() +endif(${MINGW}) diff --git a/PIMacOSBundle.plist.in b/PIMacOSBundle.plist.in new file mode 100644 index 0000000..8ccacf8 --- /dev/null +++ b/PIMacOSBundle.plist.in @@ -0,0 +1,43 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${MACOSX_BUNDLE_EXECUTABLE_NAME} + CFBundleGetInfoString + ${MACOSX_BUNDLE_INFO_STRING} + CFBundleIconFile + ${MACOSX_BUNDLE_ICON_FILE} + CFBundleIdentifier + ${MACOSX_BUNDLE_GUI_IDENTIFIER} + CFBundleInfoDictionaryVersion + ${MACOSX_BUNDLE_BUNDLE_VERSION} + CFBundleLongVersionString + ${MACOSX_BUNDLE_LONG_VERSION_STRING} + CFBundleName + ${MACOSX_BUNDLE_BUNDLE_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + ${MACOSX_BUNDLE_SHORT_VERSION_STRING} + CFBundleSignature + ${MACOSX_BUNDLE_SIGNATURE} + CFBundleVersion + ${MACOSX_BUNDLE_BUNDLE_VERSION} + CSResourcesFileMapped + + NSHumanReadableCopyright + ${MACOSX_BUNDLE_COPYRIGHT} + NSPrincipalClass + NSApplication + NSHighResolutionCapable + True + NSSupportsAutomaticTermination + + NSSupportsSuddenTermination + + ${MACOSX_BUNDLE_PRIVACIES} + + diff --git a/SHSTKMacros.cmake b/SHSTKMacros.cmake new file mode 100644 index 0000000..bdf5a8b --- /dev/null +++ b/SHSTKMacros.cmake @@ -0,0 +1,107 @@ + +macro(sdk_install _DIR IS_APP _TARGET _H_FILES _QM_FILES) + #message("QM=${_QM_FILES}") + if((NOT ${IS_APP}) AND (NOT "${_H_FILES}" STREQUAL "")) + if(LIB) + if(WIN32) + install(FILES ${_H_FILES} DESTINATION ${MINGW_INCLUDE}/${_DIR}) + else() + install(FILES ${_H_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/${_DIR}) + endif() + else() + install(FILES ${_H_FILES} DESTINATION include/${_DIR}) + endif() + endif() + if (NOT "${_TARGET}" STREQUAL "") + if(LIB) + if(WIN32) + if (${IS_APP}) + qt_install(TARGETS ${_TARGET} DESTINATION ${MINGW_BIN}) + qt_install(TARGETS ${_TARGET} DESTINATION QtBin) + else() + qt_install(TARGETS ${_TARGET} ARCHIVE DESTINATION ${MINGW_LIB}) + qt_install(TARGETS ${_TARGET} RUNTIME DESTINATION ${MINGW_BIN}) + qt_install(TARGETS ${_TARGET} RUNTIME DESTINATION QtBin) + endif() + else() + if (${IS_APP}) + qt_install(TARGETS ${_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) + else() + qt_install(TARGETS ${_TARGET} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) + endif() + endif() + if(NOT "x${_QM_FILES}" STREQUAL "x") + qt_install(LANG ${_QM_FILES} DESTINATION QtLang) + endif() + else() + if(${IS_APP}) + qt_install(TARGETS ${_TARGET} DESTINATION bin) + else() + if(WIN32) + qt_install(TARGETS ${_TARGET} RUNTIME DESTINATION bin) + qt_install(TARGETS ${_TARGET} ARCHIVE DESTINATION lib) + else() + qt_install(TARGETS ${_TARGET} DESTINATION lib) + endif() + endif() + if(NOT "x${_QM_FILES}" STREQUAL "x") + qt_install(LANG ${_QM_FILES} DESTINATION lang) + endif() + endif() + endif() +endmacro() + + +macro(copy_to_parent _inc_var) + set(QT_MULTILIB_LIST ${QT_MULTILIB_LIST} PARENT_SCOPE) + set(_qt_libs ${_qt_libs} PARENT_SCOPE) + set(_qt_apps ${_qt_apps} PARENT_SCOPE) + set(_qt_plugs ${_qt_plugs} PARENT_SCOPE) + if (NOT "x${_inc_var}" STREQUAL "x") + set(${_inc_var} ${${_inc_var}} PARENT_SCOPE) + endif() + if (LIB) + set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE) + endif() +endmacro() + + +macro(add_directories_with_include multilib_prefix) + set(DIRS) + file(GLOB _dl "[^.]*") + foreach(_d ${_dl}) + if(IS_DIRECTORY ${_d}) + list(APPEND DIRS ${_d}) + endif() + endforeach() + + set(inc_var ${multilib_prefix}includes) + set(${inc_var}) + foreach(_d ${DIRS}) + get_filename_component(_dname "${_d}" NAME) + list(APPEND QT_MULTILIB_LIST ${multilib_prefix}${_dname}) + list(APPEND ${inc_var} "${_d}") + list(APPEND ${inc_var} "${CMAKE_CURRENT_BINARY_DIR}/${_dname}") + endforeach() + + include_directories(${${inc_var}}) + foreach(_d ${DIRS}) + add_subdirectory(${_d}) + endforeach() + + copy_to_parent(${inc_var}) +endmacro() + + +macro(add_directories multilib_prefix) + include_directories(${${multilib_prefix}includes}) + file(GLOB _dl "[^.]*") + foreach(_d ${_dl}) + if(IS_DIRECTORY ${_d}) + add_subdirectory(${_d}) + endif() + endforeach() + + copy_to_parent(${multilib_prefix}includes) +endmacro() + diff --git a/TargetArch.cmake b/TargetArch.cmake new file mode 100644 index 0000000..2e9136d --- /dev/null +++ b/TargetArch.cmake @@ -0,0 +1,136 @@ +# Based on the Qt 5 processor detection code, so should be very accurate +# https://qt.gitorious.org/qt/qtbase/blobs/master/src/corelib/global/qprocessordetection.h +# Currently handles arm (v5, v6, v7), x86 (32/64), ia64, and ppc (32/64) + +# Regarding POWER/PowerPC, just as is noted in the Qt source, +# "There are many more known variants/revisions that we do not handle/detect." + +set(archdetect_c_code " +#if defined(__aarch64__) + #error cmake_ARCH arm64 +#elif defined(__arm__) || defined(__TARGET_ARCH_ARM) + #if defined(__ARM_ARCH_7__) \\ + || defined(__ARM_ARCH_7A__) \\ + || defined(__ARM_ARCH_7R__) \\ + || defined(__ARM_ARCH_7M__) \\ + || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 7) + #error cmake_ARCH armv7 + #elif defined(__ARM_ARCH_6__) \\ + || defined(__ARM_ARCH_6J__) \\ + || defined(__ARM_ARCH_6T2__) \\ + || defined(__ARM_ARCH_6Z__) \\ + || defined(__ARM_ARCH_6K__) \\ + || defined(__ARM_ARCH_6ZK__) \\ + || defined(__ARM_ARCH_6M__) \\ + || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 6) + #error cmake_ARCH armv6 + #elif defined(__ARM_ARCH_5TEJ__) \\ + || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 5) + #error cmake_ARCH armv5 + #else + #error cmake_ARCH arm + #endif +#elif defined(__i386) || defined(__i386__) || defined(_M_IX86) + #error cmake_ARCH i386 +#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) + #error cmake_ARCH x86_64 +#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64) + #error cmake_ARCH ia64 +#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \\ + || defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \\ + || defined(_M_MPPC) || defined(_M_PPC) + #if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__) + #error cmake_ARCH ppc64 + #else + #error cmake_ARCH ppc + #endif +#endif + +#error cmake_ARCH unknown +") + +# Set ppc_support to TRUE before including this file or ppc and ppc64 +# will be treated as invalid architectures since they are no longer supported by Apple + +function(target_architecture output_var) + if(APPLE AND CMAKE_OSX_ARCHITECTURES) + # On OS X we use CMAKE_OSX_ARCHITECTURES *if* it was set + # First let's normalize the order of the values + + # Note that it's not possible to compile PowerPC applications if you are using + # the OS X SDK version 10.6 or later - you'll need 10.4/10.5 for that, so we + # disable it by default + # See this page for more information: + # http://stackoverflow.com/questions/5333490/how-can-we-restore-ppc-ppc64-as-well-as-full-10-4-10-5-sdk-support-to-xcode-4 + + # Architecture defaults to i386 or ppc on OS X 10.5 and earlier, depending on the CPU type detected at runtime. + # On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise. + + foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES}) + if("${osx_arch}" STREQUAL "ppc" AND ppc_support) + set(osx_arch_ppc TRUE) + elseif("${osx_arch}" STREQUAL "i386") + set(osx_arch_i386 TRUE) + elseif("${osx_arch}" STREQUAL "x86_64") + set(osx_arch_x86_64 TRUE) + elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support) + set(osx_arch_ppc64 TRUE) + else() + message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}") + endif() + endforeach() + + # Now add all the architectures in our normalized order + if(osx_arch_ppc) + list(APPEND ARCH ppc) + endif() + + if(osx_arch_i386) + list(APPEND ARCH i386) + endif() + + if(osx_arch_x86_64) + list(APPEND ARCH x86_64) + endif() + + if(osx_arch_ppc64) + list(APPEND ARCH ppc64) + endif() + else() + file(WRITE "${CMAKE_BINARY_DIR}/arch.c" "${archdetect_c_code}") + + enable_language(C) + + # Detect the architecture in a rather creative way... + # This compiles a small C program which is a series of ifdefs that selects a + # particular #error preprocessor directive whose message string contains the + # target architecture. The program will always fail to compile (both because + # file is not a valid C program, and obviously because of the presence of the + # #error preprocessor directives... but by exploiting the preprocessor in this + # way, we can detect the correct target architecture even when cross-compiling, + # since the program itself never needs to be run (only the compiler/preprocessor) + try_run( + run_result_unused + compile_result_unused + "${CMAKE_BINARY_DIR}" + "${CMAKE_BINARY_DIR}/arch.c" + COMPILE_OUTPUT_VARIABLE ARCH + CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} + ) + + # Parse the architecture name from the compiler output + string(REGEX MATCH "cmake_ARCH ([a-zA-Z0-9_]+)" ARCH "${ARCH}") + + # Get rid of the value marker leaving just the architecture name + string(REPLACE "cmake_ARCH " "" ARCH "${ARCH}") + + # If we are compiling with an unknown architecture this variable should + # already be set to "unknown" but in the case that it's empty (i.e. due + # to a typo in the code), then set it to unknown + if (NOT ARCH) + set(ARCH unknown) + endif() + endif() + + set(${output_var} "${ARCH}" PARENT_SCOPE) +endfunction() diff --git a/android_debug.keystore b/android_debug.keystore new file mode 100644 index 0000000..bd7bac4 Binary files /dev/null and b/android_debug.keystore differ diff --git a/gradle.properties.in b/gradle.properties.in new file mode 100644 index 0000000..55bedf2 --- /dev/null +++ b/gradle.properties.in @@ -0,0 +1,10 @@ +androidBuildToolsVersion= +androidCompileSdkVersion=@ANDROID_TARGET_SDK@ +android.bundle.enableUncompressedNativeLibs=@ANDROID_NEW_LOADER@ +buildDir=build +qt5AndroidDir=@Qt5_ROOT@/src/android/java +DEBUG_STORE_FILE=@__ANDROID_DEBUG_KEYSTORE__@ +RELEASE_STORE_FILE=@ANDROID_STORE_FILE@ +RELEASE_STORE_PASSWORD=@ANDROID_STORE_PASSWORD@ +RELEASE_KEY_PASSWORD=@ANDROID_KEY_PASSWORD@ +RELEASE_KEY_ALIAS=@ANDROID_KEY_ALIAS@