From 9fc71f9d7f6c5c6f228677defa27343c093db9d9 Mon Sep 17 00:00:00 2001 From: Eberhard Graether Date: Thu, 5 Feb 2015 11:48:39 +0100 Subject: [PATCH] build: fixed MacOS bundle to include all libraries and frameworks Follwed instructions for Qt from: http://qt-project.org/doc/qt-4.8/deployment-mac.html fortune cookie message = Smile! A smile will make you younger. --- CMakeLists.txt | 12 +++-- setup/MacOSX/bundle_install.sh.in | 54 ++++++++++++++++++--- src/app/main.cpp | 4 +- src/app/platform_includes/includes.h.in | 2 +- src/app/platform_includes/includesDefault.h | 2 +- src/app/platform_includes/includesMac.h | 15 +++++- src/app/platform_includes/includesWindows.h | 2 +- 7 files changed, 76 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 08ad50b5..eacc9e8d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,6 +108,7 @@ set(CMAKE_AUTOMOC ON) set(CMAKE_PREFIX_PATH "$ENV{QT_DIR}/") find_package(Qt5Widgets) +find_package(Qt5PrintSupport) add_executable(${APP_PROJECT_NAME} ${APP_FILES}) @@ -148,7 +149,7 @@ if (APPLE) set(MACOSX_BUNDLE_NAME ${PROJECT_NAME}) set(MACOSX_BINARY_NAME ${APP_PROJECT_NAME}) - set(MACOSX_DYNAMIC_LIBRARIES ${Boost_LIBRARIES}) + set(MACOSX_DYNAMIC_LIBRARIES ${Boost_LIBRARIES} "${LLVM_LIBRARY_DIRS}/libLTO.dylib") string(REPLACE ";" " " MACOSX_DYNAMIC_LIBRARIES "${MACOSX_DYNAMIC_LIBRARIES}") get_property(QT_CORE_PATH TARGET ${Qt5Core_LIBRARIES} PROPERTY LOCATION) @@ -160,8 +161,13 @@ if (APPLE) get_property(QT_WIDGETS_PATH TARGET ${Qt5Widgets_LIBRARIES} PROPERTY LOCATION) get_filename_component(QT_WIDGETS_PATH ${QT_WIDGETS_PATH} REALPATH) - list(APPEND MACOSX_FRAMEWORKS ${QT_CORE_PATH} ${QT_GUI_PATH} ${QT_WIDGETS_PATH}) - string(REPLACE ";" " " MACOSX_FRAMEWORKS "${MACOSX_FRAMEWORKS}") + get_property(QT_PRINT_PATH TARGET ${Qt5PrintSupport_LIBRARIES} PROPERTY LOCATION) + get_filename_component(QT_PRINT_PATH ${QT_PRINT_PATH} REALPATH) + + list(APPEND MACOSX_QT_FRAMEWORKS ${QT_CORE_PATH} ${QT_GUI_PATH} ${QT_WIDGETS_PATH} ${QT_PRINT_PATH}) + string(REPLACE ";" " " MACOSX_QT_FRAMEWORKS "${MACOSX_QT_FRAMEWORKS}") + + set(MACOSX_QT_DIR "$ENV{QT_DIR}") configure_file( ${PROJECT_SOURCE_DIR}/setup/MacOSX/bundle_install.sh.in diff --git a/setup/MacOSX/bundle_install.sh.in b/setup/MacOSX/bundle_install.sh.in index 5cd39939..4d15fb94 100755 --- a/setup/MacOSX/bundle_install.sh.in +++ b/setup/MacOSX/bundle_install.sh.in @@ -12,7 +12,9 @@ echo -e $INFO "Creating app bundle for MacOSX." BUNDLE_NAME="@MACOSX_BUNDLE_NAME@" APP_NAME="@MACOSX_BINARY_NAME@" DYNLIB_PATHS=(@MACOSX_DYNAMIC_LIBRARIES@) -FRAMEWORK_PATHS=(@MACOSX_FRAMEWORKS@) + +QT_DIR="@MACOSX_QT_DIR@" +QT_FRAMEWORK_PATHS=(@MACOSX_QT_FRAMEWORKS@) if [ ! -x "$APP_NAME" ] then @@ -29,6 +31,7 @@ fi BUNDLE_PATH=$BUNDLE_NAME.app BIN_DIR=$BUNDLE_PATH/Contents/MacOS DYNLIB_DIR=$BUNDLE_PATH/Contents/lib +PLUGIN_DIR=$BUNDLE_PATH/Contents/PlugIns/platforms FRAMEWORK_DIR=$BUNDLE_PATH/Contents/Frameworks RES_DIR=$BUNDLE_PATH/Contents/Resources APP_PATH=$BIN_DIR/$APP_NAME @@ -42,37 +45,76 @@ fi echo -e $INFO "Creating bundle folders." mkdir -p $BIN_DIR mkdir -p $DYNLIB_DIR +mkdir -p $PLUGIN_DIR mkdir -p $FRAMEWORK_DIR mkdir -p $RES_DIR + echo -e $INFO "Copying bundle contents." cp $APP_NAME $APP_PATH cp bundle_info.plist $BUNDLE_PATH/Contents/Info.plist cp -R ../data $RES_DIR/data + echo -e $INFO "Copying dynamic libraries." for LIB_PATH in ${DYNLIB_PATHS[@]} do LIB_NAME=$(basename $LIB_PATH) cp $LIB_PATH $DYNLIB_DIR/$LIB_NAME - install_name_tool -change $LIB_NAME @executable_path/../lib/$LIB_NAME $APP_PATH - echo $LIB_PATH $LIB_NAME + install_name_tool -change $LIB_NAME @executable_path/../lib/$LIB_NAME $APP_PATH + install_name_tool -change @rpath/$LIB_NAME @executable_path/../lib/$LIB_NAME $APP_PATH + + echo "lib" $LIB_PATH $LIB_NAME done +echo -e $INFO "Fixing lib dependencies" +install_name_tool -change libboost_system.dylib @executable_path/../lib/libboost_system.dylib $DYNLIB_DIR/libboost_filesystem.dylib +otool -L $DYNLIB_DIR/libboost_filesystem.dylib + + +echo -e $INFO "Copying Plugins" +cp $QT_DIR/plugins/platforms/libqcocoa.dylib $PLUGIN_DIR/libqcocoa.dylib + + echo -e $INFO "Copying frameworks." -for FRAMEWORK_BIN_PATH in ${FRAMEWORK_PATHS[@]} +for FRAMEWORK_BIN_PATH in ${QT_FRAMEWORK_PATHS[@]} do FRAMEWORK_PATH=$(echo $FRAMEWORK_BIN_PATH | grep -o "\S*.framework") FRAMEWORK_NAME=$(echo $FRAMEWORK_BIN_PATH | grep -o "\w*.framework") cp -R $FRAMEWORK_PATH $FRAMEWORK_DIR/$FRAMEWORK_NAME FRAMEWORK_SUB_PATH=$(echo $FRAMEWORK_BIN_PATH | grep -o "\w*.framework\S*") - install_name_tool -change $FRAMEWORK_BIN_PATH @loader_path/../Frameworks/$FRAMEWORK_SUB_PATH $APP_PATH + install_name_tool -id @executable_path/../Frameworks/$FRAMEWORK_SUB_PATH $FRAMEWORK_DIR/$FRAMEWORK_SUB_PATH + install_name_tool -change $FRAMEWORK_BIN_PATH @executable_path/../Frameworks/$FRAMEWORK_SUB_PATH $APP_PATH - echo $FRAMEWORK_BIN_PATH $FRAMEWORK_PATH + echo "framework" $FRAMEWORK_BIN_PATH $FRAMEWORK_PATH done +# http://qt-project.org/doc/qt-4.8/deployment-mac.html +echo -e $INFO "Fixing framework dependencies" + +install_name_tool -change $QT_DIR/lib/QtCore.framework/Versions/5/QtCore @executable_path/../Frameworks/QtCore.framework/Versions/5/QtCore $FRAMEWORK_DIR/QtGui.framework/Versions/5/QtGui +install_name_tool -change $QT_DIR/lib/QtCore.framework/Versions/5/QtCore @executable_path/../Frameworks/QtCore.framework/Versions/5/QtCore $FRAMEWORK_DIR/QtWidgets.framework/Versions/5/QtWidgets +install_name_tool -change $QT_DIR/lib/QtGui.framework/Versions/5/QtGui @executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui $FRAMEWORK_DIR/QtWidgets.framework/Versions/5/QtWidgets + +install_name_tool -change $QT_DIR/lib/QtCore.framework/Versions/5/QtCore @executable_path/../Frameworks/QtCore.framework/Versions/5/QtCore $FRAMEWORK_DIR/QtPrintSupport.framework/Versions/5/QtPrintSupport +install_name_tool -change $QT_DIR/lib/QtGui.framework/Versions/5/QtGui @executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui $FRAMEWORK_DIR/QtPrintSupport.framework/Versions/5/QtPrintSupport +install_name_tool -change $QT_DIR/lib/QtWidgets.framework/Versions/5/QtWidgets @executable_path/../Frameworks/QtWidgets.framework/Versions/5/QtWidgets $FRAMEWORK_DIR/QtPrintSupport.framework/Versions/5/QtPrintSupport + +install_name_tool -change $QT_DIR/lib/QtCore.framework/Versions/5/QtCore @executable_path/../Frameworks/QtCore.framework/Versions/5/QtCore $PLUGIN_DIR/libqcocoa.dylib +install_name_tool -change $QT_DIR/lib/QtGui.framework/Versions/5/QtGui @executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui $PLUGIN_DIR/libqcocoa.dylib +install_name_tool -change $QT_DIR/lib/QtWidgets.framework/Versions/5/QtWidgets @executable_path/../Frameworks/QtWidgets.framework/Versions/5/QtWidgets $PLUGIN_DIR/libqcocoa.dylib +install_name_tool -change $QT_DIR/lib/QtPrintSupport.framework/Versions/5/QtPrintSupport @executable_path/../Frameworks/QtPrintSupport.framework/Versions/5/QtPrintSupport $PLUGIN_DIR/libqcocoa.dylib + +otool -L $FRAMEWORK_DIR/QtCore.framework/Versions/5/QtCore +otool -L $FRAMEWORK_DIR/QtGui.framework/Versions/5/QtGui +otool -L $FRAMEWORK_DIR/QtWidgets.framework/Versions/5/QtWidgets +otool -L $FRAMEWORK_DIR/QtPrintSupport.framework/Versions/5/QtPrintSupport +otool -L $PLUGIN_DIR/libqcocoa.dylib + + +echo -e $INFO "App dependencies" otool -L $APP_PATH echo -e $SUCCESS "Installed bundle successfully!" diff --git a/src/app/main.cpp b/src/app/main.cpp index 6a61cfc0..678bef90 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -3,7 +3,7 @@ #include #include "Application.h" -#include "includes.h" // defines 'void setup()' +#include "includes.h" // defines 'void setup(int argc, char *argv[])' #include "qt/utility/utilityQt.h" #include "qt/view/QtViewFactory.h" #include "utility/logging/ConsoleLogger.h" @@ -20,7 +20,7 @@ void init() int main(int argc, char *argv[]) { - setup(); + setup(argc, argv); QApplication qtApp(argc, argv); diff --git a/src/app/platform_includes/includes.h.in b/src/app/platform_includes/includes.h.in index 24636dce..6cd54e64 100644 --- a/src/app/platform_includes/includes.h.in +++ b/src/app/platform_includes/includes.h.in @@ -1,7 +1,7 @@ #ifndef INCLUDES_H #define INCLUDES_H -void setup(); +void setup(int argc, char *argv[]); // platform specific include #include "platform_includes/@PLATFORM_INCLUDE@" diff --git a/src/app/platform_includes/includesDefault.h b/src/app/platform_includes/includesDefault.h index 88535638..2aa5c7c8 100644 --- a/src/app/platform_includes/includesDefault.h +++ b/src/app/platform_includes/includesDefault.h @@ -1,7 +1,7 @@ #ifndef INCLUDES_DEFAULT_H #define INCLUDES_DEFAULT_H -void setup() +void setup(int argc, char *argv[]) { } diff --git a/src/app/platform_includes/includesMac.h b/src/app/platform_includes/includesMac.h index ffaa0e31..6c00e725 100644 --- a/src/app/platform_includes/includesMac.h +++ b/src/app/platform_includes/includesMac.h @@ -2,8 +2,9 @@ #define INCLUDES_MAC_H #include +#include -void setup() +void setup(int argc, char *argv[]) { // ---------------------------------------------------------------------------- // This makes relative paths work in C++ in Xcode by changing directory to the Resources folder inside the .app bundle @@ -29,6 +30,18 @@ void setup() } CFRelease(resourcesURL); // ---------------------------------------------------------------------------- + + + // ---------------------------------------------------------------------------- + // This makes the mac bundle search in the right place for the cocoa plugin + // source: http://qt-project.org/doc/qt-4.8/deployment-mac.html + QDir dir(argv[0]); + if (dir.cd("../../PlugIns")) + { + QCoreApplication::setLibraryPaths(QStringList(dir.absolutePath())); + // printf("after change, libraryPaths=(%s)\n", QCoreApplication::libraryPaths().join(",").toUtf8().data()); + } + // ---------------------------------------------------------------------------- } #endif // INCLUDES_MAC_H diff --git a/src/app/platform_includes/includesWindows.h b/src/app/platform_includes/includesWindows.h index 302fcc5c..6b066be3 100644 --- a/src/app/platform_includes/includesWindows.h +++ b/src/app/platform_includes/includesWindows.h @@ -3,7 +3,7 @@ #include "vld.h" -void setup() +void setup(int argc, char *argv[]) { }