# set_deploy_property( NAME [NAME [...]]) # # Set target deploy property, where NAME one of: # * LABEL - application icon name # * VERSION - version # * FULLNAME - package name in format "*.*.*" # * COMPANY - company name # * ICON - icon file # * INFO - additional info # # You can setup several properties in one command # # # # # deploy_target( [DEPLOY_DIR ] [DESTINATION ] [RESOURCE_DIRS [ ...]]) # # DEPLOY_DIR - dir where you install # * executable on Windows, Linux # * .app directory with executable on MacOS # # DESTINATION - dir where macro place package # # Example: # deploy_target(my_app DESTINATION packages) # # Create make target "deploy" # # This macro use "deploy_tool" from sdk, # make sure it can be executed from shell # You should set deploy properties before # call this macro, see "set_deploy_property()" # # use "CMAKE_OTOOL" or "CMAKE_OBJDUMP" variable, # depends on target platform # can use "DEPLOY_ADD_LIBPATH" variable as additional # library search path # # # # # make_rc( ) # # Generate Windows *.rc file from deploy properties # and return file path to # # You should set deploy properties before # call this macro, see "set_deploy_property()" # # if (POLICY CMP0057) cmake_policy(SET CMP0057 NEW) # Support if() IN_LIST endif() set(__prop_names "LABEL;VERSION;FULLNAME;COMPANY;ICON;INFO") include(TargetArch) if (NOT MY_ARCH) target_architecture(MY_ARCH) endif() macro(set_deploy_property _T) set(_name) set(_is_name 1) foreach(_i ${ARGN}) if (_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) set(WINDOWS_RC_FULLNAME "${${_T}_FULLNAME}") set(WINDOWS_RC_VERSION "${${_T}_VERSION}") set(WINDOWS_RC_LABEL "${${_T}_LABEL}") set(WINDOWS_RC_COMPANY "${${_T}_COMPANY}") set(WINDOWS_RC_INFO "${${_T}_INFO}") get_filename_component(WINDOWS_RC_ICON "${${_T}_ICON}" REALPATH BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(_rc_file "${CMAKE_CURRENT_BINARY_DIR}/winres.rc") file(WRITE ${_rc_file} "# if defined(UNDER_CE) # include # else # include # endif #pragma code_page(65001) 1 ICON \"${WINDOWS_RC_ICON}\" VS_VERSION_INFO VERSIONINFO FILEVERSION 1,0,0,0 PRODUCTVERSION 1,0,0,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L FILETYPE 0x2L 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\", \"${_T}.exe\\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() macro(deploy_target _T) set(_DESTINATION "${CMAKE_INSTALL_PREFIX}") set(_DEPLOY_DIR "${CMAKE_INSTALL_PREFIX}") set(_RES_DIRS) set(_is_dest 0) set(_is_deploy_dir 0) set(_is_res_dirs 0) foreach(_i ${ARGN}) if (_is_dest) set(_is_dest 0) set(_DESTINATION "${_i}/") elseif (_is_deploy_dir) set(_is_deploy_dir 0) set(_DEPLOY_DIR "${_i}/") elseif (_is_res_dirs) if (IS_ABSOLUTE "${_i}") list(APPEND _RES_DIRS "${_i}") else() list(APPEND _RES_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/${_i}") endif() else() if ("x${_i}" STREQUAL "xDESTINATION") set(_is_dest 1) elseif ("x${_i}" STREQUAL "xDEPLOY_DIR") set(_is_deploy_dir 1) elseif ("x${_i}" STREQUAL "xRESOURCE_DIRS") set(_is_res_dirs 1) endif() 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) get_target_property(_LL ${_T} LINK_LIBRARIES) foreach (_L ${_LL}) if (TARGET ${_L}) get_target_property(_II ${_L} IMPORTED) if (NOT _II) #message("depend on ${_L}") get_target_property(_LT ${_L} TYPE) if ("x${_LT}" STREQUAL "xSHARED_LIBRARY") set(_DEP_LIBPATH "${_DEP_LIBPATH};$") set(_DEP_LIBS_CS "${_DEP_LIBS_CS};$/$") set(_DEP_LIBS "${_DEP_LIBS}" "$/$") endif() endif() endif() endforeach() #message("app depend libpath ${_DEP_LIBPATH}") set(_CMD_RES) if ("x${CMAKE_SYSTEM_NAME}" STREQUAL "xLinux") if (NOT CMAKE_LDD) find_program(CMAKE_LDD ldd) endif() string(REPLACE "_" "-" _DEBNAME "${_T}") 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") foreach(_r ${_RES_DIRS}) set(_CMD_RES ${_CMD_RES} COMMAND cp -r "${_r}" "${_AGD}/usr/share/${${_T}_COMPANY}") endforeach() set(_CMD_COPY) if (_DEP_LIBS) set(_CMD_COPY ${_CMD_COPY} COMMAND cp -f ${_DEP_LIBS} ${_AGD}/usr/lib) endif() if (_ICON_NAME) set(_CMD_COPY ${_CMD_COPY} COMMAND cp -f ${_ICON_FN} ${_AGD}/usr/share/pixmaps) endif() add_custom_target(deploy # gather deb dir COMMAND mkdir -p ${_AGD}/DEBIAN COMMAND mkdir -p ${_AGD}/usr/bin COMMAND mkdir -p ${_AGD}/usr/lib COMMAND mkdir -p ${_AGD}/usr/share/${${_T}_COMPANY} COMMAND mkdir -p ${_AGD}/usr/share/pixmaps COMMAND mkdir -p ${_AGD}/usr/share/applications COMMAND cp -f ${_DEPLOY_DIR}/${_T} ${_AGD}/usr/bin ${_CMD_COPY} ${_CMD_RES} COMMAND echo "Package: ${_DEBNAME}" ${_C_echof} COMMAND echo "Version: ${${_T}_VERSION}" ${_C_echo} COMMAND echo "Architecture: ${_DEB_ARCH}" ${_C_echo} COMMAND echo "Maintainer: ${${_T}_COMPANY} <>" ${_C_echo} COMMAND deploy_tool --prefix "Depends: " --dependencies -l ${CMAKE_LDD} ${_DEPLOY_DIR}/${_T} -a "${_DEP_LIBS_CS}" -o "${_AGD}/usr/lib" ${_C_echo} COMMAND echo "Conflicts:" ${_C_echo} COMMAND echo "Replaces:" ${_C_echo} COMMAND echo "Section: misc" ${_C_echo} COMMAND echo "Priority: optional" ${_C_echo} COMMAND echo "Description: ${${_T}_INFO}" ${_C_echo} COMMAND echo "[Desktop Entry]" ${_D_echof} COMMAND echo "Encoding=UTF-8" ${_D_echo} COMMAND echo "Type=Application" ${_D_echo} COMMAND echo "Name=${${_T}_LABEL}" ${_D_echo} COMMAND echo "GenericName=${${_T}_LABEL}" ${_D_echo} COMMAND echo "Comment=${${_T}_INFO}" ${_D_echo} COMMAND echo "Exec=/usr/bin/${_T}" ${_D_echo} COMMAND echo "Icon=/usr/share/pixmaps/${_ICON_NAME}" ${_D_echo} COMMAND echo "Terminal=false" ${_D_echo} COMMAND echo "StartupNotify=true" ${_D_echo} #COMMAND echo "X-KDE-StartupNotify=true" ${_D_echo} COMMAND echo "Categories=Utility;" ${_D_echo} #COMMAND -l "${CMAKE_LDD}" -P xcb -q ${Qt5_ROOT} -s "\"${CMAKE_PREFIX_PATH}/lib;${DEPLOY_ADD_LIBPATH}${_DEP_LIBPATH}\"" -o ${_AGD}/usr/lib -p ${_AGD}/usr/ ${_AGD}/Contents/MacOS/${_T} # generate deb COMMAND cd ${_AGD} "&&" md5deep -rl usr ">" DEBIAN/md5sums COMMAND mkdir -p ${_DESTINATION} COMMAND dpkg-deb -b ${_AGD} ${_DESTINATION}/${_TV}_${_DEB_ARCH}.deb VERBATIM COMMENT "Generating ${_TV}_${_DEB_ARCH}.deb" ) elseif(WIN32) if (NOT CMAKE_OBJDUMP) find_program(CMAKE_OBJDUMP objdump) endif() set(_AGD "${_DEPLOY_DIR}/${_TV}_win_${MY_ARCH}/") set(_SEP "/") set(_COPY "cp" "-rf") set(_COPY_SUFFIX) set(_MKDIR mkdir -p "${_AGD}") set(_MKDIR_P mkdir -p "${_DESTINATION}") if ("x${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "xWindows") set(_SEP "\\") set(_COPY xcopy "/y" "/r") set(_COPY_SUFFIX "1>" "NUL") file(TO_NATIVE_PATH "${_AGD}" _AGD) file(TO_NATIVE_PATH "${_DEPLOY_DIR}/" _DEPLOY_DIR) string(REPLACE "/" "\\" _AGD "${_AGD}") string(REPLACE "/" "\\" _DEPLOY_DIR "${_DEPLOY_DIR}") string(REPLACE "/" "\\" CMAKE_OBJDUMP "${CMAKE_OBJDUMP}") set(_MKDIR if not exist "\"${_AGD}\"" mkdir "\"${_AGD}\"") set(_MKDIR_P if not exist "\"${_DESTINATION}\"" mkdir "\"${_DESTINATION}\"") endif() foreach(_r ${_RES_DIRS}) get_filename_component(_dirname "${_r}" NAME) file(TO_NATIVE_PATH "${_r}/" _wr) if ("x${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "xWindows") set(_CMD_RES ${_CMD_RES} COMMAND if not exist "\"${_AGD}${_dirname}\"" mkdir "\"${_AGD}${_dirname}\"") string(REPLACE "/" "\\" _wr "${_wr}") else() set(_CMD_RES ${_CMD_RES} COMMAND mkdir -p "${_AGD}${_dirname}") endif() set(_CMD_RES ${_CMD_RES} COMMAND ${_COPY} "${_wr}*" "\"${_AGD}${_dirname}${_SEP}\"" ${_COPY_SUFFIX}) endforeach() add_custom_target(deploy # gather dir COMMAND ${_MKDIR} COMMAND ${_MKDIR_P} COMMAND ${_COPY} "\"${_DEPLOY_DIR}${_T}.exe\"" "\"${_AGD}\"" ${_COPY_SUFFIX} #COMMAND ${_COPY} "${_DEPLOY_DIR}lang${_SEP}*" "\"${_AGD}lang${_SEP}\"" ${_COPY_SUFFIX} ${_CMD_RES} COMMAND deploy_tool -W "\"${CMAKE_OBJDUMP}\"" -P windows -S windows -q "\"${Qt5_ROOT}\"" -s "\"${CMAKE_PREFIX_PATH}/bin;${MINGW_BIN};${DEPLOY_ADD_LIBPATH}${_DEP_LIBPATH}\"" -o ${_AGD} -p ${_AGD} "\"${_AGD}${_T}.exe\"" # zip COMMAND cd "\"${_DEPLOY_DIR}\"" "&&" zip -r "\"${_DESTINATION}/${_TV}.zip\"" "\"${_TV}_win_${MY_ARCH}\"" COMMENT "Generating ${_TV}.zip" ) 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_target_properties(${_T} PROPERTIES MACOSX_BUNDLE TRUE) set(_AGD "${_DEPLOY_DIR}/${_T}.app") set(_DMG "${CMAKE_CURRENT_BINARY_DIR}/dmg") set(_CMD_COPY) if (_ICON_NAME) set(_CMD_COPY ${_CMD_COPY} COMMAND cp -f ${_ICON_FN} ${_AGD}/Contents/Resources) endif() foreach(_r ${_RES_DIRS}) set(_CMD_RES ${_CMD_RES} COMMAND cp -r "${_r}" "${_AGD}/Contents/Resources") endforeach() add_custom_target(deploy # gather .app dir COMMAND mkdir -p ${_AGD}/Contents/Resources COMMAND mkdir -p ${_AGD}/Contents/Frameworks COMMAND mkdir -p ${_DESTINATION} ${_CMD_COPY} ${_CMD_RES} #COMMAND cp ${_ICON_FN} ${_AGD}/Contents/Resources #COMMAND cp -r ${_DEPLOY_DIR}/lang ${_AGD}/Contents/Resources COMMAND deploy_tool -M "${CMAKE_OTOOL}" -P cocoa -S mac -q ${Qt5_ROOT} -s "\"${CMAKE_PREFIX_PATH}/lib;${DEPLOY_ADD_LIBPATH}${_DEP_LIBPATH}\"" -o ${_AGD}/Contents/Frameworks -p ${_AGD}/Contents/PlugIns ${_AGD}/Contents/MacOS/${_T} # prepare dmg dir COMMAND rm -rf ${_DMG} COMMAND mkdir -p ${_DMG} COMMAND cp -r ${_AGD} ${_DMG} COMMAND ln --symbolic /Applications ${_DMG} # generate dmg COMMAND genisoimage -quiet -V "${MACOSX_BUNDLE_BUNDLE_NAME}" -D -R -apple -no-pad -o ${_DESTINATION}/${_TV}.dmg ${_DMG} COMMENT "Generating ${_TV}.dmg" ) endif() endmacro()