From 45d343e97599c1e38a886eac017d6add26e1d9fc Mon Sep 17 00:00:00 2001 From: Ian Rees Date: Sat, 23 Jan 2016 17:53:30 +1300 Subject: [PATCH 1/3] Prevent adding duplicate rpaths to bundled libs --- src/Tools/MakeMacBundleRelocatable.py | 63 +++++++++++++++++++++------ 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/src/Tools/MakeMacBundleRelocatable.py b/src/Tools/MakeMacBundleRelocatable.py index d44a94963..d5e85d18c 100644 --- a/src/Tools/MakeMacBundleRelocatable.py +++ b/src/Tools/MakeMacBundleRelocatable.py @@ -1,7 +1,8 @@ import os import sys -import subprocess +from subprocess import Popen, PIPE, check_call, check_output import pprint +import re SYS_PATHS = ["/System/", "/usr/lib/"] @@ -63,8 +64,9 @@ class DepsGraph: stack.append(ck) operation(self, self.graph[node_key], *op_args) + def is_macho(path): - output = subprocess.check_output(["file", path]) + output = check_output(["file", path]) if output.count("Mach-O") != 0: return True @@ -83,7 +85,7 @@ def get_path(name, search_paths): return None def list_install_names(path_macho): - output = subprocess.check_output(["otool", "-L", path_macho]) + output = check_output(["otool", "-L", path_macho]) lines = output.split("\t") libs = [] @@ -129,7 +131,7 @@ def create_dep_nodes(install_names, search_paths): path = get_path(lib_name, search_paths) if install_path != "" and lib[0] != "@": - #we have an absolte path install name + #we have an absolute path install name if not path: path = install_path @@ -148,7 +150,6 @@ def paths_at_depth(prefix, paths, depth): filtered.append(p) return filtered - def should_visit(prefix, path_filters, path): s_path = path.strip('/').split('/') filters = [] @@ -227,14 +228,44 @@ def in_bundle(lib, bundle_path): def copy_into_bundle(graph, node, bundle_path): if not in_bundle(node.path, bundle_path): - subprocess.check_call(["cp", "-L", os.path.join(node.path, node.name), - os.path.join(bundle_path, "lib", node.name)]) + check_call([ "cp", "-L", os.path.join(node.path, node.name), + os.path.join(bundle_path, "lib", node.name) ]) + node.path = os.path.join(bundle_path, "lib") #fix permissions - subprocess.check_call(["chmod", "a+w", os.path.join(bundle_path, - "lib", node.name)]) - + check_call([ "chmod", "a+w", + os.path.join(bundle_path, "lib", node.name) ]) + +def get_rpaths(library): + "Returns a list of rpaths specified within library" + + out = check_output(["otool", "-l", library]) + + pathRegex = r"^path (.*) \(offset \d+\)$" + expectingRpath = False + rpaths = [] + for line in out.split('\n'): + line = line.strip() + + if "cmd LC_RPATH" in line: + expectingRpath = True + continue + + if "Load command" in line: + expectingRpath = False + continue + + if not expectingRpath: + continue + + m = re.match(pathRegex, line) + if m: + rpaths.append(m.group(1)) + expectingRpath = False + + return rpaths + def add_rpaths(graph, node, bundle_path): if node.children: lib = os.path.join(node.path, node.name) @@ -245,8 +276,8 @@ def add_rpaths(graph, node, bundle_path): for install_name in install_names: name = os.path.basename(install_name) #change install names to use rpaths - subprocess.check_call(["install_name_tool", "-change", - install_name, "@rpath/" + name, lib]) + check_call([ "install_name_tool", "-change", + install_name, "@rpath/" + name, lib ]) dep_node = node.children[node.children.index(name)] rel_path = os.path.relpath(graph.get_node(dep_node).path, @@ -258,8 +289,12 @@ def add_rpaths(graph, node, bundle_path): rpath = "@loader_path/" + rel_path + "/" if rpath not in rpaths: rpaths.append(rpath) - for path in rpaths: - subprocess.call(["install_name_tool", "-add_rpath", path, lib]) + + for rpath in rpaths: + # Ensure that lib has rpath set + if not rpath in get_rpaths(lib): + check_output([ "install_name_tool", + "-add_rpath", rpath, lib ]) def main(): if len(sys.argv) < 2: From ada6ad5d89fa6325e76a6013cf2020a5b02a38bb Mon Sep 17 00:00:00 2001 From: Ian Rees Date: Sat, 23 Jan 2016 17:54:33 +1300 Subject: [PATCH 2/3] Add /Library/Frameworks/ to known system libraries Fixes issue where the 3Dconnexion drivers weren't found in relocateable mac application bundles. --- src/Tools/MakeMacBundleRelocatable.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tools/MakeMacBundleRelocatable.py b/src/Tools/MakeMacBundleRelocatable.py index d5e85d18c..3825034c0 100644 --- a/src/Tools/MakeMacBundleRelocatable.py +++ b/src/Tools/MakeMacBundleRelocatable.py @@ -4,7 +4,7 @@ from subprocess import Popen, PIPE, check_call, check_output import pprint import re -SYS_PATHS = ["/System/", "/usr/lib/"] +SYS_PATHS = ["/System/", "/usr/lib/", "/Library/Frameworks/"] class LibraryNotFound(Exception): pass From b5688aade5daaccbbaf1ed7e067ff858f9f4ab17 Mon Sep 17 00:00:00 2001 From: Ian Rees Date: Sat, 23 Jan 2016 19:16:06 +1300 Subject: [PATCH 3/3] Tidy logging (+whitespace) in Mac 3Dconnexion --- src/Gui/GuiApplicationNativeEventAware.cpp | 44 ++++++++++------------ src/Gui/GuiApplicationNativeEventAware.h | 23 +++++++---- 2 files changed, 35 insertions(+), 32 deletions(-) diff --git a/src/Gui/GuiApplicationNativeEventAware.cpp b/src/Gui/GuiApplicationNativeEventAware.cpp index 4f782d361..829572dc1 100644 --- a/src/Gui/GuiApplicationNativeEventAware.cpp +++ b/src/Gui/GuiApplicationNativeEventAware.cpp @@ -73,18 +73,14 @@ Gui::GUIApplicationNativeEventAware::~GUIApplicationNativeEventAware() #endif //mac #ifdef Q_WS_MACX - /* make sure the framework is installed */ - if (InstallConnexionHandlers == NULL) - { - Base::Console().Log("3Dconnexion framework not found!\n"); - return; - } - /* close the connection with the 3dx driver */ - //std::cerr << "tdxClientID: " << tdxClientID << std::endl; - if (tdxClientID) - UnregisterConnexionClient(tdxClientID); - CleanupConnexionHandlers(); - Base::Console().Log("Disconnected from 3DConnexion driver\n"); + // if 3Dconnexion library was loaded at runtime + if (InstallConnexionHandlers) { + // Close our connection with the 3dx driver + if (tdxClientID) + UnregisterConnexionClient(tdxClientID); + CleanupConnexionHandlers(); + Base::Console().Log("Disconnected from 3Dconnexion driver\n"); + } #endif #endif } @@ -123,33 +119,33 @@ void Gui::GUIApplicationNativeEventAware::initSpaceball(QMainWindow *window) OSStatus err; /* make sure the framework is installed */ if (InstallConnexionHandlers == NULL) - { + { Base::Console().Log("3Dconnexion framework not found!\n"); return; - } + } /* install 3dx message handler in order to receive driver events */ err = InstallConnexionHandlers(tdx_drv_handler, 0L, 0L); assert(err == 0); if (err) - { + { Base::Console().Log("Error installing 3Dconnexion handler\n"); return; - } + } /* register our app with the driver */ - //Pascal string Application name required to register driver for application + // Pascal string Application name required to register driver for application UInt8 tdxAppName[] = {7,'F','r','e','e','C','A','D'}; - //32bit appID to register driver for application + // 32bit appID to register driver for application UInt32 tdxAppID = 'FCAd'; - //std::cerr << "tdxClientID: " << tdxClientID << std::endl; - tdxClientID = RegisterConnexionClient(tdxAppID, tdxAppName, kConnexionClientModeTakeOver, kConnexionMaskAll); - //std::cerr << "tdxClientID: " << tdxClientID << std::endl; + tdxClientID = RegisterConnexionClient( tdxAppID, tdxAppName, + kConnexionClientModeTakeOver, + kConnexionMaskAll ); if (tdxClientID == 0) - { + { Base::Console().Log("Couldn't connect to 3Dconnexion driver\n"); return; - } + } - Base::Console().Log("3Dconnexion device initialized. Client ID: %d\n", tdxClientID); + Base::Console().Log("3Dconnexion driver initialized. Client ID: %d\n", tdxClientID); spaceballPresent = true; #endif #endif // _USE_3DCONNEXION_SDK diff --git a/src/Gui/GuiApplicationNativeEventAware.h b/src/Gui/GuiApplicationNativeEventAware.h index 243269f33..b52cb0576 100644 --- a/src/Gui/GuiApplicationNativeEventAware.h +++ b/src/Gui/GuiApplicationNativeEventAware.h @@ -46,9 +46,14 @@ class QMainWindow; #ifdef Q_WS_MACX #include #include -extern OSErr InstallConnexionHandlers(ConnexionMessageHandlerProc messageHandler, ConnexionAddedHandlerProc addedHandler, ConnexionRemovedHandlerProc removedHandler) - __attribute__((weak_import)); -extern UInt16 RegisterConnexionClient(UInt32 signature, UInt8 *name, UInt16 mode, UInt32 mask) __attribute__((weak_import)); +// Note that InstallConnexionHandlers will be replaced with +// SetConnexionHandlers "in the future". +extern OSErr InstallConnexionHandlers(ConnexionMessageHandlerProc messageHandler, + ConnexionAddedHandlerProc addedHandler, + ConnexionRemovedHandlerProc removedHandler) + __attribute__((weak_import)); +extern UInt16 RegisterConnexionClient(UInt32 signature, UInt8 *name, UInt16 mode, + UInt32 mask) __attribute__((weak_import)); extern void UnregisterConnexionClient(UInt16 clientID) __attribute__((weak_import)); extern void CleanupConnexionHandlers(void) __attribute__((weak_import)); #endif // Q_WS_MACX @@ -129,12 +134,14 @@ namespace Gui #endif // Q_WS_WIN #ifdef Q_WS_MACX private: - static UInt16 tdxClientID; /* ID assigned by the driver */ - static uint32_t lastButtons; + static UInt16 tdxClientID; /* ID assigned by the driver */ + static uint32_t lastButtons; public: - static void tdx_drv_handler(io_connect_t connection, natural_t messageType, void *messageArgument); - void Move3d(); - void Button3d(bool buttonDown, int buttonNumber); + static void tdx_drv_handler( io_connect_t connection, + natural_t messageType, + void *messageArgument ); + void Move3d(); + void Button3d(bool buttonDown, int buttonNumber); #endif// Q_WS_MACX #endif // _USE_3DCONNEXION_SDK