941: Add cross-compiled DMG archives r=Learath2 a=heinrich5991

Currently they only contain the client and the archives are a lot larger
than the current release artifacts.
This commit is contained in:
bors[bot] 2017-12-08 14:20:49 +00:00
commit a2f010c1fe
10 changed files with 393 additions and 133 deletions

View file

@ -21,6 +21,7 @@ else()
set(PROJECT_VERSION_MAJOR ${VERSION_MAJOR}) set(PROJECT_VERSION_MAJOR ${VERSION_MAJOR})
set(PROJECT_VERSION_MINOR ${VERSION_MINOR}) set(PROJECT_VERSION_MINOR ${VERSION_MINOR})
set(PROJECT_VERSION_PATCH ${VERSION_PATCH}) set(PROJECT_VERSION_PATCH ${VERSION_PATCH})
set(PROJECT_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
endif() endif()
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake)
@ -149,6 +150,19 @@ else()
set(ZLIB_FOUND NO) set(ZLIB_FOUND NO)
endif() 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()
find_program(HDIUTIL hdiutil)
endif()
message(STATUS "******** DDNet ********") message(STATUS "******** DDNet ********")
message(STATUS "Target OS: ${TARGET_OS} ${TARGET_BITS}bit") message(STATUS "Target OS: ${TARGET_OS} ${TARGET_BITS}bit")
message(STATUS "Compiler: ${CMAKE_CXX_COMPILER}") message(STATUS "Compiler: ${CMAKE_CXX_COMPILER}")
@ -169,11 +183,17 @@ function(show_dependency_status NAME FOUND PATH)
endfunction() endfunction()
show_dependency_status("Curl" ${CURL_FOUND} "${CURL_LIBRARY}") 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("Freetype" ${FREETYPE_FOUND} "${FREETYPE_LIBRARY}")
if(DOWNLOAD_GTEST) if(DOWNLOAD_GTEST)
show_dependency_status("Git" ${GIT_FOUND} "${GIT_EXECUTABLE}") show_dependency_status("Git" ${GIT_FOUND} "${GIT_EXECUTABLE}")
endif() endif()
show_dependency_status("GTest" ${GTEST_FOUND} "${GTEST_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) if(MYSQL)
show_dependency_status("MySQL" ${MYSQL_FOUND} "${MYSQL_LIBRARY}") show_dependency_status("MySQL" ${MYSQL_FOUND} "${MYSQL_LIBRARY}")
endif() endif()
@ -935,6 +955,15 @@ target_link_libraries(${TARGET_SERVER} ${LIBS_SERVER})
list(APPEND TARGETS_OWN ${TARGET_SERVER}) list(APPEND TARGETS_OWN ${TARGET_SERVER})
list(APPEND TARGETS_LINK ${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 # VARIOUS TARGETS
######################################################################## ########################################################################
@ -1146,6 +1175,7 @@ if(TARGET_OS AND TARGET_BITS)
endif() endif()
set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME}) 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_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-src)
set(CPACK_SOURCE_FILES set(CPACK_SOURCE_FILES
CMakeLists.txt CMakeLists.txt
@ -1201,7 +1231,7 @@ if(TARGET_OS STREQUAL "windows")
endif() endif()
if(CMAKE_VERSION VERSION_GREATER 3.6 OR CMAKE_VERSION VERSION_EQUAL 3.6) 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(TARGETS ${CPACK_TARGETS} ${EXTRA_ARGS})
install(DIRECTORY ${CPACK_DIRS} ${EXTRA_ARGS}) install(DIRECTORY ${CPACK_DIRS} ${EXTRA_ARGS})
install(FILES ${CPACK_FILES} ${EXTRA_ARGS}) install(FILES ${CPACK_FILES} ${EXTRA_ARGS})
@ -1209,23 +1239,97 @@ else()
message(WARNING "Cannot create CPack targets, CMake version too old. Use CMake 3.6 or newer.") message(WARNING "Cannot create CPack targets, CMake version too old. Use CMake 3.6 or newer.")
endif() endif()
set(COPY_FILE_COMMANDS) set(PACKAGE_TARGETS)
set(COPY_DIR_COMMANDS)
set(COPY_TARGET_COMMANDS) if(DMGTOOLS_FOUND OR HDIUTIL)
foreach(file ${CPACK_FILES}) file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/bundle/client/")
list(APPEND COPY_FILE_COMMANDS COMMAND cmake -E copy ${PROJECT_SOURCE_DIR}/${file} ${CPACK_PACKAGE_FILE_NAME}/) file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/bundle/server/")
endforeach() configure_file(other/bundle/client/Info.plist.in bundle/client/Info.plist)
foreach(dir ${CPACK_DIRS}) configure_file(other/bundle/server/Info.plist.in bundle/server/Info.plist)
list(APPEND COPY_DIR_COMMAND COMMAND cmake -E copy_directory ${PROJECT_SOURCE_DIR}/${dir} ${CPACK_PACKAGE_FILE_NAME}/${dir})
endforeach() if(HDIUTIL)
foreach(target ${CPACK_TARGETS}) set(DMG_PARAMS --hdiutil ${HDIUTIL})
list(APPEND COPY_TARGET_COMMANDS COMMAND cmake -E copy $<TARGET_FILE:${target}> ${CPACK_PACKAGE_FILE_NAME}/) elseif(DMGTOOLS_FOUND)
endforeach() 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
${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})
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_COMMAND} -E remove_directory ${DMG_TMPDIR}
${DMG_MKDIR_COMMANDS}
# 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 bundle/client/Info.plist ${PROJECT_SOURCE_DIR}/other/bundle/client/PkgInfo ${DMG_TMPDIR}/${TARGET_CLIENT}.app/Contents/
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${TARGET_CLIENT}> ${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_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 bundle/server/Info.plist ${PROJECT_SOURCE_DIR}/other/bundle/server/PkgInfo ${DMG_TMPDIR}/${TARGET_SERVER}.app/Contents/
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${TARGET_SERVER}> $<TARGET_FILE:${TARGET_SERVER_LAUNCHER}> ${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_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)
list(APPEND PACKAGE_TARGETS package_dmg)
endif()
foreach(ext zip tar.gz tar.xz) foreach(ext zip tar.gz tar.xz)
set(TAR_MODE c) set(TAR_MODE c)
set(TAR_EXTRA_ARGS) set(TAR_EXTRA_ARGS)
string(REPLACE . _ EXT_SLUG ${ext}) 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_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/${file} ${TMPDIR}/)
endforeach()
foreach(dir ${CPACK_DIRS})
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_COMMAND} -E copy $<TARGET_FILE:${target}> ${TMPDIR}/)
endforeach()
if(ext STREQUAL zip) if(ext STREQUAL zip)
set(TAR_EXTRA_ARGS --format=zip) set(TAR_EXTRA_ARGS --format=zip)
elseif(ext STREQUAL tar.gz) elseif(ext STREQUAL tar.gz)
@ -1234,27 +1338,27 @@ foreach(ext zip tar.gz tar.xz)
set(TAR_MODE cJ) set(TAR_MODE cJ)
endif() endif()
add_custom_command(OUTPUT ${CPACK_PACKAGE_FILE_NAME}.${ext} add_custom_command(OUTPUT ${CPACK_PACKAGE_FILE_NAME}.${ext}
COMMAND cmake -E make_directory ${CPACK_PACKAGE_FILE_NAME} COMMAND ${CMAKE_COMMAND} -E remove_directory ${TMPDIR}
COMMAND ${CMAKE_COMMAND} -E make_directory ${TMPDIR}
${COPY_FILE_COMMANDS} ${COPY_FILE_COMMANDS}
${COPY_DIR_COMMANDS} ${COPY_DIR_COMMANDS}
${COPY_TARGET_COMMANDS} ${COPY_TARGET_COMMANDS}
COMMAND 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}/
WORKING_DIRECTORY ${PROJECT_BINARY_DIR} DEPENDS ${CPACK_TARGETS}
) )
add_custom_target(package_${EXT_SLUG} DEPENDS ${CPACK_PACKAGE_FILE_NAME}.${ext}) add_custom_target(package_${EXT_SLUG} DEPENDS ${CPACK_PACKAGE_FILE_NAME}.${ext})
list(APPEND PACKAGE_TARGETS package_${EXT_SLUG})
endforeach() endforeach()
set(PACKAGE_DEFAULT tar_xz) set(PACKAGE_DEFAULT tar_xz)
if(TARGET_OS STREQUAL "windows") if(TARGET_OS STREQUAL "windows")
set(PACKAGE_DEFAULT zip) set(PACKAGE_DEFAULT zip)
elseif(TARGET_OS STREQUAL "mac")
set(PACKAGE_DEFAULT dmg)
endif() endif()
add_custom_target(package_default DEPENDS package_${PACKAGE_DEFAULT}) add_custom_target(package_default DEPENDS package_${PACKAGE_DEFAULT})
add_custom_target(package_all DEPENDS add_custom_target(package_all DEPENDS ${PACKAGE_TARGETS})
package_tar_gz
package_tar_xz
package_zip
)
# Unset these variables, they might do something in the future of CPack. # Unset these variables, they might do something in the future of CPack.
unset(CPACK_SOURCE_FILES) unset(CPACK_SOURCE_FILES)

View file

@ -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 `-DCMAKE_OSX_SYSROOT=/path/to/osxcross/target/SDK/MacOSX10.11.sdk/` to the
**initial** CMake command line. **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 Importing the official DDNet Database
------------------------------------- -------------------------------------

View file

@ -2,6 +2,7 @@ set(CMAKE_SYSTEM_NAME Darwin)
set(CMAKE_C_COMPILER o64-clang) set(CMAKE_C_COMPILER o64-clang)
set(CMAKE_CXX_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_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${TARGET_CLIENT}</string>
<key>CFBundleIconFile</key>
<string>${TARGET_CLIENT}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${PROJECT_VERSION}</string>
<key>CFBundleIdentifier</key>
<string>org.DDNetClient.app</string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>

View file

@ -0,0 +1 @@
APPL????

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${TARGET_SERVER_LAUNCHER}</string>
<key>CFBundleIconFile</key>
<string>${TARGET_SERVER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${PROJECT_VERSION}</string>
</dict>
</plist>

View file

@ -0,0 +1 @@
APPL????

106
scripts/dmg.py Normal file
View file

@ -0,0 +1,106 @@
from collections import namedtuple
import os
import shlex
import subprocess
import tempfile
ConfigDmgtools = namedtuple('Config', 'dmg hfsplus newfs_hfs verbose')
ConfigHdiutil = namedtuple('Config', 'hdiutil 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"] = open(os.devnull, 'wb')
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):
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):
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)
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)
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")
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")
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")
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 []
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__':
main()

View file

@ -1,112 +0,0 @@
#import <Cocoa/Cocoa.h>
@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;
}

1
src/osxlaunch/server.m Symbolic link
View file

@ -0,0 +1 @@
server.mm

108
src/osxlaunch/server.mm Normal file
View file

@ -0,0 +1,108 @@
#import <Cocoa/Cocoa.h>
@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 runModal] != NSOKButton)
return;
NSString *filename = [[openDlg URL] path];
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<NSWindowDelegate>)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;
}