diff --git a/Code/Mantid/MantidPlot/CMakeLists.txt b/Code/Mantid/MantidPlot/CMakeLists.txt index 6314b89a3f66c3453d7097e99b98e615f199154a..be38f40c868eaac700586566f27a61d0eb3e482e 100644 --- a/Code/Mantid/MantidPlot/CMakeLists.txt +++ b/Code/Mantid/MantidPlot/CMakeLists.txt @@ -1041,12 +1041,18 @@ install ( FILES ${CONFIG_RESET_SCRIPT} DESTINATION ${BIN_DIR} ) # this causes fail of the installation with macports # therefore MACPORTS option is introduced if ( APPLE ) - if (OSX_VERSION VERSION_LESS 10.9 OR MACPORTS) + if (OSX_VERSION VERSION_LESS 10.9) configure_file ( ${CMAKE_CURRENT_SOURCE_DIR}/FixBundle.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FixBundle.cmake @ONLY ) install ( SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/FixBundle.cmake ) + elseif (MACPORTS) + install ( FILES package_python_macports.py DESTINATION MantidPlot.app/ ) + configure_file ( ${CMAKE_CURRENT_SOURCE_DIR}/FixMacportsBundle.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/FixMacportsBundle.cmake + @ONLY ) + install ( SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/FixMacportsBundle.cmake ) else () install ( FILES make_package.rb DESTINATION MantidPlot.app/ ) configure_file ( ${CMAKE_CURRENT_SOURCE_DIR}/FixMavericksBundle.cmake.in diff --git a/Code/Mantid/MantidPlot/FixMacportsBundle.cmake.in b/Code/Mantid/MantidPlot/FixMacportsBundle.cmake.in new file mode 100644 index 0000000000000000000000000000000000000000..02fa2fe1d37f542a8667ed9da9c571b9622a7619 --- /dev/null +++ b/Code/Mantid/MantidPlot/FixMacportsBundle.cmake.in @@ -0,0 +1,122 @@ +set(BU_CHMOD_BUNDLE_ITEMS True) +set ( bundle ${CMAKE_INSTALL_PREFIX}/MantidPlot.app ) +execute_process(COMMAND chmod +x package_python_macports.py WORKING_DIRECTORY ${bundle}) +execute_process(COMMAND ./package_python_macports.py WORKING_DIRECTORY ${bundle}) + +file ( GLOB pyqt_libs ${bundle}/Contents/MacOS/PyQt4/*.so ) +file ( GLOB mantid_plugins ${bundle}/plugins/*.dylib ) +file ( GLOB_RECURSE qtplugins ${bundle}/Contents/Frameworks/plugins/*.dylib ) +file ( GLOB_RECURSE mtdqtplugins ${bundle}/plugins/*.dylib ) +file ( GLOB_RECURSE pvplugins ${bundle}/pvplugins/*.dylib ) +file ( GLOB vatesplugins ${bundle}/pvplugins/*.dylib ) # Find just the top level Vates plugins + +# gp_resolved_file_type_override +# Sets the type of the dependency. The options are: system, local, embedded, other +# For OS X, system & embedded dependencies are NOT copied in to the bundle +function(gp_resolved_file_type_override resolved_file type_var) + if(resolved_file MATCHES "^/usr(|/local)/lib") + message(STATUS "resolving ${file} as system") + set(${type_var} system PARENT_SCOPE) + endif() + # Copy Qt dependencies to bundle + if(file MATCHES "libQt") + message("resolving ${file} as embedded") + set(${type_var} embedded PARENT_SCOPE) + endif() + # Don't copy ParaView into the bundle +# if(resolved_file MATCHES "^@ParaView_DIR@") +# message(STATUS "resolving ParaView dependency ${file} as system") +# set(${type_var} system PARENT_SCOPE) +# endif() + # resolve python framework as system + if(file MATCHES "Python.framework") + message("resolving ${file} as system") + set(${type_var} system PARENT_SCOPE) + endif() +endfunction() + +# gp_item_default_embedded_path_override item default_embedded_path_var +# +# Return the path that others should refer to the item by when the item +# is embedded inside a bundle. +# +# This is a project-specific override of BundleUtilities.cmake's +# gp_item_default_embedded_path +# +function(gp_item_default_embedded_path_override item default_embedded_path_var) + # By default, embed items next to application + # + set( path "@executable_path/../MacOS" ) + + list( FIND mantid_plugins ${item} mtd_plugin_found ) + if( mtd_plugin_found GREATER -1 ) + message( STATUS "Setting path for Mantid plugin ") + set( path "@executable_path/../../plugins" ) + set( overridden 1 PARENT_SCOPE ) + endif() + + list( FIND vatesplugins ${item} vatesplugin_found ) + if( vatesplugin_found GREATER -1 ) + message( STATUS "Setting path for Vates plugin ") + set( path "@executable_path/../../pvplugins" ) + set( overridden 1 PARENT_SCOPE ) + endif() + + if(item MATCHES "[^/]+\\.framework/") + set(path "@executable_path/../Frameworks") + set( overridden 1 PARENT_SCOPE ) + endif() + + if(item MATCHES "_kernel.so") + set(path "@loader_path/../kernel") + set( overridden 1 PARENT_SCOPE ) + endif() + + if(item MATCHES "_geometry.so") + set(path "@loader_path/../geometry") + set( overridden 1 PARENT_SCOPE ) + endif() + + set(${default_embedded_path_var} "${path}" PARENT_SCOPE) +endfunction(gp_item_default_embedded_path_override) + +include (BundleUtilities) + +set ( mantidpydir ${bundle}/Contents/MacOS/mantid ) +set ( mantidpylibs ${mantidpydir}/kernel/_kernel.so + ${mantidpydir}/geometry/_geometry.so + ${mantidpydir}/api/_api.so ) + +set ( other_libs ${bundle}/Contents/MacOS/mantidqtpython.so + ${bundle}/Contents/MacOS/readline.so + ${mantid_plugins} + ${pyqt_libs} ${qtplugins} ${pvplugins} + ${mantidpylibs} ${mtdqtplugins} ) + +set ( dirs "@CMAKE_LIBRARY_OUTPUT_DIRECTORY@" "@CMAKE_LIBRARY_PATH@" /Library/Frameworks /opt/intel/lib /opt/local/lib) + +fixup_bundle ( "${bundle}" "${other_libs}" "${dirs}" ) # This will fix up the dependencies for the hard dependencies: MantidKernel etc + +#################################################### +# Functions to change the dependency references +#################################################### +function( change_bundle_id new_id sharedlib ) + execute_process(COMMAND install_name_tool -id ${new_id} ${sharedlib}) +endfunction() + +function( change_bundle_dep old_dep new_dep sharedlib ) + execute_process(COMMAND install_name_tool -change ${old_dep} ${new_dep} ${sharedlib}) +endfunction() + + +# Allow include to do cmake_policy push/pops: +# Makes the below behaviour work +if(COMMAND CMAKE_POLICY) + cmake_policy(SET CMP0011 NEW) +endif(COMMAND CMAKE_POLICY) +# Allows ON to be treated directly in an if() statement +if(COMMAND CMAKE_POLICY) + cmake_policy(SET CMP0012 NEW) +endif(COMMAND CMAKE_POLICY) + +# MAKE_VATES does not work with macports diff --git a/Code/Mantid/MantidPlot/package_python_macports.py b/Code/Mantid/MantidPlot/package_python_macports.py new file mode 100644 index 0000000000000000000000000000000000000000..7ff39ce91e677ad28d65f05e48d5bab23ae88aca --- /dev/null +++ b/Code/Mantid/MantidPlot/package_python_macports.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python +""" +Script to pack the python libraries +to the dmg package created with clang+macports +""" +import sys, shutil, os +from distutils.spawn import find_executable + +# path to copy the libraries +OUTPUT_PATH = os.path.abspath("Contents/MacOS") + +# list of the python libraries to copy +PYTHON_LIBRARIES = ['sphinx', 'sphinx_bootstrap_theme', 'IPython', 'zmq', 'pygments', \ + '_markerlib', 'backports', 'certifi', 'tornado', 'markupsafe', \ + 'jinja2', 'psutil', 'nxs'] + +# path to the nxs +# by default the nexus library installs it here +sys.path.append('/opt/local/lib/python2.7/site-packages/') + +# names of the nexus libraries for symlinks +NEXUSLIBS = {"libNeXus.0.dylib": "libNeXus.dylib", "libNeXusCPP.0.dylib": "libNeXusCPP.dylib"} + +def copy_directory(src, dest): + """ + Copies recursively directory src to dest + overwrites dest if the directory dest already exists + """ + if os.path.exists(dest): + shutil.rmtree(dest) + try: + shutil.copytree(src, dest) + # Directories are the same + except shutil.Error as error: + print 'Directory not copied. Error: %s' % error + # Any error saying that the directory doesn't exist + except OSError as error: + print 'Directory not copied. Error: %s' % error + +def copy_file(src, dest): + """ + Copies the file src to destination dst + dest must be a full file name + """ + try: + shutil.copyfile(src, dest) + # file already exists + except shutil.Error as error: + print 'File is not copied. Error: %s' % error + # Any error saying that the directory doesn't exist + except OSError as error: + print 'File is not copied. Error: %s' % error + + +if __name__ == '__main__': + # copy the python libraries + for lib in PYTHON_LIBRARIES: + try: + module = map(__import__, [lib]) + except ImportError as detail: + print "Cannot import library ", lib + print "Reason: ", detail + else: + copy_directory(module[0].__path__[0], os.path.join(OUTPUT_PATH, lib)) + + # create symlinks for NEXUSLIBS + for nlib in NEXUSLIBS.keys(): + libnexus_src = os.path.join(OUTPUT_PATH, nlib) + libnexus_dst = os.path.join(OUTPUT_PATH, NEXUSLIBS[nlib]) + os.symlink(libnexus_src, libnexus_dst) + + # copy ipython (although I do not understand why) + # find ipython executable + IPYTHON_EXECUTABLE = find_executable('ipython') + if not IPYTHON_EXECUTABLE: + print "Cannot find ipython executable" + else: + # create bin folder + BIN_DIRECTORY_NAME = os.path.join(OUTPUT_PATH, 'bin') + try: + if not os.path.exists(BIN_DIRECTORY_NAME): + os.mkdir(BIN_DIRECTORY_NAME) + except OSError as error: + print "Cannot create directory %s. Error: %s." % (BIN_DIRECTORY_NAME, error) + else: + # copy ipython executable + copy_file(IPYTHON_EXECUTABLE, os.path.join(BIN_DIRECTORY_NAME, 'ipython')) + + # find and copy pyparsing + try: + import pyparsing + except ImportError as detail: + print "Cannot import pyparsing. Error: ", detail + else: + copy_file(pyparsing.__file__, os.path.join(OUTPUT_PATH, 'pyparsing.pyc')) + copy_file(os.path.splitext(pyparsing.__file__)[0]+'.py', \ + os.path.join(OUTPUT_PATH, 'pyparsing.py')) + + # find and copy readline + try: + import readline + import readline_path + except ImportError as detail: + print "Cannot import readline. Error: ", detail + else: + copy_file(readline.__file__, os.path.join(OUTPUT_PATH, os.path.split(readline.__file__)[1])) + copy_file(readline_path.__file__, os.path.join(OUTPUT_PATH, \ + os.path.split(readline_path.__file__)[1])) + copy_file(os.path.splitext(readline_path.__file__)[0]+'.py', \ + os.path.join(OUTPUT_PATH, 'readline_path.py')) + +