From 5435e6477ec0b981e4fb91a53ab1372a60a610af Mon Sep 17 00:00:00 2001 From: Mohcine Chraibi <m.chraibi@fz-juelich.de> Date: Fri, 11 Nov 2016 16:37:11 +0100 Subject: [PATCH] bundle fixup: Deploy in OSX this file should be refactord --- CMakeLists.txt | 85 +++++++++++++++---------------------- Resources/dmg.json | 10 +++++ checkDependencies.py | 46 ++++++++++++++++++++ deployAPPLE.sh | 42 +++++++++++++++--- install_packages_debian.txt | 2 +- 5 files changed, 128 insertions(+), 57 deletions(-) create mode 100644 Resources/dmg.json create mode 100644 checkDependencies.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 2dbaf41..a650d8d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,7 +51,7 @@ message (STATUS "MODULE_PATH: " ${CMAKE_MODULE_PATH}) set(CMAKE_COLOR_MAKEFILE ON) set(JPSVIS_MAJOR_VERSION 0) set(JPSVIS_MINOR_VERSION 8) -set(JPSVIS_PATCH_VERSION 0) +set(JPSVIS_PATCH_VERSION 1) set(JPSVIS_VERSION ${JPSVIS_MAJOR_VERSION}.${JPSVIS_MINOR_VERSION}.${JPSVIS_PATCH_VERSION}) message( STATUS "JPSVIS_VERSION: " ${JPSVIS_VERSION} ) @@ -63,7 +63,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(README_FILE "${CMAKE_SOURCE_DIR}/README.md") if(APPLE AND CMAKE_INSTALL_PREFIX MATCHES "/usr/local") - set(CMAKE_INSTALL_PREFIX "/Applications") + set(CMAKE_INSTALL_PREFIX ${EXECUTABLE_OUTPUT_PATH}) #"/Applications") endif() message(STATUS "${PROJECT_NAME} will be installed to ${CMAKE_INSTALL_PREFIX}") @@ -304,35 +304,15 @@ elseif( ${QT5_INSTALLED}) ${UI_HDRS} ${RCS} ) - qt5_use_modules(JPSvis Widgets) - target_link_libraries(JPSvis Qt5::Xml) - target_link_libraries(JPSvis Qt5::Network) - target_link_libraries(JPSvis ${Qt5Widgets_LIBRARIES}) + qt5_use_modules(jpsvis Widgets) + target_link_libraries(jpsvis Qt5::Xml) + target_link_libraries(jpsvis Qt5::Network) + target_link_libraries(jpsvis ${Qt5Widgets_LIBRARIES}) else() message(FATAL_ERROR "QT NOT FOUND - ABORT") endif() -#====================================================================== -# debug where is python? -# foreach(REQUIRED_PYTHON_VERSION 2.7) # 2.6 2.5) -# message(STATUS "======== LOOKING FOR ${REQUIRED_PYTHON_VERSION} ========================") -# # find_package ( PythonInterp ${REQUIRED_PYTHON_VERSION} REQUIRED) -# # find_package ( PythonLibs ${PYTHON_VERSION_STRING} EXACT) -# # find_package ( PythonLibs ${PYTHON_VERSION_STRING} EXACT REQUIRED ) - - -# message(STATUS "PYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}") -# message(STATUS "PYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY}") -# message(STATUS "PYTHON_INCLUDE_DIR:FILEPATH=${PYTHON_INCLUDE_DIR}") -# message(STATUS "PYTHON_FRAMEWORK_INCLUDES=${PYTHON_FRAMEWORK_INCLUDES}") -# message(STATUS "PYTHONLIBS_VERSION_STRING=${PYTHONLIBS_VERSION_STRING}") -# message(STATUS "Python_FRAMEWORKS=${Python_FRAMEWORKS}") - -# # unset(PYTHON_EXECUTABLE CACHE) -# # unset(PYTHON_LIBRARY CACHE) -# # unset(PYTHON_INCLUDE_DIR CACHE) -# endforeach() # For Apple set the icns file containing icons @@ -424,8 +404,8 @@ SET(plugin_dest_dir bin) SET(qtconf_dest_dir bin) SET(APPS "\${CMAKE_INSTALL_PREFIX}/bin/jpsvis") IF(APPLE) - SET(plugin_dest_dir JPSvis.app/Contents/MacOS) - SET(qtconf_dest_dir JPSvis.app/Contents/Resources) + SET(plugin_dest_dir ${CMAKE_INSTALL_PREFIX}/jpsvis.app/Contents/MacOS) + SET(qtconf_dest_dir ${CMAKE_INSTALL_PREFIX}/jpsvis.app/Contents/Resources) SET(APPS "\${CMAKE_INSTALL_PREFIX}/jpsvis.app") ENDIF(APPLE) @@ -471,12 +451,13 @@ SET(DIRS ${QT_LIBRARY_DIRS}) # An alternative is the do a configure_file() on a script and use install(SCRIPT ...). # Note that the image plugins depend on QtSvg and QtXml, and it got those copied # over. -INSTALL(CODE " - file(GLOB_RECURSE QTPLUGINS - \"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/plugins/*${CMAKE_SHARED_LIBRARY_SUFFIX}\") - include(BundleUtilities) - fixup_bundle(\"${APPS}\" \"\${QTPLUGINS}\" \"${DIRS}\") - " COMPONENT Runtime) +# needed? +# INSTALL(CODE " +# file(GLOB_RECURSE QTPLUGINS +# \"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/plugins/*${CMAKE_SHARED_LIBRARY_SUFFIX}\") +# include(BundleUtilities) +# fixup_bundle(\"${APPS}\" \"\${QTPLUGINS}\" \"${DIRS}\") +# " COMPONENT Runtime) IF(APPLE) @@ -504,10 +485,10 @@ set(CPACK_BINARY_DRAGNDROP ON) set(CPACK_PACKAGE_NAME "jpsvis") set(CPACK_PACKAGE_VENDOR "www.jupedsim.org") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "jpsvis - CPack Component Installation Example") -set(CPACK_PACKAGE_VERSION "1.0.0") -set(CPACK_PACKAGE_VERSION_MAJOR "1") -set(CPACK_PACKAGE_VERSION_MINOR "0") -set(CPACK_PACKAGE_VERSION_PATCH "0") +set(CPACK_PACKAGE_VERSION ${JPSVIS_VERSION}) +set(CPACK_PACKAGE_VERSION_MAJOR ${JPSVIS_MAJOR_VERSION}) +set(CPACK_PACKAGE_VERSION_MINOR ${JPSVIS_MINOR_VERSION}) +set(CPACK_PACKAGE_VERSION_PATCH ${JPSVIS_PATCH_VERSION}) set(CPACK_PACKAGE_INSTALL_DIRECTORY "JPSvis_dir") if(APPLE) @@ -539,19 +520,21 @@ else() endif() # https://github.com/artm/vision-ui-skeleton/blob/master/cmake/QArtmRelease.cmake - IF(APPLE) - SET(EXE_CONTENTS "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE}/Contents") - FILE(WRITE - ${EXE_CONTENTS}/Resources/qt.conf - "[Paths]\nPlugins=PlugIns\n") - FILE(COPY ${QT_PLUGINS_DIR}/imageformats - DESTINATION ${EXE_CONTENTS}/PlugIns/ - PATTERN "*_debug.*" EXCLUDE) - ADD_CUSTOM_COMMAND( - TARGET ${PROJECT_NAME} POST_BUILD - COMMAND ruby ${PROJECT_SOURCE_DIR}/ruby/fixup/fixup.rb ${EXECUTABLE} - COMMENT "Fixing up the app bundle") - ENDIF(APPLE) +IF(APPLE) + SET(EXE_CONTENTS "${CMAKE_INSTALL_PREFIX}/${EXECUTABLE}/Contents") + message(STATUS "EXE_CONTENTS: " ${EXE_CONTENTS}) + message(STATUS "EXECUTABLE: " ${EXECUTABLE}) + FILE(WRITE + ${EXE_CONTENTS}/Resources/qt.conf + "[Paths]\nPlugins=PlugIns\n") + FILE(COPY ${QT_PLUGINS_DIR}/imageformats + DESTINATION ${EXE_CONTENTS}/PlugIns/ + PATTERN "*_debug.*" EXCLUDE) + ADD_CUSTOM_COMMAND( + TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ruby ${PROJECT_SOURCE_DIR}/ruby/fixup/fixup.rb ${CMAKE_INSTALL_PREFIX}/${EXECUTABLE} + COMMENT "Fixing up the app bundle") +ENDIF(APPLE) # if(APPLE OR WIN32) diff --git a/Resources/dmg.json b/Resources/dmg.json new file mode 100644 index 0000000..e209f1b --- /dev/null +++ b/Resources/dmg.json @@ -0,0 +1,10 @@ +{ + "title": "JPSvis", + "icon": "../forms/jpsvis.icns", + "background": "back.png", + "contents": [ + { "x": 348, "y": 144, "type": "link", "path": "/Applications" }, + { "x": 220, "y": 144, "type": "file", "path": "../bin/jpsvis.app" }, + { "x": 92, "y": 144, "type": "file", "path": "../samples" } + ] +} diff --git a/checkDependencies.py b/checkDependencies.py new file mode 100644 index 0000000..752457f --- /dev/null +++ b/checkDependencies.py @@ -0,0 +1,46 @@ +# some vtk libs depend on python. +# correct this dependency and make it point to local python. +import glob2 +import subprocess +import shlex +import os +RED = '\033[0;31m' +NC = '\033[0m' # No Color + + +CMD = "jpsvis" +PATH = "./bin/%s.app/Contents/Frameworks" % CMD + +dependencies = glob2.glob("%s/**/*.dylib"%PATH) + + + + + +#VTK_LIBS +for vtklib in dependencies: + + print "vtklib: <%s>" % vtklib + + cmd = "otool -L %s" % vtklib + f = open("blah.txt", "w") + res = subprocess.call(shlex.split(cmd), stdout=f) + f.close() + f = open("blah.txt", "r") + lines = f.readlines() + for line in lines[1:]: + line = line.strip() + if not line.startswith("/usr/lib") \ + and not line.startswith("/System") \ + and not line.startswith("@executable_path"): + + print ">> <%s>" % line.split()[0] + change = "install_name_tool -change %s @executable_path/../Frameworks/Python.framework/Versions/3.5/Python %s"%(line.split()[0], vtklib) + print "<%s>" % change + res = subprocess.call(shlex.split(change)) + + + f.close() + +if os.path.exists ("blah.txt"): + os.remove("blah.txt") diff --git a/deployAPPLE.sh b/deployAPPLE.sh index 9eefd42..2069f0c 100755 --- a/deployAPPLE.sh +++ b/deployAPPLE.sh @@ -1,8 +1,10 @@ -#!/bin/sh RED='\033[0;31m' NC='\033[0m' # No Color +CMD="jpsvis" + + if [ -d build ];then echo "INFO: found build directory" echo "INFO:${RED} rm build ${NC}" @@ -28,8 +30,38 @@ cmake .. echo "INFO: make .." make -j4 -echo "INFO: running dynlibbundler .." -dylibbundler -od -b -x ../bin/JPSvis.app/Contents/MacOS/JPSvis -d ../bin/JPSvis.app/Contents/libs/ -echo "INFO: running macdeployqt .." -macdeployqt ../bin/JPSvis.app -dmg +echo "INFO: running <dylibbundler -od -b -x ../bin/${CMD}.app/Contents/MacOS/${CMD} -d ../bin/${CMD}.app/Contents/libs/>" +dylibbundler -od -b -x ../bin/${CMD}.app/Contents/MacOS/${CMD} -d ../bin/${CMD}.app/Contents/libs/ + + +# dylibbundler has a problem linking to local python framework. So this quick fix.. +isPythonDependencyGlobal=`otool -L ../bin/${CMD}.app/Contents/MacOS/${CMD} | grep Python.framework` + +echo "isPythonDependencyGlobal: <$isPythonDependencyGlobal>" + +if [[ -n $isPythonDependencyGlobal ]];then + if [[ ! $isPythonSWDependencyGlobal == *"@executable_path"* ]]; then + #install_name_tool -change /usr/local/opt/python3/Frameworks/Python.framework/Versions/3.5/Python + # @executable_path/../Frameworks/Python.framework/Versions/3.5/Python + # ./bin/jpsvis.app/Contents/MacOS/jpsvis + + Python=`echo ${isPythonDependencyGlobal} | xargs | awk '{print $1}'` + echo "WARNING: ${RED} <$Python> is not relative to ${CMD} ${NC}." + + Frameworks=`echo ${Python} | awk -F Frameworks '{ print "Frameworks"$2 }'` + echo "WARNING: ${RED} change <$Python> to <@executable_path/../$Frameworks> ${CMD} ${NC}." + + install_name_tool -change $Python @executable_path/../$Frameworks ../bin/${CMD}.app/Contents/MacOS/${CMD} + + echo "INFO: Check again" + otool -L ../bin/${CMD}.app/Contents/MacOS/${CMD} | grep Python.framework + echo "-----------------" + + fi +fi + +# check if dependencies to libs are local to .app +python checkDependencies.py + +appdmg Resources/dmg.json {CMD}-0.8.1.dmg diff --git a/install_packages_debian.txt b/install_packages_debian.txt index 4a18f26..bf3cca1 100644 --- a/install_packages_debian.txt +++ b/install_packages_debian.txt @@ -14,4 +14,4 @@ sudo apt-get install libmgl-qt5 sudo apt-get install libvtk5-dev sudo apt-get install libvtk5.8-qt4 * ubuntu docker -see Dockerfile + see Dockerfile -- GitLab