[chronojump: 2/3] Add a new script to package macOS
- From: Xavier de Blas <xaviblas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump: 2/3] Add a new script to package macOS
- Date: Tue, 26 May 2020 16:30:03 +0000 (UTC)
commit a3c2528ea3c22ea40267f42d2ae4e64339c4256a
Author: Andoni Morales Alastruey <ylatuya gmail com>
Date: Fri May 15 18:41:15 2020 +0200
Add a new script to package macOS
.gitignore | 4 +
package/macos/Makefile | 60 +++++++++
package/macos/app/Applications | 1 +
.../app/Chronojump.app/Contents/MacOS/Chronojump | 1 +
.../Chronojump.app/Contents/Resources/icon.icns | Bin 0 -> 88060 bytes
package/macos/resources/Info.plist | 26 ++++
package/macos/resources/config | 54 ++++++++
package/macos/resources/osxrelocator.py | 139 +++++++++++++++++++++
8 files changed, 285 insertions(+)
---
diff --git a/.gitignore b/.gitignore
index fe30cea4..76016a11 100644
--- a/.gitignore
+++ b/.gitignore
@@ -76,3 +76,7 @@ chronojump.userprefs
# Files generated by "make dist" on Linux
ChangeLog
chronojump-*.tar.gz
+
+#MacOS package
+package/macos/Chronojump.app/Contents/Home
+package/macos/Chronojump.app/Contents/Info.plist
\ No newline at end of file
diff --git a/package/macos/Makefile b/package/macos/Makefile
new file mode 100644
index 00000000..c714a7a3
--- /dev/null
+++ b/package/macos/Makefile
@@ -0,0 +1,60 @@
+MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
+CUR_DIR := $(dir $(MKFILE_PATH))
+BASE_DIR = "$(CUR_DIR)/../../"
+SOURCES_DIR = "$(CUR_DIR)/../../src"
+TOOLS_DIR = "$(CUR_DIR)/../../tools"
+PACKAGE_DIR = "$(CUR_DIR)/../../package/macos"
+APP_DIR = "$(PACKAGE_DIR)/app/Chronojump.app/Contents/"
+RESOURCES_DIR = "$(PACKAGE_DIR)/resources"
+SIGNING = "$(PACKAGE_DIR)/../signing"
+USER = $(shell whoami)
+PACKAGE_VERSION = $(shell git describe --abbrev=0)
+PACKAGE_NAME = "chronojump-$(PACKAGE_VERSION)-x86_64"
+BUILD_DIR = "$(SOURCES_DIR)/build"
+MONO_DIR = "/Library/Frameworks/Mono.framework/Versions/Current/"
+MONO_PKG_CONFIG = "$(MONO_DIR)/lib/pkgconfig"
+PATH := $(PATH):/usr/local/Cellar/gettext/0.20.1/bin
+
+all: configure chronojump install_chronojump install_mono bundle package
+
+
+configure:
+ cd $(BASE_DIR) && PKG_CONFIG_PATH=/Library/Frameworks/Mono.framework/Versions/Current/lib/pkgconfig
sh autogen.sh --prefix=$(APP_DIR)/Home/
+
+chronojump:
+ cd $(BASE_DIR) && make
+
+install_chronojump:
+ cd $(BASE_DIR) && make install
+
+install_mono:
+ # Copy the files that will not be embedded in the bundle
+ cp -r $(MONO_DIR)/lib/lib*dylib $(APP_DIR)/Home/lib/
+ cp $(MONO_DIR)/lib/*sharpglue*.so $(APP_DIR)/Home/lib/
+ codesign --remove-signature $(APP_DIR)/Home/lib/lib*dylib
+ python $(RESOURCES_DIR)/osxrelocator.py lib/ $(APP_DIR)/Home/
/Library/Frameworks/Mono.framework/Versions/6.8.0/ --recursive
+
+bundle:
+ # Generate Info.plist file
+ cp $(PACKAGE_DIR)/resources/Info.plist $(APP_DIR)
+ sed -e s/{version}/$(PACKAGE_VERSION)/ $(PACKAGE_DIR)/resources/Info.plist > $(APP_DIR)/Info.plist
+ # The mono binary is signed, we need to remove the signature to add the rpath's
+ # otherwise modifying the binary invalidates the signature
+ cp $(MONO_DIR)/bin/mono $(PACKAGE_DIR)
+ codesign --remove-signature $(PACKAGE_DIR)/mono
+ install_name_tool -add_rpath @executable_path/../lib -add_rpath @loader_path $(PACKAGE_DIR)/mono
+ mkbundle \
+ $(APP_DIR)/Home/lib/chronojump/Chronojump.exe \
+ -o $(PACKAGE_DIR)/Chronojump \
+ -L $(MONO_DIR)/lib/mono/4.5/ \
+ -L $(MONO_DIR)/lib/mono/4.5/Facades \
+ -L $(MONO_DIR)/lib/mono/gtk-sharp-2.0 \
+ --runtime $(PACKAGE_DIR)/mono \
+ --config $(RESOURCES_DIR)/config \
+ --simple \
+ --deps
+ cp $(PACKAGE_DIR)/Chronojump $(APP_DIR)/Home/bin/
+
+
+package:
+ hdiutil create -volname Chronojump -srcfolder app -ov -format UDZO Chronojump-$(PACKAGE_VERSION).dmg
\ No newline at end of file
diff --git a/package/macos/app/Applications b/package/macos/app/Applications
new file mode 120000
index 00000000..bd2d47fa
--- /dev/null
+++ b/package/macos/app/Applications
@@ -0,0 +1 @@
+/Applications
\ No newline at end of file
diff --git a/package/macos/app/Chronojump.app/Contents/MacOS/Chronojump
b/package/macos/app/Chronojump.app/Contents/MacOS/Chronojump
new file mode 120000
index 00000000..b0d18d41
--- /dev/null
+++ b/package/macos/app/Chronojump.app/Contents/MacOS/Chronojump
@@ -0,0 +1 @@
+../Home/bin/Chronojump
\ No newline at end of file
diff --git a/package/macos/app/Chronojump.app/Contents/Resources/icon.icns
b/package/macos/app/Chronojump.app/Contents/Resources/icon.icns
new file mode 100644
index 00000000..026086dc
Binary files /dev/null and b/package/macos/app/Chronojump.app/Contents/Resources/icon.icns differ
diff --git a/package/macos/resources/Info.plist b/package/macos/resources/Info.plist
new file mode 100644
index 00000000..f778bc82
--- /dev/null
+++ b/package/macos/resources/Info.plist
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+<key>CFBundleIdentifier</key>
+<string>org.chronojump</string>
+<key>CFBundleName</key>
+<string>Chronojump</string>
+<key>CFBundleExecutable</key>
+<string>Chronojump</string>
+<key>CFBundlePackageGetInfoString</key>
+<string>Chronojump</string>
+<key>CFBundlePackageType</key>
+<string>APPL</string>
+<key>CFBundleVersion</key>
+<string>{version}</string>
+<key>CFBundleShortVersionString</key>
+<string>{version}</string>
+<key>LSMinimumSystemVersion</key>
+<string>10.7</string>
+<key>CFBundleInfoDictionaryVersion</key>
+<string>6.0</string>
+<key>CFBundleIconFile</key>
+<string>icon.icns</string>
+</dict>
+</plist>
diff --git a/package/macos/resources/config b/package/macos/resources/config
new file mode 100644
index 00000000..f993009b
--- /dev/null
+++ b/package/macos/resources/config
@@ -0,0 +1,54 @@
+<configuration>
+ <dllmap dll="i:cygwin1.dll" target="libc.dylib" os="!windows" />
+ <dllmap dll="libc" target="libc.dylib" os="!windows"/>
+ <dllmap dll="intl" target="libintl.dylib" os="!windows"/>
+ <dllmap dll="intl" name="bind_textdomain_codeset" target="libc.dylib" os="solaris"/>
+ <dllmap dll="libintl" name="bind_textdomain_codeset" target="libc.dylib" os="solaris"/>
+ <dllmap dll="libintl" target="libintl.dylib" os="!windows"/>
+ <dllmap dll="i:libxslt.dll" target="libxslt.dylib" os="!windows"/>
+ <dllmap dll="i:odbc32.dll" target="libodbc.so.2" os="!windows"/>
+ <dllmap dll="i:odbc32.dll" target="libiodbc.dylib" os="osx"/>
+ <dllmap dll="oci" target="libclntsh.dylib" os="!windows"/>
+ <dllmap dll="db2cli" target="libdb2_36.dylib" os="!windows"/>
+ <dllmap dll="MonoPosixHelper" target="libMonoPosixHelper.dylib" os="!windows" />
+ <dllmap dll="System.Native" target="libmono-native-compat.dylib" os="!windows" />
+ <dllmap dll="System.Net.Security.Native" target="libmono-native-compat.dylib" os="!windows" />
+ <dllmap dll="System.Security.Cryptography.Native.Apple" target="libmono-native-compat.dylib" os="osx"
/>
+ <dllmap dll="libmono-btls-shared" target="libmono-btls-shared.dylib" os="!windows" />
+ <dllmap dll="i:msvcrt" target="libc.dylib" os="!windows"/>
+ <dllmap dll="i:msvcrt.dll" target="libc.dylib" os="!windows"/>
+ <dllmap dll="sqlite" target="libsqlite.0.dylib" os="!windows"/>
+ <dllmap dll="sqlite3" target="libsqlite3.0.dylib" os="!windows"/>
+ <dllmap dll="libX11" target="libX11.dylib" os="!windows" />
+ <dllmap dll="libgdk-x11-2.0" target="libgdk-x11-2.0.dylib" os="!windows"/>
+ <dllmap dll="libgdk_pixbuf-2.0" target="libgdk_pixbuf-2.0.so.0" os="!windows"/>
+ <dllmap dll="libgtk-x11-2.0" target="libgtk-x11-2.0.dylib" os="!windows"/>
+ <dllmap dll="libglib-2.0" target="libglib-2.0.so.0" os="!windows"/>
+ <dllmap dll="libgobject-2.0" target="libgobject-2.0.so.0" os="!windows"/>
+ <dllmap dll="libgnomeui-2" target="libgnomeui-2.so.0" os="!windows"/>
+ <dllmap dll="librsvg-2" target="librsvg-2.so.2" os="!windows"/>
+ <dllmap dll="libXinerama" target="libXinerama.so.1" os="!windows" />
+ <dllmap dll="libasound" target="libasound.so.2" os="!windows" />
+ <dllmap dll="libcairo-2.dll" target="libcairo.so.2" os="!windows"/>
+ <dllmap dll="libcairo-2.dll" target="libcairo.2.dylib" os="osx"/>
+ <dllmap dll="libcups" target="libcups.so.2" os="!windows"/>
+ <dllmap dll="libcups" target="libcups.dylib" os="osx"/>
+ <dllmap dll="i:kernel32.dll">
+ <dllentry dll="__Internal" name="CopyMemory" target="mono_win32_compat_CopyMemory"/>
+ <dllentry dll="__Internal" name="FillMemory" target="mono_win32_compat_FillMemory"/>
+ <dllentry dll="__Internal" name="MoveMemory" target="mono_win32_compat_MoveMemory"/>
+ <dllentry dll="__Internal" name="ZeroMemory" target="mono_win32_compat_ZeroMemory"/>
+ </dllmap>
+ <dllmap dll="gdiplus" target="/Library/Frameworks/Mono.framework/Versions/6.8.0/lib/libgdiplus.dylib"
os="!windows"/>
+ <dllmap dll="gdiplus.dll"
target="/Library/Frameworks/Mono.framework/Versions/6.8.0/lib/libgdiplus.dylib" os="!windows"/>
+ <dllmap dll="gdi32" target="/Library/Frameworks/Mono.framework/Versions/6.8.0/lib/libgdiplus.dylib"
os="!windows"/>
+ <dllmap dll="gdi32.dll"
target="/Library/Frameworks/Mono.framework/Versions/6.8.0/lib/libgdiplus.dylib" os="!windows"/>
+
+ <dllmap dll="libglib-2.0-0.dll" target="libglib-2.0.0.dylib"/>
+ <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.0.dylib"/>
+ <dllmap dll="libatk-1.0-0.dll" target="libatk-1.0.0.dylib"/>
+ <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-quartz-2.0.0.dylib"/>
+ <dllmap dll="libgdk-win32-2.0-0.dll" target="libgdk-quartz-2.0.0.dylib"/>
+ <dllmap dll="libgdk_pixbuf-2.0-0.dll" target="libgdk_pixbuf-2.0.0.dylib"/>
+ <dllmap dll="libglade-2.0-0.dll" target="libglade-2.0.0.dylib"/>
+</configuration>
diff --git a/package/macos/resources/osxrelocator.py b/package/macos/resources/osxrelocator.py
new file mode 100644
index 00000000..864c6152
--- /dev/null
+++ b/package/macos/resources/osxrelocator.py
@@ -0,0 +1,139 @@
+#!/usr/bin/env python3
+# cerbero - a multi-platform build system for Open Source software
+# Copyright (C) 2012 Andoni Morales Alastruey <ylatuya gmail com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+import os
+import subprocess
+
+
+INT_CMD = 'install_name_tool'
+OTOOL_CMD = 'otool'
+
+
+class OSXRelocator(object):
+ '''
+ Wrapper for OS X's install_name_tool and otool commands to help
+ relocating shared libraries.
+
+ It parses lib/ /libexec and bin/ directories, changes the prefix path of
+ the shared libraries that an object file uses and changes it's library
+ ID if the file is a shared library.
+ '''
+
+ def __init__(self, root, lib_prefix, recursive, logfile=None):
+ self.root = root
+ self.lib_prefix = self._fix_path(lib_prefix)
+ self.recursive = recursive
+ self.use_relative_paths = True
+ self.logfile = None
+
+ def relocate(self):
+ self.parse_dir(self.root)
+
+ def relocate_dir(self, dirname):
+ self.parse_dir(os.path.join(self.root, dirname))
+
+ def relocate_file(self, object_file):
+ self.change_libs_path(object_file)
+
+ def change_id(self, object_file, id=None):
+ id = id or object_file.replace(self.lib_prefix, '@rpath')
+ filename = os.path.basename(object_file)
+ if not (filename.endswith('so') or filename.endswith('dylib')):
+ return
+ subprocess.call([INT_CMD, "-id", id, object_file])
+
+ def change_libs_path(self, object_file):
+ depth = len(object_file.split('/')) - len(self.root.split('/')) - 1
+ p_depth = '/..' * depth
+ rpaths = ['.']
+ rpaths += ['@loader_path' + p_depth, '@executable_path' + p_depth]
+ rpaths += ['@loader_path' + '/../lib', '@executable_path' + '/../lib']
+ if not (object_file.endswith('so') or object_file.endswith('dylib')):
+ return
+ if depth > 1:
+ rpaths += ['@loader_path/..', '@executable_path/..']
+ for p in rpaths:
+ subprocess.call([INT_CMD, "-add_rpath", p, object_file])
+ for lib in self.list_shared_libraries(object_file):
+ if self.lib_prefix in lib:
+ new_lib = lib.replace(self.lib_prefix, '@rpath')
+ subprocess.call([INT_CMD, '-change', lib, new_lib, object_file])
+
+ def change_lib_path(self, object_file, old_path, new_path):
+ for lib in self.list_shared_libraries(object_file):
+ if old_path in lib:
+ new_path = lib.replace(old_path, new_path)
+ cmd = '%s -change "%s" "%s" "%s"' % (INT_CMD, lib, new_path,
+ object_file)
+ subprocess.call(cmd, fail=True, logfile=self.logfile)
+
+ def parse_dir(self, dir_path, filters=None):
+ for dirpath, dirnames, filenames in os.walk(dir_path):
+ for f in filenames:
+ if filters is not None and \
+ os.path.splitext(f)[1] not in filters:
+ continue
+ self.change_libs_path(os.path.join(dirpath, f))
+ if not self.recursive:
+ break
+
+ @staticmethod
+ def list_shared_libraries(object_file):
+ res = subprocess.getoutput("{} -L {}".format(OTOOL_CMD, object_file)).splitlines()
+ # We don't use the first line
+ libs = res[1:]
+ # Remove the first character tabulation
+ libs = [str(x[1:]) for x in libs]
+ # Remove the version info
+ libs = [x.split(' ', 1)[0] for x in libs]
+ return libs
+
+ def _fix_path(self, path):
+ if path.endswith('/'):
+ return path[:-1]
+ return path
+
+
+class Main(object):
+
+ def run(self):
+ # We use OptionParser instead of ArgumentsParse because this script
+ # might be run in OS X 10.6 or older, which do not provide the argparse
+ # module
+ import optparse
+ usage = "usage: %prog [options] library_path old_prefix new_prefix"
+ description = 'Rellocates object files changing the dependant '\
+ ' dynamic libraries location path with a new one'
+ parser = optparse.OptionParser(usage=usage, description=description)
+ parser.add_option('-r', '--recursive', action='store_true',
+ default=False, dest='recursive',
+ help='Scan directories recursively')
+
+ options, args = parser.parse_args()
+ if len(args) != 3:
+ parser.print_usage()
+ exit(1)
+ relocator = OSXRelocator(args[1], args[2], options.recursive)
+ relocator.relocate_dir(args[0])
+ exit(0)
+
+
+if __name__ == "__main__":
+ main = Main()
+ main.run()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]