diff --git a/admin/osx/macdeployqt.py b/admin/osx/macdeployqt.py deleted file mode 100755 index fbf4a1952..000000000 --- a/admin/osx/macdeployqt.py +++ /dev/null @@ -1,366 +0,0 @@ -#!/usr/bin/python -# This file is part of ownCloud. -# It was inspired in large part by the macdeploy script in Clementine -# and Tomahawk -# -# ownCloud is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# ownCLoud 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with ownCloud. If not, see . - -from __future__ import print_function -import os -import re -import subprocess -import commands -import sys -from glob import glob -from distutils.version import LooseVersion - -def QueryQMake(attrib): - return subprocess.check_output([qmake_path, '-query', attrib]).rstrip('\n') - -FRAMEWORK_SEARCH_PATH=[ - '/Library/Frameworks', - os.path.join(os.environ['HOME'], 'Library/Frameworks') -] - -LIBRARY_SEARCH_PATH=['/usr/local/lib', '/usr/local/Qt-5.12.5/lib', '.'] - -QT_PLUGINS = [ - 'sqldrivers/libqsqlite.dylib', - 'platforms/libqcocoa.dylib', - 'styles/libqmacstyle.dylib', - 'imageformats/libqgif.dylib', - 'imageformats/libqico.dylib', - 'imageformats/libqjpeg.dylib', - 'imageformats/libqsvg.dylib', -] - -QT_PLUGINS_SEARCH_PATH=[ -# os.path.join(os.environ['QTDIR'], 'plugins'), -# '/usr/local/Cellar/qt/5.2.1/plugins', - '/usr/local/Qt-5.12.5/plugins', -] - - -class Error(Exception): - pass - - -class CouldNotFindQtPluginErrorFindFrameworkError(Error): - pass - - -class InstallNameToolError(Error): - pass - - -class CouldNotFindQtPluginError(Error): - pass - - -class CouldNotFindScriptPluginError(Error): - pass - -class CouldNotFindFrameworkError(Error): - pass - -if len(sys.argv) < 3: - print('Usage: %s ' % sys.argv[0]) - exit() - -def is_exe(fpath): - return os.path.isfile(fpath) and os.access(fpath, os.X_OK) - -bundle_dir = sys.argv[1] -qmake_path = sys.argv[2] - -bundle_name = os.path.basename(bundle_dir).split('.')[0] - -commands = [] - -binary_dir = os.path.join(bundle_dir, 'Contents', 'MacOS') -frameworks_dir = os.path.join(bundle_dir, 'Contents', 'Frameworks') -commands.append(['mkdir', '-p', frameworks_dir]) -resources_dir = os.path.join(bundle_dir, 'Contents', 'Resources') -commands.append(['mkdir', '-p', resources_dir]) -plugins_dir = os.path.join(bundle_dir, 'Contents', 'PlugIns') -binaries = [i for i in glob(os.path.join(bundle_dir, 'Contents', 'MacOS', "*")) if is_exe(i)]; - -qt_version = QueryQMake('QT_VERSION') -print("Using Qt", qt_version) - -fixed_libraries = [] -fixed_frameworks = [] - -def WriteQtConf(): - print("Writing qt.conf...") - with open(os.path.join(resources_dir, 'qt.conf'), 'w') as f: - f.write("[Paths]\nPlugins = PlugIns\n"); - f.close() - -def GetBrokenLibraries(binary): - #print "Checking libs for binary: %s" % binary - output = subprocess.Popen(['otool', '-L', binary], stdout=subprocess.PIPE).communicate()[0] - broken_libs = { - 'frameworks': [], - 'libs': []} - for line in [x.split(' ')[0].lstrip() for x in output.split('\n')[1:]]: - #print "Checking line: %s" % line - if not line: # skip empty lines - continue - if os.path.basename(binary) == os.path.basename(line): - #print "mnope %s-%s" % (os.path.basename(binary), os.path.basename(line)) - continue - if re.match(r'^\s*/System/', line): - continue # System framework - elif re.match(r'^\s*/usr/lib/', line): - #print "unix style system lib" - continue # unix style system library - elif re.match(r'Breakpad', line): - continue # Manually added by cmake. - elif re.match(r'^\s*@executable_path', line) or re.match(r'^\s*@loader_path', line): - # Potentially already fixed library - if '.framework' in line: - relative_path = os.path.join(*line.split('/')[3:]) - if not os.path.exists(os.path.join(frameworks_dir, relative_path)): - broken_libs['frameworks'].append(relative_path) - else: - relative_path = os.path.join(*line.split('/')[1:]) - #print "RELPATH %s %s" % (relative_path, os.path.join(binary_dir, relative_path)) - if not os.path.exists(os.path.join(binary_dir, relative_path)): - broken_libs['libs'].append(relative_path) - elif re.search(r'\w+\.framework', line): - broken_libs['frameworks'].append(line) - else: - broken_libs['libs'].append(line) - - return broken_libs - -def FindFramework(path): - search_pathes = FRAMEWORK_SEARCH_PATH - search_pathes.insert(0, QueryQMake('QT_INSTALL_LIBS')) - for search_path in search_pathes: - # The following two lines are needed for a custom built Qt from version 5.5 on, possibly not for the one from the Qt SDK. - # Looks like the upstream macdeployqt also had an issue there https://bugreports.qt.io/browse/QTBUG-47868 - if path.find( "\@rpath/"): - path = path.replace("@rpath/", "") - abs_path = os.path.join(search_path, path) - if os.path.exists(abs_path): - return abs_path - - raise CouldNotFindFrameworkError(path) - -def FindLibrary(path): - if os.path.exists(path): - return path - search_pathes = LIBRARY_SEARCH_PATH - search_pathes.insert(0, QueryQMake('QT_INSTALL_LIBS')) - for search_path in search_pathes: - abs_path = os.path.join(search_path, path) - if os.path.exists(abs_path): - return abs_path - else: # try harder---look for lib name in library folders - newpath = os.path.join(search_path,os.path.basename(path)) - if os.path.exists(newpath): - return newpath - - return "" - #raise CouldNotFindFrameworkError(path) - -def FixAllLibraries(broken_libs): - for framework in broken_libs['frameworks']: - FixFramework(framework) - for lib in broken_libs['libs']: - FixLibrary(lib) - -def FixFramework(path): - if path in fixed_libraries: - return - else: - fixed_libraries.append(path) - abs_path = FindFramework(path) - broken_libs = GetBrokenLibraries(abs_path) - FixAllLibraries(broken_libs) - - new_path = CopyFramework(abs_path) - id = os.sep.join(new_path.split(os.sep)[3:]) - FixFrameworkId(new_path, id) - for framework in broken_libs['frameworks']: - FixFrameworkInstallPath(framework, new_path) - for library in broken_libs['libs']: - FixLibraryInstallPath(library, new_path) - -def FixLibrary(path): - if path in fixed_libraries or FindSystemLibrary(os.path.basename(path)) is not None: - return - else: - fixed_libraries.append(path) - abs_path = FindLibrary(path) - if abs_path == "": - print("Could not resolve %s, not fixing!" % path) - return - broken_libs = GetBrokenLibraries(abs_path) - FixAllLibraries(broken_libs) - - new_path = CopyLibrary(abs_path) - FixLibraryId(new_path) - for framework in broken_libs['frameworks']: - FixFrameworkInstallPath(framework, new_path) - for library in broken_libs['libs']: - FixLibraryInstallPath(library, new_path) - -def FixPlugin(abs_path, subdir): - broken_libs = GetBrokenLibraries(abs_path) - FixAllLibraries(broken_libs) - - new_path = CopyPlugin(abs_path, subdir) - for framework in broken_libs['frameworks']: - FixFrameworkInstallPath(framework, new_path) - for library in broken_libs['libs']: - FixLibraryInstallPath(library, new_path) - -def FixBinary(path): - broken_libs = GetBrokenLibraries(path) - FixAllLibraries(broken_libs) - for framework in broken_libs['frameworks']: - FixFrameworkInstallPath(framework, path) - for library in broken_libs['libs']: - FixLibraryInstallPath(library, path) - -def CopyLibrary(path): - new_path = os.path.join(binary_dir, os.path.basename(path)) - args = ['ditto', '--arch=x86_64', path, new_path] - commands.append(args) - args = ['chmod', 'u+w', new_path] - commands.append(args) - return new_path - -def CopyPlugin(path, subdir): - new_path = os.path.join(plugins_dir, subdir, os.path.basename(path)) - args = ['mkdir', '-p', os.path.dirname(new_path)] - commands.append(args) - args = ['ditto', '--arch=x86_64', path, new_path] - commands.append(args) - args = ['chmod', 'u+w', new_path] - commands.append(args) - return new_path - -def CopyFramework(source_dylib): - parts = source_dylib.split(os.sep) - print("CopyFramework:", source_dylib) - for i, part in enumerate(parts): - matchObj = re.match(r'(\w+\.framework)', part) - if matchObj: - framework = matchObj.group(1) - dylib_name = parts[-1] - source_path = os.path.join('/', *parts[:i+1]) - dest_path = os.path.join(frameworks_dir, framework) - dest_dylib_path = os.path.join(frameworks_dir, *parts[i:-1]) - break -# if os.path.exists(dest_path): -# print dest_path, "already exists, skipping copy..." -# return os.path.join(dest_dylib_path, dylib_name) - - args = ['mkdir', '-p', dest_dylib_path] - commands.append(args) - args = ['ditto', '--arch=x86_64', source_dylib, dest_dylib_path] - commands.append(args) - args = ['chmod', 'u+w', os.path.join(dest_dylib_path, parts[-1])] - commands.append(args) - args = ['ln', '-s', '5', os.path.join(dest_path, 'Versions', 'Current')] - commands.append(args) - args = ['ln', '-s', os.path.join('Versions', 'Current', dylib_name), os.path.join(dest_path, dylib_name)] - commands.append(args) - args = ['ln', '-s', os.path.join('Versions', 'Current', 'Resources'), os.path.join(dest_path, 'Resources')] - commands.append(args) - args = ['cp', '-r', os.path.join(source_path, 'Versions', '5', 'Resources'), os.path.join(dest_path, 'Versions', '5')] - commands.append(args) - args = ['ln', '-s', os.path.join('Versions', 'Current', 'Helpers'), os.path.join(dest_path, 'Helpers')] - commands.append(args) - args = ['cp', '-r', os.path.join(source_path, 'Versions', '5', 'Helpers'), os.path.join(dest_path, 'Versions', '5')] - commands.append(args) - - return os.path.join(dest_dylib_path, dylib_name) - -def FixId(path, library_name): - id = '@executable_path/../Frameworks/%s' % library_name - args = ['install_name_tool', '-id', id, path] - commands.append(args) - -def FixLibraryId(path): - library_name = os.path.basename(path) - FixId(path, library_name) - -def FixFrameworkId(path, id): - FixId(path, id) - -def FixInstallPath(library_path, library, new_path): - args = ['install_name_tool', '-change', library_path, new_path, library] - commands.append(args) - -def FindSystemLibrary(library_name): - for path in ['/lib', '/usr/lib']: - full_path = os.path.join(path, library_name) - if os.path.exists(full_path): - return full_path - return None - -def FixLibraryInstallPath(library_path, library): - system_library = FindSystemLibrary(os.path.basename(library_path)) - if system_library is None: - new_path = '@executable_path/../MacOS/%s' % os.path.basename(library_path) - FixInstallPath(library_path, library, new_path) - else: - FixInstallPath(library_path, library, system_library) - -def FixFrameworkInstallPath(library_path, library): - parts = library_path.split(os.sep) - for i, part in enumerate(parts): - if re.match(r'\w+\.framework', part): - full_path = os.path.join(*parts[i:]) - break - new_path = '@executable_path/../Frameworks/%s' % full_path - FixInstallPath(library_path, library, new_path) - -def FindQtPlugin(name): - search_path = QT_PLUGINS_SEARCH_PATH - search_path.insert(0, QueryQMake('QT_INSTALL_PLUGINS')) - for path in search_path: - if os.path.exists(path): - if os.path.exists(os.path.join(path, name)): - return os.path.join(path, name) - raise CouldNotFindQtPluginError(name) - -for binary in binaries: - FixBinary(binary) - -for plugin in QT_PLUGINS: - FixPlugin(FindQtPlugin(plugin), os.path.dirname(plugin)) - -if LooseVersion(qt_version) >= LooseVersion("5.10.0"): - args = ['plutil', '-insert', 'LSMinimumSystemVersion', '-string', '10.10.0', os.path.join(bundle_dir, 'Contents', 'Info.plist')] - commands.append(args) -else: - args = ['plutil', '-insert', 'LSMinimumSystemVersion', '-string', '10.7.0', os.path.join(bundle_dir, 'Contents', 'Info.plist')] - commands.append(args) - -if len(sys.argv) <= 2: - print('Will run %d commands:' % len(commands)) - for command in commands: - print(' '.join(command)) - -for command in commands: - p = subprocess.Popen(command) - os.waitpid(p.pid, 0) - -WriteQtConf() diff --git a/src/cmd/CMakeLists.txt b/src/cmd/CMakeLists.txt index 6b0d0b0dc..722fc1284 100644 --- a/src/cmd/CMakeLists.txt +++ b/src/cmd/CMakeLists.txt @@ -46,10 +46,15 @@ endif() # currently it needs to be done because the code right above needs to be executed no matter # if building a bundle or not and the install_qt4_executable needs to be called afterwards if(BUILD_OWNCLOUD_OSX_BUNDLE AND NOT BUILD_LIBRARIES_ONLY) - get_target_property (QT_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION) - install(CODE " - message(STATUS \"Deploying (Qt) dependencies and fixing library paths...\") - execute_process(COMMAND \"${CMAKE_SOURCE_DIR}/admin/osx/macdeployqt.py\" ${CMAKE_INSTALL_PREFIX}/${OWNCLOUD_OSX_BUNDLE} ${QT_QMAKE_EXECUTABLE}) - execute_process(COMMAND \"${CMAKE_SOURCE_DIR}/admin/osx/macdeployqt.py\" ${CMAKE_INSTALL_PREFIX}/${OWNCLOUD_OSX_BUNDLE}/Contents/Frameworks/QtWebEngineCore.framework/Helpers/QtWebEngineProcess.app ${QT_QMAKE_EXECUTABLE}) - " COMPONENT RUNTIME) + get_target_property (QT_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION) + get_filename_component(QT_BIN_DIR "${QT_QMAKE_EXECUTABLE}" DIRECTORY) + find_program(MACDEPLOYQT_EXECUTABLE macdeployqt HINTS "${QT_BIN_DIR}") + + add_custom_command(TARGET ${cmd_NAME} POST_BUILD + COMMAND "${MACDEPLOYQT_EXECUTABLE}" + "$/../.." + -qmldir=${CMAKE_SOURCE_DIR}/src/gui + -always-overwrite + COMMENT "Running macdeployqt..." + ) endif() diff --git a/src/crashreporter/CMakeLists.txt b/src/crashreporter/CMakeLists.txt index 57043f6ff..eb68418dc 100644 --- a/src/crashreporter/CMakeLists.txt +++ b/src/crashreporter/CMakeLists.txt @@ -49,11 +49,16 @@ if(NOT BUILD_LIBRARIES_ONLY) # currently it needs to be done because the code right above needs to be executed no matter # if building a bundle or not and the install_qt4_executable needs to be called afterwards if(BUILD_OWNCLOUD_OSX_BUNDLE) - get_target_property (QT_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION) - install(CODE " - message(STATUS \"Deploying (Qt) dependencies and fixing library paths...\") - execute_process(COMMAND \"${CMAKE_SOURCE_DIR}/admin/osx/macdeployqt.py\" ${CMAKE_INSTALL_PREFIX}/${OWNCLOUD_OSX_BUNDLE} ${QT_QMAKE_EXECUTABLE}) - execute_process(COMMAND \"${CMAKE_SOURCE_DIR}/admin/osx/macdeployqt.py\" ${CMAKE_INSTALL_PREFIX}/${OWNCLOUD_OSX_BUNDLE}/Contents/Frameworks/QtWebEngineCore.framework/Helpers/QtWebEngineProcess.app ${QT_QMAKE_EXECUTABLE}) - " COMPONENT RUNTIME) + get_target_property (QT_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION) + get_filename_component(QT_BIN_DIR "${QT_QMAKE_EXECUTABLE}" DIRECTORY) + find_program(MACDEPLOYQT_EXECUTABLE macdeployqt HINTS "${QT_BIN_DIR}") + + add_custom_command(TARGET ${CRASHREPORTER_EXECUTABLE} POST_BUILD + COMMAND "${MACDEPLOYQT_EXECUTABLE}" + "$/../.." + -qmldir=${CMAKE_SOURCE_DIR}/src/gui + -always-overwrite + COMMENT "Running macdeployqt..." + ) endif() endif() diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 93f63450e..ed17270cb 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -389,12 +389,17 @@ install(TARGETS ${APPLICATION_EXECUTABLE} # currently it needs to be done because the code right above needs to be executed no matter # if building a bundle or not and the install_qt4_executable needs to be called afterwards if(BUILD_OWNCLOUD_OSX_BUNDLE AND NOT BUILD_LIBRARIES_ONLY) - get_target_property (QT_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION) - install(CODE " - message(STATUS \"Deploying (Qt) dependencies and fixing library paths...\") - execute_process(COMMAND \"${CMAKE_SOURCE_DIR}/admin/osx/macdeployqt.py\" ${CMAKE_INSTALL_PREFIX}/${OWNCLOUD_OSX_BUNDLE} ${QT_QMAKE_EXECUTABLE}) - execute_process(COMMAND \"${CMAKE_SOURCE_DIR}/admin/osx/macdeployqt.py\" ${CMAKE_INSTALL_PREFIX}/${OWNCLOUD_OSX_BUNDLE}/Contents/Frameworks/QtWebEngineCore.framework/Helpers/QtWebEngineProcess.app ${QT_QMAKE_EXECUTABLE}) - " COMPONENT RUNTIME) + get_target_property (QT_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION) + get_filename_component(QT_BIN_DIR "${QT_QMAKE_EXECUTABLE}" DIRECTORY) + find_program(MACDEPLOYQT_EXECUTABLE macdeployqt HINTS "${QT_BIN_DIR}") + + add_custom_command(TARGET ${APPLICATION_EXECUTABLE} POST_BUILD + COMMAND "${MACDEPLOYQT_EXECUTABLE}" + "$/../.." + -qmldir=${CMAKE_SOURCE_DIR}/src/gui + -always-overwrite + COMMENT "Running macdeployqt..." + ) endif() if(NOT BUILD_OWNCLOUD_OSX_BUNDLE AND NOT WIN32)