From 2593091380b2841532afa925e3402c4a1de6396e Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Thu, 9 Nov 2017 00:16:52 +0100 Subject: [PATCH 01/12] Preliminary version of cross-compiled DMG archives Currently they only contain the client and the archives are a lot larger than the current release artifacts. --- CMakeLists.txt | 45 ++++++++++++++++ README.md | 6 +++ cmake/toolchains/darwin.toolchain | 1 + scripts/dmg.py | 90 +++++++++++++++++++++++++++++++ 4 files changed, 142 insertions(+) create mode 100644 scripts/dmg.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 01b2de824..19cde587d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,6 +140,17 @@ else() set(ZLIB_FOUND NO) endif() +if(TARGET_OS AND TARGET_OS STREQUAL "mac") + find_program(DMG dmg) + find_program(HFSPLUS hfsplus) + find_program(NEWFS_HFS newfs_hfs) + if(DMG AND HFSPLUS AND NEWFS_HFS) + set(DMGTOOLS_FOUND ON) + else() + set(DMGTOOLS_FOUND OFF) + endif() +endif() + message(STATUS "******** DDNet ********") message(STATUS "Target OS: ${TARGET_OS} ${TARGET_BITS}bit") message(STATUS "Compiler: ${CMAKE_CXX_COMPILER}") @@ -160,6 +171,9 @@ function(show_dependency_status NAME FOUND PATH) endfunction() show_dependency_status("Curl" ${CURL_FOUND} "${CURL_LIBRARY}") +if(TARGET_OS AND TARGET_OS STREQUAL "mac") + show_dependency_status("Dmg tools" ${DMGTOOLS_FOUND} "") +endif() show_dependency_status("Freetype" ${FREETYPE_FOUND} "${FREETYPE_LIBRARY}") show_dependency_status("GTest" ${GTEST_FOUND} "${GTEST_LIBRARY}") if(MYSQL) @@ -1127,6 +1141,7 @@ if(TARGET_OS AND TARGET_BITS) endif() set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME}) +set(CPACK_ARCHIVE_PORTABLE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME}) set(CPACK_SOURCE_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-src) set(CPACK_SOURCE_FILES CMakeLists.txt @@ -1204,6 +1219,34 @@ foreach(target ${CPACK_TARGETS}) list(APPEND COPY_TARGET_COMMANDS COMMAND cmake -E copy $ ${CPACK_PACKAGE_FILE_NAME}/) endforeach() +if(DMGTOOLS_FOUND) + set(DMG_TMPDIR ${CPACK_PACKAGE_FILE_NAME}_dmg) + set(DMG_MKDIRS + ${TARGET_CLIENT}.app + ${TARGET_CLIENT}.app/Contents + ${TARGET_CLIENT}.app/Contents/Frameworks + ${TARGET_CLIENT}.app/Contents/MacOS + ${TARGET_CLIENT}.app/Contents/Resources + ) + set(DMG_MKDIR_COMMANDS) + foreach(dir ${DMG_MKDIRS}) + list(APPEND DMG_MKDIR_COMMANDS COMMAND cmake -E make_directory ${DMG_TMPDIR}/${dir}) + endforeach() + add_custom_command(OUTPUT ${CPACK_PACKAGE_FILE_NAME}.dmg + ${DMG_MKDIR_COMMANDS} + COMMAND cmake -E copy_directory ${PROJECT_SOURCE_DIR}/data ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Resources/data + COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/other/icons/DDNet.icns ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Resources/ + COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/other/bundle/Info.plist ${PROJECT_SOURCE_DIR}/other/bundle/PkgInfo ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/ + COMMAND cmake -E copy $ ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/ + COMMAND cmake -E copy_directory ${PROJECT_SOURCE_DIR}/ddnet-libs/sdl/mac/lib64/SDL2.framework ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/SDL2.framework + COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/ddnet-libs/freetype/mac/lib64/libfreetype.6.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/ + COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change @rpath/SDL2.framework/Versions/A/SDL2 @executable_path/../Frameworks/SDL2.framework/SDL2 ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/${TARGET_CLIENT} + COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change /usr/local/lib/libfreetype.6.dylib @executable_path/../Frameworks/libfreetype.6.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/${TARGET_CLIENT} + COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/dmg.py create --dmg ${DMG} --hfsplus ${HFSPLUS} --newfs_hfs ${NEWFS_HFS} ${CPACK_PACKAGE_FILE_NAME}.dmg ${CPACK_PACKAGE_FILE_NAME} ${DMG_TMPDIR} + ) + add_custom_target(package_dmg DEPENDS ${CPACK_PACKAGE_FILE_NAME}.dmg) +endif() + foreach(ext zip tar.gz tar.xz) set(TAR_MODE c) set(TAR_EXTRA_ARGS) @@ -1229,6 +1272,8 @@ endforeach() set(PACKAGE_DEFAULT tar_xz) if(TARGET_OS STREQUAL "windows") set(PACKAGE_DEFAULT zip) +elseif(TARGET_OS STREQUAL "mac") + set(PACKAGE_DEFAULT dmg) endif() add_custom_target(package_default DEPENDS package_${PACKAGE_DEFAULT}) diff --git a/README.md b/README.md index fdc61378c..96ca08d11 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,12 @@ Install [osxcross](https://github.com/tpoechtrager/osxcross), then add `-DCMAKE_OSX_SYSROOT=/path/to/osxcross/target/SDK/MacOSX10.11.sdk/` to the **initial** CMake command line. +Install `dmg` and `hfsplus` from +[libdmg-hfsplus](https://github.com/mozilla/libdmg-hfsplus) and `newfs_hfs` +from +[diskdev_cmds](http://pkgs.fedoraproject.org/repo/pkgs/hfsplus-tools/diskdev_cmds-540.1.linux3.tar.gz/0435afc389b919027b69616ad1b05709/diskdev_cmds-540.1.linux3.tar.gz) +to unlock the `package_dmg` target that outputs a macOS disk image. + Importing the official DDNet Database ------------------------------------- diff --git a/cmake/toolchains/darwin.toolchain b/cmake/toolchains/darwin.toolchain index 33e9b0ef0..94ee94074 100644 --- a/cmake/toolchains/darwin.toolchain +++ b/cmake/toolchains/darwin.toolchain @@ -2,6 +2,7 @@ set(CMAKE_SYSTEM_NAME Darwin) set(CMAKE_C_COMPILER o64-clang) set(CMAKE_CXX_COMPILER o64-clang++) +set(CMAKE_INSTALL_NAME_TOOL x86_64-apple-darwin15-install_name_tool) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) diff --git a/scripts/dmg.py b/scripts/dmg.py new file mode 100644 index 000000000..b5ad0ff1d --- /dev/null +++ b/scripts/dmg.py @@ -0,0 +1,90 @@ +from collections import namedtuple +import os +import shlex +import subprocess +import tempfile + +Config = namedtuple('Config', 'dmg hfsplus newfs_hfs verbose') + +def chunks(l, n): + """ + Yield successive n-sized chunks from l. + + From https://stackoverflow.com/a/312464. + """ + for i in range(0, len(l), n): + yield l[i:i + n] + +class Dmg: + def __init__(self, config): + self.config = config + + def _check_call(self, process_args, *args, **kwargs): + if self.config.verbose >= 1: + print("EXECUTING {}".format(" ".join(shlex.quote(x) for x in process_args))) + if not (self.config.verbose >= 2 and "stdout" not in kwargs): + kwargs["stdout"] = subprocess.DEVNULL + subprocess.check_call(process_args, *args, **kwargs) + + def _mkfs_hfs(self, *args): + self._check_call((self.config.newfs_hfs,) + args) + def _hfs(self, *args): + self._check_call((self.config.hfsplus,) + args) + def _dmg(self, *args): + self._check_call((self.config.dmg,) + args) + + def _create_hfs(self, hfs, volume_name, size): + if self.config.verbose >= 1: + print("TRUNCATING {} to {} bytes".format(hfs, size)) + with open(hfs, 'wb') as f: + f.truncate(size) + self._mkfs_hfs('-v', volume_name, hfs) + + def _symlink(self, hfs, target, link_name): + self._hfs(hfs, 'symlink', link_name, target) + + def _add(self, hfs, directory): + self._hfs(hfs, 'addall', directory) + + def _finish(self, hfs, dmg): + self._dmg('build', hfs, dmg) + + def create(self, dmg, volume_name, directory, symlinks): + output_size_kb = int(subprocess.check_output(['du', '--apparent-size', '-sk', directory]).split()[0]) + # TODO: Approximate a useful size (--apparent-size is GNU-specific) + output_size = max(int(round(output_size_kb * 1024 * 2)), 1024**2) + hfs = tempfile.mktemp(prefix=dmg + '.', suffix='.hfs') + self._create_hfs(hfs, volume_name, output_size) + self._add(hfs, directory) + for target, link_name in symlinks: + self._symlink(hfs, target, link_name) + self._finish(hfs, dmg) + if self.config.verbose >= 1: + print("REMOVING {}".format(hfs)) + os.remove(hfs) + +def main(): + import argparse + p = argparse.ArgumentParser(description="Manipulate dmg archives") + + subcommands = p.add_subparsers(help="Subcommand", dest='command', metavar="COMMAND") + subcommands.required = True + + create = subcommands.add_parser("create", help="Create a dmg archive from files or directories") + create.add_argument('-v', '--verbose', action='count', help="Verbose output") + create.add_argument('--dmg', help="Path to the dmg executable (https://github.com/mozilla/libdmg-hfsplus)", required=True) + create.add_argument('--hfsplus', help="Path to the hfsplus executable (https://github.com/mozilla/libdmg-hfsplus)", required=True) + create.add_argument('--newfs_hfs', help="Path to the newfs_hfs executable (http://pkgs.fedoraproject.org/repo/pkgs/hfsplus-tools/diskdev_cmds-540.1.linux3.tar.gz/0435afc389b919027b69616ad1b05709/diskdev_cmds-540.1.linux3.tar.gz)", required=True) + create.add_argument('output', metavar="OUTPUT", help="Filename of the output dmg archive") + create.add_argument('volume_name', metavar="VOLUME_NAME", help="Name of the dmg archive") + create.add_argument('directory', metavar="DIR", help="Directory to create the archive from") + create.add_argument('--symlink', metavar="SYMLINK", nargs=2, action="append", help="Symlink the first argument under the second name") + args = p.parse_args() + + verbose = args.verbose or 0 + symlinks = args.symlink or [] + dmg = Dmg(Config(dmg=args.dmg, hfsplus=args.hfsplus, newfs_hfs=args.newfs_hfs, verbose=verbose)) + dmg.create(volume_name=args.volume_name, directory=args.directory, dmg=args.output, symlinks=symlinks) + +if __name__ == '__main__': + main() From eb6c8ea10181230d8675d471e9bedc617ed4b213 Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Thu, 9 Nov 2017 13:35:59 +0100 Subject: [PATCH 02/12] Allow DMG creation on macOS via hdiutil --- CMakeLists.txt | 50 ++++++++++++++++++++++++++++++++------------------ scripts/dmg.py | 27 ++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 19cde587d..ff0e07f82 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -149,6 +149,8 @@ if(TARGET_OS AND TARGET_OS STREQUAL "mac") else() set(DMGTOOLS_FOUND OFF) endif() + + find_program(HDIUTIL hdiutil) endif() message(STATUS "******** DDNet ********") @@ -176,6 +178,9 @@ if(TARGET_OS AND TARGET_OS STREQUAL "mac") endif() show_dependency_status("Freetype" ${FREETYPE_FOUND} "${FREETYPE_LIBRARY}") show_dependency_status("GTest" ${GTEST_FOUND} "${GTEST_LIBRARY}") +if(TARGET_OS AND TARGET_OS STREQUAL "mac") + show_dependency_status("Hdiutil" ${HDIUTIL} "") +endif() if(MYSQL) show_dependency_status("MySQL" ${MYSQL_FOUND} "${MYSQL_LIBRARY}") endif() @@ -1206,21 +1211,13 @@ else() message(WARNING "Cannot create CPack targets, CMake version too old. Use CMake 3.6 or newer.") endif() -set(COPY_FILE_COMMANDS) -set(COPY_DIR_COMMANDS) -set(COPY_TARGET_COMMANDS) -foreach(file ${CPACK_FILES}) - list(APPEND COPY_FILE_COMMANDS COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/${file} ${CPACK_PACKAGE_FILE_NAME}/) -endforeach() -foreach(dir ${CPACK_DIRS}) - list(APPEND COPY_DIR_COMMAND COMMAND cmake -E copy_directory ${PROJECT_SOURCE_DIR}/${dir} ${CPACK_PACKAGE_FILE_NAME}/${dir}) -endforeach() -foreach(target ${CPACK_TARGETS}) - list(APPEND COPY_TARGET_COMMANDS COMMAND cmake -E copy $ ${CPACK_PACKAGE_FILE_NAME}/) -endforeach() - -if(DMGTOOLS_FOUND) - set(DMG_TMPDIR ${CPACK_PACKAGE_FILE_NAME}_dmg) +if(DMGTOOLS_FOUND OR HDIUTIL) + if(HDIUTIL) + set(DMG_PARAMS --hdiutil ${HDIUTIL}) + elseif(DMGTOOLS_FOUND) + set(DMG_PARAMS --dmgtools ${DMG} ${HFSPLUS} ${NEWFS_HFS}) + endif() + set(DMG_TMPDIR pack_${CPACK_PACKAGE_FILE_NAME}_dmg) set(DMG_MKDIRS ${TARGET_CLIENT}.app ${TARGET_CLIENT}.app/Contents @@ -1233,6 +1230,7 @@ if(DMGTOOLS_FOUND) list(APPEND DMG_MKDIR_COMMANDS COMMAND cmake -E make_directory ${DMG_TMPDIR}/${dir}) endforeach() add_custom_command(OUTPUT ${CPACK_PACKAGE_FILE_NAME}.dmg + COMMAND cmake -E remove_directory ${DMG_TMPDIR} ${DMG_MKDIR_COMMANDS} COMMAND cmake -E copy_directory ${PROJECT_SOURCE_DIR}/data ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Resources/data COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/other/icons/DDNet.icns ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Resources/ @@ -1242,7 +1240,7 @@ if(DMGTOOLS_FOUND) COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/ddnet-libs/freetype/mac/lib64/libfreetype.6.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/ COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change @rpath/SDL2.framework/Versions/A/SDL2 @executable_path/../Frameworks/SDL2.framework/SDL2 ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/${TARGET_CLIENT} COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change /usr/local/lib/libfreetype.6.dylib @executable_path/../Frameworks/libfreetype.6.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/${TARGET_CLIENT} - COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/dmg.py create --dmg ${DMG} --hfsplus ${HFSPLUS} --newfs_hfs ${NEWFS_HFS} ${CPACK_PACKAGE_FILE_NAME}.dmg ${CPACK_PACKAGE_FILE_NAME} ${DMG_TMPDIR} + COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/dmg.py create ${DMG_PARAMS} ${CPACK_PACKAGE_FILE_NAME}.dmg ${CPACK_PACKAGE_FILE_NAME} ${DMG_TMPDIR} ) add_custom_target(package_dmg DEPENDS ${CPACK_PACKAGE_FILE_NAME}.dmg) endif() @@ -1251,6 +1249,22 @@ foreach(ext zip tar.gz tar.xz) set(TAR_MODE c) set(TAR_EXTRA_ARGS) string(REPLACE . _ EXT_SLUG ${ext}) + + set(TMPDIR pack_${CPACK_PACKAGE_FILE_NAME}_${EXT_SLUG}/${CPACK_PACKAGE_FILE_NAME}) + + set(COPY_FILE_COMMANDS) + set(COPY_DIR_COMMANDS) + set(COPY_TARGET_COMMANDS) + foreach(file ${CPACK_FILES}) + list(APPEND COPY_FILE_COMMANDS COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/${file} ${TMPDIR}/) + endforeach() + foreach(dir ${CPACK_DIRS}) + list(APPEND COPY_DIR_COMMANDS COMMAND cmake -E copy_directory ${PROJECT_SOURCE_DIR}/${dir} ${TMPDIR}/${dir}) + endforeach() + foreach(target ${CPACK_TARGETS}) + list(APPEND COPY_TARGET_COMMANDS COMMAND cmake -E copy $ ${TMPDIR}/) + endforeach() + if(ext STREQUAL zip) set(TAR_EXTRA_ARGS --format=zip) elseif(ext STREQUAL tar.gz) @@ -1259,11 +1273,11 @@ foreach(ext zip tar.gz tar.xz) set(TAR_MODE cJ) endif() add_custom_command(OUTPUT ${CPACK_PACKAGE_FILE_NAME}.${ext} - COMMAND cmake -E make_directory ${CPACK_PACKAGE_FILE_NAME} + COMMAND cmake -E make_directory ${TMPDIR} ${COPY_FILE_COMMANDS} ${COPY_DIR_COMMANDS} ${COPY_TARGET_COMMANDS} - COMMAND cmake -E tar ${TAR_MODE} ${CPACK_PACKAGE_FILE_NAME}.${ext} ${TAR_EXTRA_ARGS} -- ${CPACK_PACKAGE_FILE_NAME}/ + COMMAND cmake -E chdir pack_${CPACK_PACKAGE_FILE_NAME}_${EXT_SLUG} cmake -E tar ${TAR_MODE} ../${CPACK_PACKAGE_FILE_NAME}.${ext} ${TAR_EXTRA_ARGS} -- ${CPACK_PACKAGE_FILE_NAME}/ WORKING_DIRECTORY ${PROJECT_BINARY_DIR} ) add_custom_target(package_${EXT_SLUG} DEPENDS ${CPACK_PACKAGE_FILE_NAME}.${ext}) diff --git a/scripts/dmg.py b/scripts/dmg.py index b5ad0ff1d..f8c60cebb 100644 --- a/scripts/dmg.py +++ b/scripts/dmg.py @@ -4,7 +4,8 @@ import shlex import subprocess import tempfile -Config = namedtuple('Config', 'dmg hfsplus newfs_hfs verbose') +ConfigDmgtools = namedtuple('Config', 'dmg hfsplus newfs_hfs verbose') +ConfigHdiutil = namedtuple('Config', 'hdiutil verbose') def chunks(l, n): """ @@ -26,6 +27,7 @@ class Dmg: kwargs["stdout"] = subprocess.DEVNULL subprocess.check_call(process_args, *args, **kwargs) +class Dmgtools(Dmg): def _mkfs_hfs(self, *args): self._check_call((self.config.newfs_hfs,) + args) def _hfs(self, *args): @@ -63,6 +65,15 @@ class Dmg: print("REMOVING {}".format(hfs)) os.remove(hfs) +class Hdiutil(Dmg): + def _hdiutil(self, *args): + self._check_call((self.config.hdiutil,) + args) + + def create(self, dmg, volume_name, directory, symlinks): + if symlinks: + raise NotImplementedError("symlinks are not yet implemented") + self._hdiutil('create', '-volname', volume_name, '-srcdir', directory, dmg) + def main(): import argparse p = argparse.ArgumentParser(description="Manipulate dmg archives") @@ -72,9 +83,9 @@ def main(): create = subcommands.add_parser("create", help="Create a dmg archive from files or directories") create.add_argument('-v', '--verbose', action='count', help="Verbose output") - create.add_argument('--dmg', help="Path to the dmg executable (https://github.com/mozilla/libdmg-hfsplus)", required=True) - create.add_argument('--hfsplus', help="Path to the hfsplus executable (https://github.com/mozilla/libdmg-hfsplus)", required=True) - create.add_argument('--newfs_hfs', help="Path to the newfs_hfs executable (http://pkgs.fedoraproject.org/repo/pkgs/hfsplus-tools/diskdev_cmds-540.1.linux3.tar.gz/0435afc389b919027b69616ad1b05709/diskdev_cmds-540.1.linux3.tar.gz)", required=True) + createx = create.add_mutually_exclusive_group(required=True) + createx.add_argument('--dmgtools', nargs=3, help="Paths to the dmg and hfsplus executable (https://github.com/mozilla/libdmg-hfsplus) and the newfs_hfs executable (http://pkgs.fedoraproject.org/repo/pkgs/hfsplus-tools/diskdev_cmds-540.1.linux3.tar.gz/0435afc389b919027b69616ad1b05709/diskdev_cmds-540.1.linux3.tar.gz)") + createx.add_argument('--hdiutil', help="Path to the hdiutil (only exists for macOS at time of writing)") create.add_argument('output', metavar="OUTPUT", help="Filename of the output dmg archive") create.add_argument('volume_name', metavar="VOLUME_NAME", help="Name of the dmg archive") create.add_argument('directory', metavar="DIR", help="Directory to create the archive from") @@ -83,7 +94,13 @@ def main(): verbose = args.verbose or 0 symlinks = args.symlink or [] - dmg = Dmg(Config(dmg=args.dmg, hfsplus=args.hfsplus, newfs_hfs=args.newfs_hfs, verbose=verbose)) + if args.dmgtools: + dmg, hfsplus, newfs_hfs = args.dmgtools + dmg = Dmgtools(ConfigDmgtools(dmg=dmg, hfsplus=hfsplus, newfs_hfs=newfs_hfs, verbose=verbose)) + elif args.hdiutil: + dmg = Hdiutil(ConfigHdiutil(hdiutil=args.hdiutil, verbose=verbose)) + else: + raise RuntimeError("unreachable") dmg.create(volume_name=args.volume_name, directory=args.directory, dmg=args.output, symlinks=symlinks) if __name__ == '__main__': From c6016b77c57e76d2b547cc5ac9247caa597ac3d3 Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Fri, 10 Nov 2017 08:32:21 +0100 Subject: [PATCH 03/12] Add other/bundle/ directory with Info.plist and PkgInfo --- other/bundle/Info.plist | 24 ++++++++++++++++++++++++ other/bundle/PkgInfo | 1 + 2 files changed, 25 insertions(+) create mode 100644 other/bundle/Info.plist create mode 100644 other/bundle/PkgInfo diff --git a/other/bundle/Info.plist b/other/bundle/Info.plist new file mode 100644 index 000000000..09cab5db1 --- /dev/null +++ b/other/bundle/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + DDNet + CFBundleIconFile + DDNet + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + %s + CFBundleIdentifier + org.DDNetClient.app + NSHighResolutionCapable + + + diff --git a/other/bundle/PkgInfo b/other/bundle/PkgInfo new file mode 100644 index 000000000..6f749b0f3 --- /dev/null +++ b/other/bundle/PkgInfo @@ -0,0 +1 @@ +APPL???? From 2f0b76f17895e08b1a91766bef4032d733c42e04 Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Thu, 16 Nov 2017 00:11:30 +0100 Subject: [PATCH 04/12] dmg.py: Compatibility with Python 3.2 and below --- scripts/dmg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dmg.py b/scripts/dmg.py index f8c60cebb..aed55e911 100644 --- a/scripts/dmg.py +++ b/scripts/dmg.py @@ -24,7 +24,7 @@ class Dmg: if self.config.verbose >= 1: print("EXECUTING {}".format(" ".join(shlex.quote(x) for x in process_args))) if not (self.config.verbose >= 2 and "stdout" not in kwargs): - kwargs["stdout"] = subprocess.DEVNULL + kwargs["stdout"] = open(os.devnull, 'wb') subprocess.check_call(process_args, *args, **kwargs) class Dmgtools(Dmg): From 3620e234db6bc48661b84c0e35314171ad242596 Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Thu, 16 Nov 2017 10:03:11 +0100 Subject: [PATCH 05/12] dmg.py: Add proper size calculation --- scripts/dmg.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/dmg.py b/scripts/dmg.py index aed55e911..8f2d4cfc1 100644 --- a/scripts/dmg.py +++ b/scripts/dmg.py @@ -52,9 +52,8 @@ class Dmgtools(Dmg): self._dmg('build', hfs, dmg) def create(self, dmg, volume_name, directory, symlinks): - output_size_kb = int(subprocess.check_output(['du', '--apparent-size', '-sk', directory]).split()[0]) - # TODO: Approximate a useful size (--apparent-size is GNU-specific) - output_size = max(int(round(output_size_kb * 1024 * 2)), 1024**2) + input_size = sum(os.stat(os.path.join(path, f)).st_size for path, dirs, files in os.walk(directory) for f in files) + output_size = max(input_size * 2, 1024**2) hfs = tempfile.mktemp(prefix=dmg + '.', suffix='.hfs') self._create_hfs(hfs, volume_name, output_size) self._add(hfs, directory) From 194e4cffe70b8f5b0c287a7a8d07b1af139f8e56 Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Thu, 16 Nov 2017 10:28:55 +0100 Subject: [PATCH 06/12] Also package the server into DMGs --- CMakeLists.txt | 21 +++++++++++++++++++-- other/bundle/{ => client}/Info.plist | 0 other/bundle/{ => client}/PkgInfo | 0 other/bundle/server/Info.plist | 20 ++++++++++++++++++++ other/bundle/server/PkgInfo | 1 + 5 files changed, 40 insertions(+), 2 deletions(-) rename other/bundle/{ => client}/Info.plist (100%) rename other/bundle/{ => client}/PkgInfo (100%) create mode 100644 other/bundle/server/Info.plist create mode 100644 other/bundle/server/PkgInfo diff --git a/CMakeLists.txt b/CMakeLists.txt index ff0e07f82..054624fe0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1224,6 +1224,12 @@ if(DMGTOOLS_FOUND OR HDIUTIL) ${TARGET_CLIENT}.app/Contents/Frameworks ${TARGET_CLIENT}.app/Contents/MacOS ${TARGET_CLIENT}.app/Contents/Resources + ${TARGET_SERVER}.app + ${TARGET_SERVER}.app/Contents + ${TARGET_SERVER}.app/Contents/MacOS + ${TARGET_SERVER}.app/Contents/Resources + ${TARGET_SERVER}.app/Contents/Resources/data + ${TARGET_SERVER}.app/Contents/Resources/data/mapres ) set(DMG_MKDIR_COMMANDS) foreach(dir ${DMG_MKDIRS}) @@ -1232,14 +1238,24 @@ if(DMGTOOLS_FOUND OR HDIUTIL) add_custom_command(OUTPUT ${CPACK_PACKAGE_FILE_NAME}.dmg COMMAND cmake -E remove_directory ${DMG_TMPDIR} ${DMG_MKDIR_COMMANDS} + + # CLIENT COMMAND cmake -E copy_directory ${PROJECT_SOURCE_DIR}/data ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Resources/data - COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/other/icons/DDNet.icns ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Resources/ - COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/other/bundle/Info.plist ${PROJECT_SOURCE_DIR}/other/bundle/PkgInfo ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/ + COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/other/icons/${TARGET_CLIENT}.icns ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Resources/ + COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/other/bundle/client/Info.plist ${PROJECT_SOURCE_DIR}/other/bundle/client/PkgInfo ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/ COMMAND cmake -E copy $ ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/ COMMAND cmake -E copy_directory ${PROJECT_SOURCE_DIR}/ddnet-libs/sdl/mac/lib64/SDL2.framework ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/SDL2.framework COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/ddnet-libs/freetype/mac/lib64/libfreetype.6.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/ COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change @rpath/SDL2.framework/Versions/A/SDL2 @executable_path/../Frameworks/SDL2.framework/SDL2 ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/${TARGET_CLIENT} COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change /usr/local/lib/libfreetype.6.dylib @executable_path/../Frameworks/libfreetype.6.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/${TARGET_CLIENT} + + # SERVER + COMMAND cmake -E copy_directory ${PROJECT_SOURCE_DIR}/data/maps ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/Resources/data/maps + COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/other/icons/${TARGET_SERVER}.icns ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/Resources/ + COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/other/bundle/server/Info.plist ${PROJECT_SOURCE_DIR}/other/bundle/server/PkgInfo ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/ + COMMAND cmake -E copy $ ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/ + + # DMG COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/dmg.py create ${DMG_PARAMS} ${CPACK_PACKAGE_FILE_NAME}.dmg ${CPACK_PACKAGE_FILE_NAME} ${DMG_TMPDIR} ) add_custom_target(package_dmg DEPENDS ${CPACK_PACKAGE_FILE_NAME}.dmg) @@ -1273,6 +1289,7 @@ foreach(ext zip tar.gz tar.xz) set(TAR_MODE cJ) endif() add_custom_command(OUTPUT ${CPACK_PACKAGE_FILE_NAME}.${ext} + COMMAND cmake -E remove_directory ${TMPDIR} COMMAND cmake -E make_directory ${TMPDIR} ${COPY_FILE_COMMANDS} ${COPY_DIR_COMMANDS} diff --git a/other/bundle/Info.plist b/other/bundle/client/Info.plist similarity index 100% rename from other/bundle/Info.plist rename to other/bundle/client/Info.plist diff --git a/other/bundle/PkgInfo b/other/bundle/client/PkgInfo similarity index 100% rename from other/bundle/PkgInfo rename to other/bundle/client/PkgInfo diff --git a/other/bundle/server/Info.plist b/other/bundle/server/Info.plist new file mode 100644 index 000000000..79ccd31a4 --- /dev/null +++ b/other/bundle/server/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + DDNet_server + CFBundleIconFile + DDNet-Server + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + %s + + diff --git a/other/bundle/server/PkgInfo b/other/bundle/server/PkgInfo new file mode 100644 index 000000000..6f749b0f3 --- /dev/null +++ b/other/bundle/server/PkgInfo @@ -0,0 +1 @@ +APPL???? From dd5c26f81c2e8fee9979e7499c23d0193063e103 Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Fri, 17 Nov 2017 14:37:29 +0100 Subject: [PATCH 07/12] Build the server launcher on macOS, package it --- CMakeLists.txt | 15 ++++- other/bundle/server/Info.plist | 2 +- src/osxlaunch/server.m | 113 +-------------------------------- src/osxlaunch/server.mm | 112 ++++++++++++++++++++++++++++++++ 4 files changed, 127 insertions(+), 115 deletions(-) mode change 100644 => 120000 src/osxlaunch/server.m create mode 100644 src/osxlaunch/server.mm diff --git a/CMakeLists.txt b/CMakeLists.txt index 054624fe0..bf9f1da44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -936,6 +936,15 @@ target_link_libraries(${TARGET_SERVER} ${LIBS_SERVER}) list(APPEND TARGETS_OWN ${TARGET_SERVER}) list(APPEND TARGETS_LINK ${TARGET_SERVER}) +if(TARGET_OS AND TARGET_OS STREQUAL "mac") + set(SERVER_LAUNCHER_SRC src/osxlaunch/server.mm) + set(TARGET_SERVER_LAUNCHER ${TARGET_SERVER}-Launcher) + add_executable(${TARGET_SERVER_LAUNCHER} ${SERVER_LAUNCHER_SRC}) + target_link_libraries(${TARGET_SERVER_LAUNCHER} ${COCOA}) + list(APPEND TARGETS_OWN ${TARGET_SERVER_LAUNCHER}) + list(APPEND TARGETS_LINK ${TARGET_SERVER_LAUNCHER}) +endif() + ######################################################################## # VARIOUS TARGETS ######################################################################## @@ -1253,10 +1262,12 @@ if(DMGTOOLS_FOUND OR HDIUTIL) COMMAND cmake -E copy_directory ${PROJECT_SOURCE_DIR}/data/maps ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/Resources/data/maps COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/other/icons/${TARGET_SERVER}.icns ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/Resources/ COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/other/bundle/server/Info.plist ${PROJECT_SOURCE_DIR}/other/bundle/server/PkgInfo ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/ - COMMAND cmake -E copy $ ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/ + COMMAND cmake -E copy $ $ ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/MacOS/ # DMG COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/dmg.py create ${DMG_PARAMS} ${CPACK_PACKAGE_FILE_NAME}.dmg ${CPACK_PACKAGE_FILE_NAME} ${DMG_TMPDIR} + + DEPENDS ${TARGET_CLIENT} ${TARGET_SERVER} ${TARGET_SERVER_LAUNCHER} ) add_custom_target(package_dmg DEPENDS ${CPACK_PACKAGE_FILE_NAME}.dmg) endif() @@ -1295,7 +1306,7 @@ foreach(ext zip tar.gz tar.xz) ${COPY_DIR_COMMANDS} ${COPY_TARGET_COMMANDS} COMMAND cmake -E chdir pack_${CPACK_PACKAGE_FILE_NAME}_${EXT_SLUG} cmake -E tar ${TAR_MODE} ../${CPACK_PACKAGE_FILE_NAME}.${ext} ${TAR_EXTRA_ARGS} -- ${CPACK_PACKAGE_FILE_NAME}/ - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS ${CPACK_TARGETS} ) add_custom_target(package_${EXT_SLUG} DEPENDS ${CPACK_PACKAGE_FILE_NAME}.${ext}) endforeach() diff --git a/other/bundle/server/Info.plist b/other/bundle/server/Info.plist index 79ccd31a4..32d88498f 100644 --- a/other/bundle/server/Info.plist +++ b/other/bundle/server/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion English CFBundleExecutable - DDNet_server + DDNet-Server-Launcher CFBundleIconFile DDNet-Server CFBundleInfoDictionaryVersion diff --git a/src/osxlaunch/server.m b/src/osxlaunch/server.m deleted file mode 100644 index e542ff16f..000000000 --- a/src/osxlaunch/server.m +++ /dev/null @@ -1,112 +0,0 @@ -#import - -@interface ServerView : NSTextView -{ - NSTask *task; - NSFileHandle *file; -} -- (void)listenTo: (NSTask*)t; -@end - -@implementation ServerView -- (void)listenTo: (NSTask*)t; -{ - NSPipe *pipe; - task = t; - pipe = [NSPipe pipe]; - [task setStandardOutput: pipe]; - file = [pipe fileHandleForReading]; - - [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(outputNotification:) name: NSFileHandleReadCompletionNotification object: file]; - - [file readInBackgroundAndNotify]; -} - -- (void) outputNotification: (NSNotification *) notification -{ - NSData *data = [[[notification userInfo] objectForKey: NSFileHandleNotificationDataItem] retain]; - NSString *string = [[NSString alloc] initWithData: data encoding: NSASCIIStringEncoding]; - NSAttributedString *attrstr = [[NSAttributedString alloc] initWithString: string]; - - [[self textStorage] appendAttributedString: attrstr]; - int length = [[self textStorage] length]; - NSRange range = NSMakeRange(length, 0); - [self scrollRangeToVisible: range]; - - [attrstr release]; - [string release]; - [file readInBackgroundAndNotify]; -} - --(void)windowWillClose:(NSNotification *)notification -{ - [task terminate]; - [NSApp terminate:self]; -} -@end - -void runServer() -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSApp = [NSApplication sharedApplication]; - NSBundle* mainBundle = [NSBundle mainBundle]; - NSTask *task; - task = [[NSTask alloc] init]; - [task setCurrentDirectoryPath: [mainBundle resourcePath]]; - - // get a server config - NSOpenPanel* openDlg = [NSOpenPanel openPanel]; - [openDlg setCanChooseFiles:YES]; - - if([openDlg runModalForDirectory:nil file:nil] != NSOKButton) - return; - - NSArray* filenames = [openDlg filenames]; - if([filenames count] != 1) - return; - - NSString* filename = [filenames objectAtIndex: 0]; - NSArray* arguments = [NSArray arrayWithObjects: @"-f", filename, nil]; - - // run server - NSWindow *window; - ServerView *view; - NSRect graphicsRect; - - graphicsRect = NSMakeRect(100.0, 1000.0, 600.0, 400.0); - - window = [[NSWindow alloc] - initWithContentRect: graphicsRect - styleMask: NSTitledWindowMask - | NSClosableWindowMask - | NSMiniaturizableWindowMask - backing: NSBackingStoreBuffered - defer: NO]; - - [window setTitle: @"DDNet Server"]; - - view = [[[ServerView alloc] initWithFrame: graphicsRect] autorelease]; - [view setEditable: NO]; - [view setRulerVisible: YES]; - - [window setContentView: view]; - [window setDelegate: view]; - [window makeKeyAndOrderFront: nil]; - - [view listenTo: task]; - [task setLaunchPath: [mainBundle pathForAuxiliaryExecutable: @"DDNet-Server"]]; - [task setArguments: arguments]; - [task launch]; - [NSApp run]; - [task terminate]; - - [NSApp release]; - [pool release]; -} - -int main (int argc, char **argv) -{ - runServer(); - - return 0; -} diff --git a/src/osxlaunch/server.m b/src/osxlaunch/server.m new file mode 120000 index 000000000..9ff19d9b5 --- /dev/null +++ b/src/osxlaunch/server.m @@ -0,0 +1 @@ +server.mm \ No newline at end of file diff --git a/src/osxlaunch/server.mm b/src/osxlaunch/server.mm new file mode 100644 index 000000000..229857200 --- /dev/null +++ b/src/osxlaunch/server.mm @@ -0,0 +1,112 @@ +#import + +@interface ServerView : NSTextView +{ + NSTask *task; + NSFileHandle *file; +} +- (void)listenTo: (NSTask*)t; +@end + +@implementation ServerView +- (void)listenTo: (NSTask*)t; +{ + NSPipe *pipe; + task = t; + pipe = [NSPipe pipe]; + [task setStandardOutput: pipe]; + file = [pipe fileHandleForReading]; + + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(outputNotification:) name: NSFileHandleReadCompletionNotification object: file]; + + [file readInBackgroundAndNotify]; +} + +- (void) outputNotification: (NSNotification *) notification +{ + NSData *data = [[[notification userInfo] objectForKey: NSFileHandleNotificationDataItem] retain]; + NSString *string = [[NSString alloc] initWithData: data encoding: NSASCIIStringEncoding]; + NSAttributedString *attrstr = [[NSAttributedString alloc] initWithString: string]; + + [[self textStorage] appendAttributedString: attrstr]; + int length = [[self textStorage] length]; + NSRange range = NSMakeRange(length, 0); + [self scrollRangeToVisible: range]; + + [attrstr release]; + [string release]; + [file readInBackgroundAndNotify]; +} + +-(void)windowWillClose:(NSNotification *)notification +{ + [task terminate]; + [NSApp terminate:self]; +} +@end + +void runServer() +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSApp = [NSApplication sharedApplication]; + NSBundle* mainBundle = [NSBundle mainBundle]; + NSTask *task; + task = [[NSTask alloc] init]; + [task setCurrentDirectoryPath: [mainBundle resourcePath]]; + + // get a server config + NSOpenPanel* openDlg = [NSOpenPanel openPanel]; + [openDlg setCanChooseFiles:YES]; + + if([openDlg runModalForDirectory:nil file:nil] != NSOKButton) + return; + + NSArray* filenames = [openDlg filenames]; + if([filenames count] != 1) + return; + + NSString* filename = [filenames objectAtIndex: 0]; + NSArray* arguments = [NSArray arrayWithObjects: @"-f", filename, nil]; + + // run server + NSWindow *window; + ServerView *view; + NSRect graphicsRect; + + graphicsRect = NSMakeRect(100.0, 1000.0, 600.0, 400.0); + + window = [[NSWindow alloc] + initWithContentRect: graphicsRect + styleMask: NSTitledWindowMask + | NSClosableWindowMask + | NSMiniaturizableWindowMask + backing: NSBackingStoreBuffered + defer: NO]; + + [window setTitle: @"DDNet Server"]; + + view = [[[ServerView alloc] initWithFrame: graphicsRect] autorelease]; + [view setEditable: NO]; + [view setRulerVisible: YES]; + + [window setContentView: view]; + [window setDelegate: (id)view]; + [window makeKeyAndOrderFront: nil]; + + [view listenTo: task]; + [task setLaunchPath: [mainBundle pathForAuxiliaryExecutable: @"DDNet-Server"]]; + [task setArguments: arguments]; + [task launch]; + [NSApp run]; + [task terminate]; + + [NSApp release]; + [pool release]; +} + +int main (int argc, char **argv) +{ + runServer(); + + return 0; +} From dcbd8197a40dd088a773d1c750ca56f554c8928d Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Fri, 17 Nov 2017 14:57:42 +0100 Subject: [PATCH 08/12] Stop using deprecated APIs on macOS in server launcher --- src/osxlaunch/server.mm | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/osxlaunch/server.mm b/src/osxlaunch/server.mm index 229857200..97c8301f9 100644 --- a/src/osxlaunch/server.mm +++ b/src/osxlaunch/server.mm @@ -5,11 +5,11 @@ NSTask *task; NSFileHandle *file; } -- (void)listenTo: (NSTask*)t; +- (void)listenTo: (NSTask *)t; @end @implementation ServerView -- (void)listenTo: (NSTask*)t; +- (void)listenTo: (NSTask *)t { NSPipe *pipe; task = t; @@ -49,24 +49,20 @@ void runServer() { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSApp = [NSApplication sharedApplication]; - NSBundle* mainBundle = [NSBundle mainBundle]; + NSBundle *mainBundle = [NSBundle mainBundle]; NSTask *task; task = [[NSTask alloc] init]; [task setCurrentDirectoryPath: [mainBundle resourcePath]]; // get a server config - NSOpenPanel* openDlg = [NSOpenPanel openPanel]; + NSOpenPanel *openDlg = [NSOpenPanel openPanel]; [openDlg setCanChooseFiles:YES]; - if([openDlg runModalForDirectory:nil file:nil] != NSOKButton) + if([openDlg runModal] != NSOKButton) return; - NSArray* filenames = [openDlg filenames]; - if([filenames count] != 1) - return; - - NSString* filename = [filenames objectAtIndex: 0]; - NSArray* arguments = [NSArray arrayWithObjects: @"-f", filename, nil]; + NSString *filename = [[openDlg URL] path]; + NSArray *arguments = [NSArray arrayWithObjects: @"-f", filename, nil]; // run server NSWindow *window; @@ -104,7 +100,7 @@ void runServer() [pool release]; } -int main (int argc, char **argv) +int main(int argc, char **argv) { runServer(); From 44c0f872fec25eb19c738bd3cb4d75f2ba919e3a Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Fri, 17 Nov 2017 15:55:22 +0100 Subject: [PATCH 09/12] Replace `cmake` by `${CMAKE_COMMAND}` in custom commands This allows execution even when `cmake` isn't in the current `$PATH` or `%PATH%` variable. --- CMakeLists.txt | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bf9f1da44..acc896ff9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1242,27 +1242,27 @@ if(DMGTOOLS_FOUND OR HDIUTIL) ) set(DMG_MKDIR_COMMANDS) foreach(dir ${DMG_MKDIRS}) - list(APPEND DMG_MKDIR_COMMANDS COMMAND cmake -E make_directory ${DMG_TMPDIR}/${dir}) + list(APPEND DMG_MKDIR_COMMANDS COMMAND ${CMAKE_COMMAND} -E make_directory ${DMG_TMPDIR}/${dir}) endforeach() add_custom_command(OUTPUT ${CPACK_PACKAGE_FILE_NAME}.dmg - COMMAND cmake -E remove_directory ${DMG_TMPDIR} + COMMAND ${CMAKE_COMMAND} -E remove_directory ${DMG_TMPDIR} ${DMG_MKDIR_COMMANDS} # CLIENT - COMMAND cmake -E copy_directory ${PROJECT_SOURCE_DIR}/data ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Resources/data - COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/other/icons/${TARGET_CLIENT}.icns ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Resources/ - COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/other/bundle/client/Info.plist ${PROJECT_SOURCE_DIR}/other/bundle/client/PkgInfo ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/ - COMMAND cmake -E copy $ ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/ - COMMAND cmake -E copy_directory ${PROJECT_SOURCE_DIR}/ddnet-libs/sdl/mac/lib64/SDL2.framework ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/SDL2.framework - COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/ddnet-libs/freetype/mac/lib64/libfreetype.6.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/ + COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/data ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Resources/data + COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/other/icons/${TARGET_CLIENT}.icns ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Resources/ + COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/other/bundle/client/Info.plist ${PROJECT_SOURCE_DIR}/other/bundle/client/PkgInfo ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/ + COMMAND ${CMAKE_COMMAND} -E copy $ ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/ + COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/ddnet-libs/sdl/mac/lib64/SDL2.framework ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/SDL2.framework + COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/ddnet-libs/freetype/mac/lib64/libfreetype.6.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/ COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change @rpath/SDL2.framework/Versions/A/SDL2 @executable_path/../Frameworks/SDL2.framework/SDL2 ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/${TARGET_CLIENT} COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change /usr/local/lib/libfreetype.6.dylib @executable_path/../Frameworks/libfreetype.6.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/${TARGET_CLIENT} # SERVER - COMMAND cmake -E copy_directory ${PROJECT_SOURCE_DIR}/data/maps ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/Resources/data/maps - COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/other/icons/${TARGET_SERVER}.icns ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/Resources/ - COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/other/bundle/server/Info.plist ${PROJECT_SOURCE_DIR}/other/bundle/server/PkgInfo ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/ - COMMAND cmake -E copy $ $ ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/MacOS/ + COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/data/maps ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/Resources/data/maps + COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/other/icons/${TARGET_SERVER}.icns ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/Resources/ + COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/other/bundle/server/Info.plist ${PROJECT_SOURCE_DIR}/other/bundle/server/PkgInfo ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/ + COMMAND ${CMAKE_COMMAND} -E copy $ $ ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/MacOS/ # DMG COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/dmg.py create ${DMG_PARAMS} ${CPACK_PACKAGE_FILE_NAME}.dmg ${CPACK_PACKAGE_FILE_NAME} ${DMG_TMPDIR} @@ -1283,13 +1283,13 @@ foreach(ext zip tar.gz tar.xz) set(COPY_DIR_COMMANDS) set(COPY_TARGET_COMMANDS) foreach(file ${CPACK_FILES}) - list(APPEND COPY_FILE_COMMANDS COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/${file} ${TMPDIR}/) + list(APPEND COPY_FILE_COMMANDS COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/${file} ${TMPDIR}/) endforeach() foreach(dir ${CPACK_DIRS}) - list(APPEND COPY_DIR_COMMANDS COMMAND cmake -E copy_directory ${PROJECT_SOURCE_DIR}/${dir} ${TMPDIR}/${dir}) + list(APPEND COPY_DIR_COMMANDS COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/${dir} ${TMPDIR}/${dir}) endforeach() foreach(target ${CPACK_TARGETS}) - list(APPEND COPY_TARGET_COMMANDS COMMAND cmake -E copy $ ${TMPDIR}/) + list(APPEND COPY_TARGET_COMMANDS COMMAND ${CMAKE_COMMAND} -E copy $ ${TMPDIR}/) endforeach() if(ext STREQUAL zip) @@ -1300,12 +1300,12 @@ foreach(ext zip tar.gz tar.xz) set(TAR_MODE cJ) endif() add_custom_command(OUTPUT ${CPACK_PACKAGE_FILE_NAME}.${ext} - COMMAND cmake -E remove_directory ${TMPDIR} - COMMAND cmake -E make_directory ${TMPDIR} + COMMAND ${CMAKE_COMMAND} -E remove_directory ${TMPDIR} + COMMAND ${CMAKE_COMMAND} -E make_directory ${TMPDIR} ${COPY_FILE_COMMANDS} ${COPY_DIR_COMMANDS} ${COPY_TARGET_COMMANDS} - COMMAND cmake -E chdir pack_${CPACK_PACKAGE_FILE_NAME}_${EXT_SLUG} cmake -E tar ${TAR_MODE} ../${CPACK_PACKAGE_FILE_NAME}.${ext} ${TAR_EXTRA_ARGS} -- ${CPACK_PACKAGE_FILE_NAME}/ + COMMAND ${CMAKE_COMMAND} -E chdir pack_${CPACK_PACKAGE_FILE_NAME}_${EXT_SLUG} ${CMAKE_COMMAND} -E tar ${TAR_MODE} ../${CPACK_PACKAGE_FILE_NAME}.${ext} ${TAR_EXTRA_ARGS} -- ${CPACK_PACKAGE_FILE_NAME}/ DEPENDS ${CPACK_TARGETS} ) add_custom_target(package_${EXT_SLUG} DEPENDS ${CPACK_PACKAGE_FILE_NAME}.${ext}) From 373a96a11f465eadbf204ae05526f5e044e98840 Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Fri, 17 Nov 2017 17:43:52 +0100 Subject: [PATCH 10/12] Don't install the `portable` component for `make install` --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index acc896ff9..343ae5b11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1212,7 +1212,7 @@ if(TARGET_OS STREQUAL "windows") endif() if(CMAKE_VERSION VERSION_GREATER 3.6 OR CMAKE_VERSION VERSION_EQUAL 3.6) - set(EXTRA_ARGS DESTINATION ${CPACK_PACKAGE_FILE_NAME} COMPONENT portable) + set(EXTRA_ARGS DESTINATION ${CPACK_PACKAGE_FILE_NAME} COMPONENT portable EXCLUDE_FROM_ALL) install(TARGETS ${CPACK_TARGETS} ${EXTRA_ARGS}) install(DIRECTORY ${CPACK_DIRS} ${EXTRA_ARGS}) install(FILES ${CPACK_FILES} ${EXTRA_ARGS}) From 4b45f857c71ca29b90d2b2c275fcf859a76f8e5c Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Fri, 17 Nov 2017 22:32:44 +0100 Subject: [PATCH 11/12] DMG: Put version into `Info.plist` --- CMakeLists.txt | 23 ++++++++++++++++--- .../client/{Info.plist => Info.plist.in} | 6 ++--- .../server/{Info.plist => Info.plist.in} | 6 ++--- 3 files changed, 26 insertions(+), 9 deletions(-) rename other/bundle/client/{Info.plist => Info.plist.in} (85%) rename other/bundle/server/{Info.plist => Info.plist.in} (81%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 343ae5b11..058b4191a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ else() set(PROJECT_VERSION_MAJOR ${VERSION_MAJOR}) set(PROJECT_VERSION_MINOR ${VERSION_MINOR}) set(PROJECT_VERSION_PATCH ${VERSION_PATCH}) + set(PROJECT_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) endif() set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake) @@ -1221,6 +1222,11 @@ else() endif() if(DMGTOOLS_FOUND OR HDIUTIL) + file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/bundle/client/") + file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/bundle/server/") + configure_file(other/bundle/client/Info.plist.in bundle/client/Info.plist) + configure_file(other/bundle/server/Info.plist.in bundle/server/Info.plist) + if(HDIUTIL) set(DMG_PARAMS --hdiutil ${HDIUTIL}) elseif(DMGTOOLS_FOUND) @@ -1251,7 +1257,7 @@ if(DMGTOOLS_FOUND OR HDIUTIL) # CLIENT COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/data ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Resources/data COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/other/icons/${TARGET_CLIENT}.icns ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Resources/ - COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/other/bundle/client/Info.plist ${PROJECT_SOURCE_DIR}/other/bundle/client/PkgInfo ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/ + COMMAND ${CMAKE_COMMAND} -E copy bundle/client/Info.plist ${PROJECT_SOURCE_DIR}/other/bundle/client/PkgInfo ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/ COMMAND ${CMAKE_COMMAND} -E copy $ ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/MacOS/ COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/ddnet-libs/sdl/mac/lib64/SDL2.framework ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/SDL2.framework COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/ddnet-libs/freetype/mac/lib64/libfreetype.6.dylib ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/Frameworks/ @@ -1261,13 +1267,24 @@ if(DMGTOOLS_FOUND OR HDIUTIL) # SERVER COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/data/maps ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/Resources/data/maps COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/other/icons/${TARGET_SERVER}.icns ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/Resources/ - COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/other/bundle/server/Info.plist ${PROJECT_SOURCE_DIR}/other/bundle/server/PkgInfo ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/ + COMMAND ${CMAKE_COMMAND} -E copy bundle/server/Info.plist ${PROJECT_SOURCE_DIR}/other/bundle/server/PkgInfo ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/ COMMAND ${CMAKE_COMMAND} -E copy $ $ ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/MacOS/ # DMG COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/dmg.py create ${DMG_PARAMS} ${CPACK_PACKAGE_FILE_NAME}.dmg ${CPACK_PACKAGE_FILE_NAME} ${DMG_TMPDIR} - DEPENDS ${TARGET_CLIENT} ${TARGET_SERVER} ${TARGET_SERVER_LAUNCHER} + DEPENDS + ${TARGET_CLIENT} + ${TARGET_SERVER_LAUNCHER} + ${TARGET_SERVER} + ${CMAKE_BINARY_DIR}/bundle/client/Info.plist + ${CMAKE_BINARY_DIR}/bundle/server/Info.plist + data + other/bundle/client/PkgInfo + other/bundle/server/PkgInfo + other/icons/${TARGET_CLIENT}.icns + other/icons/${TARGET_SERVER}.icns + scripts/dmg.py ) add_custom_target(package_dmg DEPENDS ${CPACK_PACKAGE_FILE_NAME}.dmg) endif() diff --git a/other/bundle/client/Info.plist b/other/bundle/client/Info.plist.in similarity index 85% rename from other/bundle/client/Info.plist rename to other/bundle/client/Info.plist.in index 09cab5db1..3346bf5e6 100644 --- a/other/bundle/client/Info.plist +++ b/other/bundle/client/Info.plist.in @@ -5,9 +5,9 @@ CFBundleDevelopmentRegion English CFBundleExecutable - DDNet + ${TARGET_CLIENT} CFBundleIconFile - DDNet + ${TARGET_CLIENT} CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType @@ -15,7 +15,7 @@ CFBundleSignature ???? CFBundleVersion - %s + ${PROJECT_VERSION} CFBundleIdentifier org.DDNetClient.app NSHighResolutionCapable diff --git a/other/bundle/server/Info.plist b/other/bundle/server/Info.plist.in similarity index 81% rename from other/bundle/server/Info.plist rename to other/bundle/server/Info.plist.in index 32d88498f..6cdd38f0d 100644 --- a/other/bundle/server/Info.plist +++ b/other/bundle/server/Info.plist.in @@ -5,9 +5,9 @@ CFBundleDevelopmentRegion English CFBundleExecutable - DDNet-Server-Launcher + ${TARGET_SERVER_LAUNCHER} CFBundleIconFile - DDNet-Server + ${TARGET_SERVER} CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType @@ -15,6 +15,6 @@ CFBundleSignature ???? CFBundleVersion - %s + ${PROJECT_VERSION} From 4c63e26bb7734aeab68002aa3893f713fa3f3cbf Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Fri, 17 Nov 2017 22:32:56 +0100 Subject: [PATCH 12/12] `package_all` now actually produces all packages --- CMakeLists.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 058b4191a..b5d7239aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1221,6 +1221,8 @@ else() message(WARNING "Cannot create CPack targets, CMake version too old. Use CMake 3.6 or newer.") endif() +set(PACKAGE_TARGETS) + if(DMGTOOLS_FOUND OR HDIUTIL) file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/bundle/client/") file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/bundle/server/") @@ -1287,6 +1289,7 @@ if(DMGTOOLS_FOUND OR HDIUTIL) scripts/dmg.py ) add_custom_target(package_dmg DEPENDS ${CPACK_PACKAGE_FILE_NAME}.dmg) + list(APPEND PACKAGE_TARGETS package_dmg) endif() foreach(ext zip tar.gz tar.xz) @@ -1326,6 +1329,7 @@ foreach(ext zip tar.gz tar.xz) DEPENDS ${CPACK_TARGETS} ) add_custom_target(package_${EXT_SLUG} DEPENDS ${CPACK_PACKAGE_FILE_NAME}.${ext}) + list(APPEND PACKAGE_TARGETS package_${EXT_SLUG}) endforeach() set(PACKAGE_DEFAULT tar_xz) @@ -1336,11 +1340,7 @@ elseif(TARGET_OS STREQUAL "mac") endif() add_custom_target(package_default DEPENDS package_${PACKAGE_DEFAULT}) -add_custom_target(package_all DEPENDS - package_tar_gz - package_tar_xz - package_zip -) +add_custom_target(package_all DEPENDS ${PACKAGE_TARGETS}) # Unset these variables, they might do something in the future of CPack. unset(CPACK_SOURCE_FILES)