Something went wrong on our end
-
Andreas Schenk authoredAndreas Schenk authored
CopyDependencies.cmake 46.27 KiB
#-------------------------------------------------------------------------------
# Author: Andreas Schenk
#
# This file contains functions to determine, copy and verify the dependencies
# of the application bundle.
#
# Part of this code was taken from BundleUtilities.cmake, distributed
# under the OSI-approved BSD License (see below), and adapted.
#-------------------------------------------------------------------------------
# CMake - Cross Platform Makefile Generator
# Copyright 2000-2011 Kitware, Inc., Insight Software Consortium
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# * Neither the names of Kitware, Inc., the Insight Software Consortium,
# nor the names of their contributors may be used to endorse or promote
# products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
# function copy dependencies
#=============================================================================
function(copy_dependencies binaries)
#--------------------------------------------------------------------------
message("copy dependencies: resolving binary paths")
#--------------------------------------------------------------------------
message(STATUS " binaries='${binaries}'")
set(resolved_binaries)
foreach(binary ${binaries})
get_filename_component(resolved_binary ${binary} REALPATH)
if(NOT ${resolved_binary} MATCHES ${CMAKE_INSTALL_PREFIX})
message(FATAL_ERROR "Binary path: '${resolved_binary}' points to outside bundle.")
endif(NOT ${resolved_binary} MATCHES ${CMAKE_INSTALL_PREFIX})
list(APPEND resolved_binaries ${resolved_binary})
endforeach(binary)
list(REMOVE_DUPLICATES resolved_binaries)
#--------------------------------------------------------------------------
message("copy dependencies: determining dependencies")
#--------------------------------------------------------------------------
collect_dependencies("${resolved_binaries}" keys)
#--------------------------------------------------------------------------
message("copy dependencies: copying files")
#--------------------------------------------------------------------------
list(LENGTH keys n)
math(EXPR n ${n}*2)
set(i 0)
foreach(key ${keys})
math(EXPR i ${i}+1)
if(${${key}_COPYFLAG})
message(STATUS "${i}/${n}: copying '${${key}_RESOLVED_ITEM}' to '${${key}_RESOLVED_EMBEDDED_ITEM}'")
set(item "${${key}_ITEM}")
copy_resolved_item("${${key}_RESOLVED_ITEM}" "${${key}_RESOLVED_EMBEDDED_ITEM}")
else(${${key}_COPYFLAG})
message(STATUS "${i}/${n}: *NOT* copying '${${key}_RESOLVED_ITEM}'")
endif(${${key}_COPYFLAG})
endforeach(key)
#--------------------------------------------------------------------------
message("copy dependencies: changing install names")
#--------------------------------------------------------------------------
foreach(key ${keys})
math(EXPR i ${i}+1)
if(APPLE)
if(NOT ${${key}_SYSTEMFLAG})
message(STATUS "${i}/${n}: changing install names for '${${key}_RESOLVED_EMBEDDED_ITEM}'")
change_install_names_for_item(keys "${key}")
else(NOT ${${key}_SYSTEMFLAG})
message(STATUS "${i}/${n}: skipping install name change for system library: '${${key}_RESOLVED_EMBEDDED_ITEM}'")
endif(NOT ${${key}_SYSTEMFLAG})
else(APPLE)
message(STATUS "${i}/${n}: changing install names not required on this platform '${${key}_RESOLVED_EMBEDDED_ITEM}'")
endif(APPLE)
endforeach(key)
#--------------------------------------------------------------------------
message("copy dependencies: verifying binaries")
#--------------------------------------------------------------------------
verify(keys)
#--------------------------------------------------------------------------
message("copy dependencies: cleaning up")
#--------------------------------------------------------------------------
clear_keys(keys)
#--------------------------------------------------------------------------
message("copy dependencies: done")
#--------------------------------------------------------------------------
endfunction(copy_dependencies)
#=============================================================================
# function collect_dependencies
#=============================================================================
function(collect_dependencies binaries keys_var)
set(${keys_var} PARENT_SCOPE)
# First add all binaries to the keys.
# This is done before dependency resolution because one of the binaries could
# potentially be a dependency.
foreach(exe ${binaries})
get_filename_component(exepath "${exe}" PATH)
set_keys_for_item(${keys_var} "${exe}" "${exe}" 0 0)
endforeach(exe)
# Get dependencies and add them to the keys.
foreach(exe ${binaries})
get_filename_component(exepath "${exe}" PATH)
add_dependencies_for_item(${keys_var} "${exe}" "${exepath}")
endforeach(exe)
# Propagate values to caller's scope:
set(${keys_var} ${${keys_var}} PARENT_SCOPE)
foreach(key ${${keys_var}})
set(${key}_ITEM "${${key}_ITEM}" PARENT_SCOPE)
set(${key}_RESOLVED_ITEM "${${key}_RESOLVED_ITEM}" PARENT_SCOPE)
set(${key}_RESOLVED_EMBEDDED_ITEM "${${key}_RESOLVED_EMBEDDED_ITEM}" PARENT_SCOPE)
set(${key}_COPYFLAG "${${key}_COPYFLAG}" PARENT_SCOPE)
set(${key}_SYSTEMFLAG "${${key}_SYSTEMFLAG}" PARENT_SCOPE)
endforeach(key)
endfunction(collect_dependencies)
#=============================================================================
# function set_keys_for_item
#=============================================================================
function(set_keys_for_item keys_var context resolved_item copyflag systemflag)
get_item_key("${resolved_item}" key)
list(LENGTH ${keys_var} length_before)
append_unique(${keys_var} "${key}")
list(LENGTH ${keys_var} length_after)
if(NOT length_before EQUAL length_after)
if(${copyflag} AND (NOT ${systemflag}) )
resolve_embedded_item("${resolved_item}" resolved_embedded_item)
set(${key}_RESOLVED_EMBEDDED_ITEM "${resolved_embedded_item}" PARENT_SCOPE)
if(${resolved_embedded_item} STREQUAL ${resolved_item})
set(${key}_COPYFLAG 0 PARENT_SCOPE)
else(${resolved_embedded_item} STREQUAL ${resolved_item})
set(${key}_COPYFLAG 1 PARENT_SCOPE)
endif(${resolved_embedded_item} STREQUAL ${resolved_item})
set(${key}_SYSTEMFLAG 0 PARENT_SCOPE)
else(${copyflag} AND (NOT ${systemflag}) )
set(${key}_COPYFLAG ${copyflag} PARENT_SCOPE)
set(${key}_SYSTEMFLAG ${systemflag} PARENT_SCOPE)
set(${key}_RESOLVED_EMBEDDED_ITEM "${resolved_item}" PARENT_SCOPE)
endif(${copyflag} AND (NOT ${systemflag}) )
set(${keys_var} ${${keys_var}} PARENT_SCOPE)
get_filename_component(item_name "${resolved_item}" NAME)
set(${key}_ITEM "${item_name}" PARENT_SCOPE)
set(${key}_RESOLVED_ITEM "${resolved_item}" PARENT_SCOPE)
else(NOT length_before EQUAL length_after)
message(FATAL_ERROR "Item key '${key}' already in the list. This should not happen.")
endif(NOT length_before EQUAL length_after)
endfunction(set_keys_for_item)
#=============================================================================
# function get_item_key
#=============================================================================
function(get_item_key item key_var)
get_filename_component(item_name "${item}" REALPATH)
if(WIN32)
string(TOLOWER "${item_name}" item_name)
endif()
string(REGEX REPLACE "\\." "_" item_name "${item_name}")
string(REGEX REPLACE "/" "_" item_name "${item_name}")
string(REGEX REPLACE "\\\\" "_" ${key_var} "${item_name}")
set(${key_var} ${${key_var}} PARENT_SCOPE)
endfunction(get_item_key)
#=============================================================================
# function clear_keys
#=============================================================================
function(clear_keys keys_var)
foreach(key ${${keys_var}})
set(${key}_ITEM PARENT_SCOPE)
set(${key}_RESOLVED_ITEM PARENT_SCOPE)
set(${key}_RESOLVED_EMBEDDED_ITEM PARENT_SCOPE)
set(${key}_COPYFLAG PARENT_SCOPE)
set(${key}_SYSTEMFLAG PARENT_SCOPE)
endforeach(key)
set(${keys_var} PARENT_SCOPE)
endfunction(clear_keys)
#=============================================================================
# function resolve_item
#=============================================================================
function(resolve_item context item exepath resolved_item_var)
set(resolved_item "${item}")
# @rpath references are relative to the paths built into the binaries with -rpath
# rpath resolution comes first, as the rpath might contain a @loader_path or @executable_path reference
if(resolved_item MATCHES "@rpath")
get_rpath("${context}" rpath)
string(REPLACE "@rpath/" "${rpath}/" resolved_item "${resolved_item}")
endif(resolved_item MATCHES "@rpath")
# @executable_path references are assumed relative to exepath
if(resolved_item MATCHES "@executable_path")
string(REPLACE "@executable_path" "${exepath}" resolved_item "${resolved_item}")
endif(resolved_item MATCHES "@executable_path")
# @loader_path references are assumed relative to the
# PATH of the given "context" (presumably another library)
if(resolved_item MATCHES "@loader_path")
get_filename_component(contextpath "${context}" PATH)
string(REPLACE "@loader_path" "${contextpath}" resolved_item "${resolved_item}")
endif(resolved_item MATCHES "@loader_path")
if(NOT WIN32)
get_filename_component(resolved_item "${resolved_item}" REALPATH)
endif(NOT WIN32)
if(IS_ABSOLUTE "${resolved_item}" AND EXISTS "${resolved_item}")
set(${resolved_item_var} "${resolved_item}" PARENT_SCOPE)
return()
endif(IS_ABSOLUTE "${resolved_item}" AND EXISTS "${resolved_item}")
set(ri "ri-NOTFOUND")
if(UNIX AND NOT WIN32)
find_file(ri "${item}" ${exepath} NO_DEFAULT_PATH)
find_file(ri "${item}" ${exepath} /usr/lib)
else(UNIX AND NOT WIN32)
find_program(ri "${item}" PATHS "${exepath}" NO_DEFAULT_PATH)
find_program(ri "${item}" PATHS "${CMAKE_INSTALL_PREFIX}/bin" NO_DEFAULT_PATH)
find_program(ri "${item}" PATHS "${exepath}")
endif(UNIX AND NOT WIN32)
if(ri)
set(resolved_item "${ri}")
set(ri "ri-NOTFOUND")
endif(ri)
if(IS_ABSOLUTE "${resolved_item}" AND EXISTS "${resolved_item}")
set(${resolved_item_var} "${resolved_item}" PARENT_SCOPE)
else(IS_ABSOLUTE "${resolved_item}" AND EXISTS "${resolved_item}")
message(FATAL_ERROR "cannot resolve item '${item}' in context:'${context}'. Partially resolved path is: '${resolved_item}'")
endif(IS_ABSOLUTE "${resolved_item}" AND EXISTS "${resolved_item}")
endfunction(resolve_item)
#=============================================================================
# function resolve_embedded_item
#=============================================================================
function(resolve_embedded_item item resolved_item_var)
if(${item} MATCHES ${CMAKE_INSTALL_PREFIX})
# item already embedded
set(${resolved_item_var} ${item} PARENT_SCOPE)
else(${item} MATCHES ${CMAKE_INSTALL_PREFIX})
# only embed libraries, therefore put into lib dir
get_filename_component(item_name "${item}" NAME)
if(WIN32 AND NOT UNIX)
set(${resolved_item_var} "${CMAKE_INSTALL_PREFIX}/bin/${item_name}" PARENT_SCOPE)
else(WIN32 AND NOT UNIX)
set(${resolved_item_var} "${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/${item_name}" PARENT_SCOPE)
endif(WIN32 AND NOT UNIX)
endif(${item} MATCHES ${CMAKE_INSTALL_PREFIX})
endfunction(resolve_embedded_item)
#=============================================================================
# function change_install_names_for_item
#=============================================================================
function(change_install_names_for_item keys_var key)
# Ensure the item is within the install directory
if(${${key}_RESOLVED_EMBEDDED_ITEM} MATCHES ${CMAKE_INSTALL_PREFIX})
set(prereqs "")
get_filename_component(exepath ${${key}_RESOLVED_EMBEDDED_ITEM} PATH)
string(REPLACE ${CMAKE_INSTALL_PREFIX} "" rel_path ${exepath})
string(REGEX REPLACE "/[^/]*" "/.." inv_rel_path ${rel_path})
get_dependencies_for_item("${${key}_RESOLVED_EMBEDDED_ITEM}" prereqs)
set(changes "")
foreach(pr ${prereqs})
# Each referenced item's key is "rkey" in the loop:
get_filename_component(exepath ${${key}_RESOLVED_EMBEDDED_ITEM} PATH)
resolve_item( ${${key}_RESOLVED_EMBEDDED_ITEM} ${pr} exepath resolved_pr)
get_item_key("${resolved_pr}" rkey)
list(FIND ${keys_var} ${rkey} r_found)
if(r_found EQUAL -1)
MESSAGE(FATAL_ERROR "Key: '${rkey}' not found in dependency list. Cannot change install name.")
endif(r_found EQUAL -1)
if(NOT ${${rkey}_SYSTEMFLAG})
get_filename_component(ref_exepath ${${rkey}_RESOLVED_EMBEDDED_ITEM} PATH)
string(REPLACE ${CMAKE_INSTALL_PREFIX} "" ref_rel_path ${ref_exepath})
set(diff_path @loader_path${inv_rel_path}${ref_rel_path}/)
set(changes ${changes} "-change" "${pr}" "${diff_path}${${rkey}_ITEM}")
endif(NOT ${${rkey}_SYSTEMFLAG})
endforeach(pr)
execute_process(COMMAND chmod u+w "${${key}_RESOLVED_EMBEDDED_ITEM}")
# Change this item's id and all of its references in one call
# to install_name_tool:
execute_process(COMMAND install_name_tool ${changes} -id "${${key}_ITEM}" "${${key}_RESOLVED_EMBEDDED_ITEM}")
else( ${${key}_RESOLVED_EMBEDDED_ITEM} MATCHES ${CMAKE_INSTALL_PREFIX})
MESSAGE(FATAL_ERROR "Trying to change install name for: ${${key}_RESOLVED_EMBEDDED_ITEM}, which is outside of install directory")
endif(${${key}_RESOLVED_EMBEDDED_ITEM} MATCHES ${CMAKE_INSTALL_PREFIX})
endfunction(change_install_names_for_item)
#=============================================================================
# function verify
#=============================================================================
function(verify keys_var)
foreach(key ${${keys_var}})
if(NOT ${${key}_SYSTEMFLAG})
get_dependencies_for_item("${${key}_RESOLVED_EMBEDDED_ITEM}" dependencies)
get_filename_component(exepath ${${key}_RESOLVED_EMBEDDED_ITEM} PATH)
foreach(dep ${dependencies})
resolve_item( ${${key}_RESOLVED_EMBEDDED_ITEM} ${dep} exepath resolved_dep)
is_system_lib(${resolved_dep} system_flag)
if(NOT ${system_flag})
if(NOT ${resolved_dep} MATCHES ${CMAKE_INSTALL_PREFIX})
MESSAGE("Warning: item:'${${key}_RESOLVED_EMBEDDED_ITEM}' contains external dependency:'${resolved_dep}'")
endif(NOT ${resolved_dep} MATCHES ${CMAKE_INSTALL_PREFIX})
endif(NOT ${system_flag})
endforeach(dep)
endif(NOT ${${key}_SYSTEMFLAG})
endforeach(key)
endfunction(verify)
#=============================================================================
# function add_dependencies_for_item
#=============================================================================
function(add_dependencies_for_item keys_var item exepath)
if(NOT IS_ABSOLUTE "${item}" AND EXISTS "${item}")
message(FATAL_ERROR "Item '${item}' does not exist.")
endif(NOT IS_ABSOLUTE "${item}" AND EXISTS "${item}")
get_dependencies_for_item(${item} dependencies)
foreach(dep ${dependencies})
resolve_item("${item}" "${dep}" "${exepath}" resolved_dep)
get_item_key("${resolved_dep}" dep_key)
list(FIND ${keys_var} ${dep_key} dep_found)
if(dep_found EQUAL -1)
message(STATUS "Resolved '${dep}' to: '${resolved_dep}'")
is_system_lib(${resolved_dep} system_flag)
if(${system_flag})
MESSAGE(STATUS "Skipping system library:'${resolved_dep}'")
set_keys_for_item(${keys_var} ${item} ${resolved_dep} 0 1)
else(${system_flag})
set_keys_for_item(${keys_var} ${item} ${resolved_dep} 1 0)
add_dependencies_for_item(${keys_var} ${resolved_dep} ${exepath})
endif(${system_flag})
endif(dep_found EQUAL -1)
endforeach(dep ${dependencies})
# Propagate values to caller's scope:
set(${keys_var} ${${keys_var}} PARENT_SCOPE)
foreach(key ${${keys_var}})
set(${key}_ITEM "${${key}_ITEM}" PARENT_SCOPE)
set(${key}_RESOLVED_ITEM "${${key}_RESOLVED_ITEM}" PARENT_SCOPE)
set(${key}_RESOLVED_EMBEDDED_ITEM "${${key}_RESOLVED_EMBEDDED_ITEM}" PARENT_SCOPE)
set(${key}_COPYFLAG "${${key}_COPYFLAG}" PARENT_SCOPE)
set(${key}_SYSTEMFLAG "${${key}_SYSTEMFLAG}" PARENT_SCOPE)
endforeach(key)
endfunction(add_dependencies_for_item)
#=============================================================================
# function append_unique
#=============================================================================
function(append_unique list_var value)
set(contains 0)
foreach(item ${${list_var}})
if("${item}" STREQUAL "${value}")
set(contains 1)
break()
endif("${item}" STREQUAL "${value}")
endforeach(item)
if(NOT contains)
set(${list_var} ${${list_var}} "${value}" PARENT_SCOPE)
endif(NOT contains)
endfunction(append_unique)
#=============================================================================
# function copy_python
#=============================================================================
function(copy_python include_path version new_binary_path)
get_filename_component(real_python_include_path ${include_path} REALPATH)
get_filename_component(python_root_dir ${real_python_include_path}/../.. REALPATH)
file(COPY ${python_root_dir}/${LIB_DIR}/python${version}/ DESTINATION ${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/python${version})
file(GLOB py_config_files "${include_path}/pyconfig*.h")
file(COPY ${py_config_files} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/python${version})
file(GLOB_RECURSE python_so_files "${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/python${version}/*.so")
if(NOT APPLE)
foreach(so_file ${python_so_files})
remove_rpath("${so_file}")
endforeach(so_file)
endif(NOT APPLE)
read_config(ost_config)
if(APPLE)
file(COPY ${python_root_dir}/Resources/Python.app/Contents/MacOS/Python DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
set(${new_binary_path} "${CMAKE_INSTALL_PREFIX}/bin/Python" PARENT_SCOPE)
string(REGEX REPLACE "pyexec=\"[^\n\$]*\"" "pyexec=\"\$DNG_BINDIR/Python\"\nexport PYTHONHOME=\$DNG_ROOT" ost_config "${ost_config}")
else(APPLE)
file(GLOB python_libs "${python_root_dir}/${LIB_DIR}/libpython${version}.so*")
file(COPY ${python_libs} DESTINATION ${CMAKE_INSTALL_PREFIX}/${LIB_DIR})
file(COPY ${python_root_dir}/bin/python${version} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
set(${new_binary_path} "${CMAKE_INSTALL_PREFIX}/bin/python${version}" PARENT_SCOPE)
string(REGEX REPLACE "pyexec=\"[^\n\$]*\"" "pyexec=\"\$DNG_BINDIR/python${version}\"\nexport PYTHONHOME=\$DNG_ROOT" ost_config "${ost_config}")
endif(APPLE)
write_config("${ost_config}")
endfunction(copy_python)
#=============================================================================
# function read_config
#=============================================================================
function(read_config ost_config_var)
file(READ "${CMAKE_INSTALL_PREFIX}/libexec/openstructure/ost_config" ost_config)
set(${ost_config_var} "${ost_config}" PARENT_SCOPE)
endfunction(read_config)
#=============================================================================
# function write_config
#=============================================================================
function(write_config ost_config)
file(WRITE "${CMAKE_INSTALL_PREFIX}/libexec/openstructure/ost_config" "${ost_config}")
endfunction(write_config)
#=============================================================================
# function write_bundle_binary
#=============================================================================
function(write_bundle_binary binary_name real_binary)
file(WRITE "${CMAKE_INSTALL_PREFIX}/../MacOS/${binary_name}" "#!/bin/sh\nexec \"\${0%/*}/${real_binary}\"\n")
execute_process(COMMAND chmod ugo+x "${CMAKE_INSTALL_PREFIX}/../MacOS/${binary_name}")
endfunction(write_bundle_binary)
#=============================================================================
# function add_linked_bundle
#=============================================================================
function(add_linked_bundle parent_bundle_name bundle_name binary_name bundle_identifier bundle_icon)
get_filename_component(dmg_main_path ${CMAKE_INSTALL_PREFIX}/../../../../ PATH)
file(MAKE_DIRECTORY "${dmg_main_path}/${bundle_name}.app/Contents/MacOS/")
file(MAKE_DIRECTORY "${dmg_main_path}/${bundle_name}.app/Contents/Resources/")
file(WRITE "${dmg_main_path}/${bundle_name}.app/Contents/MacOS/${binary_name}" "#!/bin/sh\nexec \"\${0%/*}/../../../${parent_bundle_name}.app/Contents/Resources/bin/${binary_name}\"\n")
get_filename_component(icon_name ${bundle_icon} NAME)
file(COPY ${bundle_icon} DESTINATION "${dmg_main_path}/${bundle_name}.app/Contents/Resources")
create_plist(${binary_name} ${bundle_name} ${bundle_identifier} ${icon_name} "${dmg_main_path}/${bundle_name}.app/Contents/Info.plist")
execute_process(COMMAND chmod ugo+x "${dmg_main_path}/${bundle_name}.app/Contents/MacOS/${binary_name}")
endfunction(add_linked_bundle)
#=============================================================================
# function create_plist
#=============================================================================
function(create_plist BUNDLE_EXECUTABLE BUNDLE_NAME BUNDLE_IDENTIFIER BUNDLE_ICON FILENAME)
set( info_plist "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\"
\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version=\"1.0\">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>\@BUNDLE_EXECUTABLE\@</string>
<key>CFBundleName</key>
<string>\@BUNDLE_NAME\@</string>
<key>CFBundleDisplayName</key>
<string>\@BUNDLE_NAME\@</string>
<key>CFBundleHelpBookFolder</key>
<string>\@BUNDLE_NAME\@ Manual</string>
<key>CFBundleHelpBookName</key>
<string>OpenStructure Help</string>
<key>CFBundleIconFile</key>
<string>\@BUNDLE_ICON\@</string>
<key>CFBundleIdentifier</key>
<string>\@BUNDLE_IDENTIFIER\@</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string></string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>")
string(CONFIGURE "${info_plist}" info_plist_replaced)
file(WRITE ${FILENAME} "${info_plist_replaced}")
endfunction(create_plist)
#=============================================================================
# function echo_all_cmake_variable_values
#=============================================================================
function(echo_all_cmake_variable_values)
message("")
get_cmake_property(vs VARIABLES)
foreach(v ${vs})
message("${v}='${${v}}'")
endforeach(v)
message("")
endfunction(echo_all_cmake_variable_values)
#=============================================================================
#=============================================================================
# OSX specific functions
#=============================================================================
#=============================================================================
if(APPLE)
#=============================================================================
# function get_dependencies_for_item (OSX)
#=============================================================================
function(get_dependencies_for_item item list_var)
if(NOT IS_ABSOLUTE "${item}" AND EXISTS "${item}")
message(FATAL_ERROR "Cannot find item: '${item}' to get dependencies.")
endif(NOT IS_ABSOLUTE "${item}" AND EXISTS "${item}")
find_program(otool_cmd "otool" PATHS "/usr/local/bin" "/usr/bin")
if(NOT otool_cmd)
message(FATAL_ERROR "Could not find otool - cannot analyze dependencies.")
endif(NOT otool_cmd)
execute_process( COMMAND ${otool_cmd} -L ${item} OUTPUT_VARIABLE otool_cmd_ov RESULT_VARIABLE retcode )
if(retcode)
MESSAGE(FATAL_ERROR "otool stopped with return code: '${retcode}'")
endif(retcode)
# Convert to a list of lines:
string(REGEX REPLACE ";" "\\\\;" candidates "${otool_cmd_ov}")
set(eol_char "E")
string(REGEX REPLACE "\n" "${eol_char};" candidates "${candidates}")
# check for install id and remove it from list, since otool -L can include a reference to itself
set(install_id)
execute_process( COMMAND ${otool_cmd} -D ${item} OUTPUT_VARIABLE install_id_ov RESULT_VARIABLE retcode)
if(retcode)
MESSAGE(FATAL_ERROR "otool stopped with return code: '${retcode}'")
endif(retcode)
# second line is install name
string(REGEX REPLACE ".*:\n" "" install_id "${install_id_ov}")
if(install_id)
string(REGEX MATCH "[^\n ].*[^\n ]" install_id "${install_id}")
endif(install_id)
# Analyze each line for file names that match the regular expression:
set(otool_regex "^\t([^\t]+) \\(compatibility version ([0-9]+.[0-9]+.[0-9]+), current version ([0-9]+.[0-9]+.[0-9]+)\\)${eol_char}$")
set(dep_list)
foreach(candidate ${candidates})
if("${candidate}" MATCHES "${otool_regex}")
# Extract information from each candidate:
string(REGEX REPLACE "${otool_regex}" "\\1" dep "${candidate}")
if(NOT "${dep}" STREQUAL "${install_id}")
list(APPEND dep_list ${dep})
endif(NOT "${dep}" STREQUAL "${install_id}")
endif("${candidate}" MATCHES "${otool_regex}")
endforeach(candidate)
set(${list_var} ${dep_list} PARENT_SCOPE)
endfunction(get_dependencies_for_item)
#=============================================================================
# function get_rpath (OSX)
#=============================================================================
function(get_rpath target rpath_var)
find_program(rpath_exe "otool" PATHS "/usr/local/bin" "/usr/bin")
if(NOT rpath_exe)
message(FATAL_ERROR "Could not find otool - cannot resolve rpath.")
endif(NOT rpath_exe)
execute_process(
COMMAND ${rpath_exe} "-l" ${target}
OUTPUT_VARIABLE rpath_cmd_ov
RESULT_VARIABLE retcode
)
if(retcode)
MESSAGE(FATAL_ERROR "otool stopped with return code: '${retcode}'")
endif(retcode)
set(rpath_cmd_regex ".*LC_RPATH\n *cmdsize [0-9]*\n\ *path ([^\n ]*) \\(offset.*")
if(rpath_cmd_ov MATCHES ${rpath_cmd_regex})
string(REGEX REPLACE ${rpath_cmd_regex} "\\1" rpath ${rpath_cmd_ov})
set(${rpath_var} ${rpath} PARENT_SCOPE)
endif(rpath_cmd_ov MATCHES ${rpath_cmd_regex})
endfunction(get_rpath)
#=============================================================================
# function copy_qt (OSX)
#=============================================================================
function(copy_qt library_dir plugin_dir plugins)
file(COPY "${library_dir}/Resources/qt_menu.nib"
DESTINATION "${CMAKE_INSTALL_PREFIX}/libexec/openstructure/"
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
file(COPY ${plugin_dir}
DESTINATION ${CMAKE_INSTALL_PREFIX}/libexec/openstructure)
file(GLOB_RECURSE QT_PLUGINS "${CMAKE_INSTALL_PREFIX}/libexec/openstructure/*.dylib")
set(${plugins} ${QT_PLUGINS} PARENT_SCOPE)
file(WRITE "${CMAKE_INSTALL_PREFIX}/libexec/openstructure/qt.conf" "[Paths]\nPlugins=../plugins\n")
endfunction(copy_qt)
#=============================================================================
# function is_system_lib (OSX)
#=============================================================================
function(is_system_lib item system_var)
if(item MATCHES "^(/System/Library/|/usr/lib/)")
set(${system_var} 1 PARENT_SCOPE)
else()
set(${system_var} 0 PARENT_SCOPE)
endif()
endfunction(is_system_lib)
#=============================================================================
# function copy_resolved_item (OSX)
#=============================================================================
function(copy_resolved_item resolved_item resolved_embedded_item)
if("${resolved_item}" STREQUAL "${resolved_embedded_item}")
message(STATUS "warning: resolved_item == resolved_embedded_item - not copying...")
else()
message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy ${resolved_item} ${resolved_embedded_item}")
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${resolved_item}" "${resolved_embedded_item}")
endif()
endfunction(copy_resolved_item)
#=============================================================================
# function copy_python (OSX)
#=============================================================================
function(copy_python include_path version new_binary_path)
get_filename_component(real_python_include_path ${include_path} REALPATH)
get_filename_component(python_root_dir ${real_python_include_path}/../.. REALPATH)
file(COPY ${python_root_dir}/${LIB_DIR}/python${version}/ DESTINATION ${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/python${version})
file(GLOB py_config_files "${include_path}/pyconfig*.h")
file(COPY ${py_config_files} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/python${version})
file(GLOB_RECURSE python_so_files "${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/python${version}/*.so")
foreach(so_file ${python_so_files})
file(RPATH_REMOVE FILE "${so_file}")
endforeach(so_file)
read_config(ost_config)
file(COPY ${python_root_dir}/Resources/Python.app/Contents/MacOS/Python DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
set(${new_binary_path} "${CMAKE_INSTALL_PREFIX}/bin/Python" PARENT_SCOPE)
string(REGEX REPLACE "pyexec=\"[^\n\$]*\"" "pyexec=\"\$DNG_BINDIR/Python\"\nexport PYTHONHOME=\$DNG_ROOT" ost_config "${ost_config}")
write_config("${ost_config}")
endfunction(copy_python)
elseif(WIN32 AND NOT UNIX)
#=============================================================================
#=============================================================================
# Windows specific functions
#=============================================================================
#=============================================================================
#=============================================================================
# function get_dependencies_for_item (Windows)
#=============================================================================
function(get_dependencies_for_item item list_var)
if(NOT IS_ABSOLUTE "${item}" AND EXISTS "${item}")
message(FATAL_ERROR "Cannot find item: '${item}' to get dependencies.")
endif(NOT IS_ABSOLUTE "${item}" AND EXISTS "${item}")
find_program(dumpbin_cmd "dumpbin")
if(NOT dumpbin_cmd)
message(FATAL_ERROR "Could not find dumpbin - cannot analyze dependencies.")
return()
endif(NOT dumpbin_cmd)
set(ENV{VS_UNICODE_OUTPUT} "") # Block extra output from inside VS IDE.
execute_process( COMMAND ${dumpbin_cmd} /dependents ${item} OUTPUT_VARIABLE dumpbin_cmd_ov ERROR_VARIABLE dumpbin_cmd_ev RESULT_VARIABLE retcode)
if(retcode)
if(${item} MATCHES "System32")
# 32 bit cmake might run within WOW64, which automatically mangles the path to System32
# dumpbin, which is x86_64 in this case will run with the unmangled path and therefore has to look for
# the 32 bit libraries in SysWOW64 instead of System32
string(REPLACE "System32" "SysWOW64" item ${item})
execute_process( COMMAND ${dumpbin_cmd} /dependents ${item} OUTPUT_VARIABLE dumpbin_cmd_ov ERROR_VARIABLE dumpbin_cmd_ev RESULT_VARIABLE retcode)
endif(${item} MATCHES "System32")
endif(retcode)
if(retcode)
MESSAGE( "dumpbin output: '${dumpbin_cmd_ov}'")
MESSAGE( "dumpbin error output: '${dumpbin_cmd_ev}'")
MESSAGE(FATAL_ERROR "dumpbin stopped with return code: '${retcode}'")
endif(retcode)
# Convert to a list of lines:
string(REGEX REPLACE ";" "\\\\;" candidates "${dumpbin_cmd_ov}")
set(eol_char "E")
string(REGEX REPLACE "\n" "${eol_char};" candidates "${candidates}")
# Analyze each line for file names that match the regular expression:
set(dumpbin_regex "^ ([^ ].*[Dd][Ll][Ll])${eol_char}$")
set(dep_list)
foreach(candidate ${candidates})
if("${candidate}" MATCHES "${dumpbin_regex}")
# Extract information from each candidate:
string(REGEX REPLACE "${dumpbin_regex}" "\\1" dep "${candidate}")
list(APPEND dep_list ${dep})
endif("${candidate}" MATCHES "${dumpbin_regex}")
endforeach(candidate)
set(${list_var} ${dep_list} PARENT_SCOPE)
endfunction(get_dependencies_for_item)
#=============================================================================
# function get_rpath (Windows)
#=============================================================================
function(get_rpath target rpath_var)
message(FATAL_ERROR "get_rpath not implemented for Windows.")
endfunction(get_rpath)
#=============================================================================
# function is_system_lib (Windows)
#=============================================================================
function(is_system_lib item system_var)
string(TOLOWER "${item}" lower)
string(TOLOWER "$ENV{SystemRoot}" sysroot)
string(REGEX REPLACE "\\\\" "/" sysroot "${sysroot}")
string(TOLOWER "$ENV{windir}" windir)
string(REGEX REPLACE "\\\\" "/" windir "${windir}")
if(lower MATCHES "^(${sysroot}/sys(tem|wow)|${windir}/sys(tem|wow)|(.*/)*msvc[^/]+dll)" AND NOT lower MATCHES "python.*dll")
set(${system_var} 1 PARENT_SCOPE)
else()
set(${system_var} 0 PARENT_SCOPE)
endif()
endfunction(is_system_lib)
#=============================================================================
# function copy_resolved_item (Windows)
#=============================================================================
function(copy_resolved_item resolved_item resolved_embedded_item)
# ignore case on Windows
string(TOLOWER "${resolved_item}" resolved_item_compare)
string(TOLOWER "${resolved_embedded_item}" resolved_embedded_item_compare)
if("${resolved_item_compare}" STREQUAL "${resolved_embedded_item_compare}")
message(STATUS "warning: resolved_item == resolved_embedded_item - not copying...")
else()
message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy ${resolved_item} ${resolved_embedded_item}")
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${resolved_item}" "${resolved_embedded_item}")
endif()
endfunction(copy_resolved_item)
#=============================================================================
# function copy_python (Windows)
#=============================================================================
function(copy_python include_path version new_binary_path)
get_filename_component(real_python_include_path ${include_path} REALPATH)
get_filename_component(python_root_dir ${real_python_include_path}/.. REALPATH)
file(GLOB lib_files "${python_root_dir}/Lib/*")
file(COPY ${lib_files} DESTINATION ${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/python${version})
file(GLOB dll_files "${python_root_dir}/DLLs/*")
file(COPY ${dll_files} DESTINATION ${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/python${version})
file(GLOB py_config_files "${include_path}/pyconfig*.h")
file(COPY ${py_config_files} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/python${version})
file(COPY ${python_root_dir}/python.exe DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
set(${new_binary_path} "${CMAKE_INSTALL_PREFIX}/bin/python.exe" PARENT_SCOPE)
# copy msvc90 CRT for python
get_filename_component(msvc90_dir "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0;InstallDir]" ABSOLUTE)
get_filename_component(msvc90_express_dir "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\9.0;InstallDir]" ABSOLUTE)
find_path(msvc_redist_dir NAMES x86/Microsoft.VC90.CRT/Microsoft.VC90.CRT.manifest
PATHS
"${msvc90_dir}/../../VC/redist"
"${msvc90_express_dir}/../../VC/redist"
"C:/Program Files/Microsoft Visual Studio 9.0/VC/redist"
"C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/redist"
)
set(msvc90_crt_dir "${msvc_redist_dir}/x86/Microsoft.VC90.CRT")
file(COPY "${msvc90_crt_dir}/Microsoft.VC90.CRT.manifest"
"${msvc90_crt_dir}/msvcm90.dll"
"${msvc90_crt_dir}/msvcp90.dll"
"${msvc90_crt_dir}/msvcr90.dll"
DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
endfunction(copy_python)
#=============================================================================
# function copy_qt (Windows)
#=============================================================================
function(copy_qt library_dir plugin_dir plugins)
file(COPY ${plugin_dir}
DESTINATION ${CMAKE_INSTALL_PREFIX}/libexec/openstructure)
file(GLOB_RECURSE QT_PLUGINS "${CMAKE_INSTALL_PREFIX}/libexec/openstructure/*.dll")
set(${plugins} ${QT_PLUGINS} PARENT_SCOPE)
file(WRITE "${CMAKE_INSTALL_PREFIX}/libexec/openstructure/qt.conf" "[Paths]\nPlugins=../plugins\n")
endfunction(copy_qt)
elseif(UNIX)
#=============================================================================
#=============================================================================
# Linux specific functions
#=============================================================================
#=============================================================================
#=============================================================================
# function get_dependencies_for_item (Linux)
#=============================================================================
function(get_dependencies_for_item item list_var)
if(NOT IS_ABSOLUTE "${item}" AND EXISTS "${item}")
message(FATAL_ERROR "Cannot find item: '${item}' to get dependencies.")
endif(NOT IS_ABSOLUTE "${item}" AND EXISTS "${item}")
find_program(ldd_cmd "ldd" PATHS "/usr/local/bin" "/usr/bin")
if(NOT ldd_cmd)
message(FATAL_ERROR "Could not find ldd - cannot analyze dependencies.")
return()
endif(NOT ldd_cmd)
set(old_ld_library_path $ENV{LD_LIBRARY_PATH})
set(ENV{LD_LIBRARY_PATH} "${CMAKE_INSTALL_PREFIX}/${LIB_DIR}:$ENV{LD_LIBRARY_PATH}")
execute_process( COMMAND ${ldd_cmd} ${item} OUTPUT_VARIABLE ldd_cmd_ov ERROR_VARIABLE ldd_cmd_ev RESULT_VARIABLE retcode)
set(ENV{LD_LIBRARY_PATH} ${old_ld_library_path})
if(retcode)
if(${ldd_cmd_ov})
message(${ldd_cmd_ov})
endif(${ldd_cmd_ov})
if(${ldd_cmd_ev})
message(${ldd_cmd_ev})
endif(${ldd_cmd_ev})
message("command:'${ldd_cmd}' '${item}'")
message(FATAL_ERROR "ldd stopped with return code: '${retcode}'")
endif(retcode)
# Convert to a list of lines:
string(REGEX REPLACE ";" "\\\\;" candidates "${ldd_cmd_ov}")
set(eol_char "E")
string(REGEX REPLACE "\n" "${eol_char};" candidates "${candidates}")
# Analyze each line for file names that match the regular expression:
set(ldd_regex "^[\t ]*[^\t ]+ => ([^\t\(]+) .*${eol_char}$")
set(ldd_regex_error "not found${eol_char}$")
set(ldd_regex_fallback "^[\t ]*([^\t ]+) => ([^\t ]+).*${eol_char}$")
set(dep_list)
foreach(candidate ${candidates})
if("${candidate}" MATCHES "${ldd_regex}")
# Extract information from each candidate:
if("${candidate}" MATCHES "${ldd_regex_error}")
string(REGEX REPLACE "${ldd_regex_fallback}" "\\1" dep "${candidate}")
else("${candidate}" MATCHES "${ldd_regex_error}")
string(REGEX REPLACE "${ldd_regex}" "\\1" dep "${candidate}")
endif("${candidate}" MATCHES "${ldd_regex_error}")
list(APPEND dep_list ${dep})
endif("${candidate}" MATCHES "${ldd_regex}")
endforeach(candidate)
set(${list_var} ${dep_list} PARENT_SCOPE)
endfunction(get_dependencies_for_item)
#=============================================================================
# function get_rpath (Linux)
#=============================================================================
function(get_rpath target rpath_var)
find_program(rpath_exe "readelf" PATHS "/usr/local/bin" "/usr/bin")
if(NOT rpath_exe)
message(FATAL_ERROR "Could not find readelf - cannot resolve rpath.")
endif(NOT rpath_exe)
execute_process(
COMMAND ${rpath_exe} "-d" ${target}
OUTPUT_VARIABLE rpath_cmd_ov
RESULT_VARIABLE retcode
)
if(retcode)
MESSAGE(FATAL_ERROR "readelf stopped with return code: '${retcode}'")
endif(retcode)
set(rpath_cmd_regex "Library rpath: \[([^\n ]*):\]")
if(rpath_cmd_ov MATCHES ${rpath_cmd_regex})
string(REGEX REPLACE ${rpath_cmd_regex} "\\1" rpath ${rpath_cmd_ov})
set(${rpath_var} ${rpath} PARENT_SCOPE)
endif(rpath_cmd_ov MATCHES ${rpath_cmd_regex})
endfunction(get_rpath)
#=============================================================================
# function copy_qt (Linux)
#=============================================================================
function(copy_qt library_dir plugin_dir plugins)
file(COPY ${plugin_dir}
DESTINATION ${CMAKE_INSTALL_PREFIX}/libexec/openstructure)
file(GLOB_RECURSE QT_PLUGINS "${CMAKE_INSTALL_PREFIX}/libexec/openstructure/*.so")
foreach(plugin ${QT_PLUGINS})
remove_rpath("${plugin}")
endforeach(plugin)
set(${plugins} ${QT_PLUGINS} PARENT_SCOPE)
file(WRITE "${CMAKE_INSTALL_PREFIX}/libexec/openstructure/qt.conf" "[Paths]\nPlugins=../plugins\n")
endfunction(copy_qt)
#=============================================================================
# function is_system_lib (Linux)
#=============================================================================
function(is_system_lib item system_var)
if(item MATCHES "/cmov/|ld-linux[\\.\\-]|libc[\\.\\-]|libdl[\\.\\-]|libdrm[\\.\\-]|libelf[\\.\\-]|libexpat[\\.\\-]|libfontconfig[\\.\\-]|libfreetype[\\.\\-]|libg[\\.\\-]|libgcc_s[\\.\\-]|libGL[\\.\\-]|libglib[\\.\\-]|libgthread[\\.\\-]|lib(ice|ICE)[\\.\\-]|libnvidia[\\.\\-]|libpthread[\\.\\-]|libse(pol|linux)[\\.\\-]|libSM[\\.\\-]|libstdc\\+\\+[\\.\\-]|libX[a-zA-Z0-9]*[\\.\\-]|libxcb[\\.\\-]|pylibc[\\.\\-]")
set(${system_var} 1 PARENT_SCOPE)
else()
set(${system_var} 0 PARENT_SCOPE)
endif()
endfunction(is_system_lib)
#=============================================================================
# function copy_resolved_item (Linux)
#=============================================================================
function(copy_resolved_item resolved_item resolved_embedded_item)
get_filename_component(real_resolved_item "${resolved_item}" REALPATH)
get_filename_component(real_resolved_embedded_item "${resolved_embedded_item}" REALPATH)
if("${real_resolved_item}" STREQUAL "${real_resolved_embedded_item}")
message(STATUS "warning: resolved_item == resolved_embedded_item - not copying...")
else()
message(STATUS "copying ${resolved_item} to ${resolved_embedded_item} including symlinks")
# determine all the symlinks pointing to the current item and copy them into the package
# along with the item
get_filename_component(external_path ${real_resolved_item} PATH)
get_filename_component(embedded_path ${real_resolved_embedded_item} PATH)
get_filename_component(external_name ${real_resolved_item} NAME)
string(REGEX REPLACE "([a-zA-Z]+).*" "\\1" name_base ${external_name})
file(GLOB candidates "${external_path}/${name_base}*" )
set(external_files)
foreach(candidate ${candidates})
get_filename_component(real_candidate "${candidate}" REALPATH)
if(real_candidate STREQUAL ${real_resolved_item})
list(APPEND external_files ${candidate})
endif(real_candidate STREQUAL ${real_resolved_item})
endforeach(candidate)
file(COPY ${external_files} DESTINATION ${embedded_path})
remove_rpath("${real_resolved_embedded_item}")
endif()
endfunction(copy_resolved_item)
#=============================================================================
# function copy_python (Linux)
#=============================================================================
function(copy_python include_path version new_binary_path)
get_filename_component(real_python_include_path ${include_path} REALPATH)
get_filename_component(python_root_dir ${real_python_include_path}/../.. REALPATH)
file(COPY ${python_root_dir}/${LIB_DIR}/python${version}/ DESTINATION ${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/python${version})
file(GLOB py_config_files "${include_path}/pyconfig*.h")
file(COPY ${py_config_files} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/python${version})
file(GLOB_RECURSE python_so_files "${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/python${version}/*.so")
foreach(so_file ${python_so_files})
file(RPATH_REMOVE FILE "${so_file}")
endforeach(so_file)
read_config(ost_config)
file(GLOB python_libs "${python_root_dir}/${LIB_DIR}/libpython${version}.so*")
file(COPY ${python_libs} DESTINATION ${CMAKE_INSTALL_PREFIX}/${LIB_DIR})
file(COPY ${python_root_dir}/bin/python${version} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
set(${new_binary_path} "${CMAKE_INSTALL_PREFIX}/bin/python${version}" PARENT_SCOPE)
string(REGEX REPLACE "pyexec=\"[^\n\$]*\"" "pyexec=\"\$DNG_BINDIR/python${version}\"\nexport PYTHONHOME=\$DNG_ROOT" ost_config "${ost_config}")
write_config("${ost_config}")
endfunction(copy_python)
#=============================================================================
# function remove_rpath (Linux)
#=============================================================================
function(remove_rpath file)
execute_process(COMMAND stat --format %a "${file}" OUTPUT_VARIABLE permissions)
execute_process(COMMAND chmod ugo+x "${file}")
string(SUBSTRING ${permissions} 0 3 permissions)
file(RPATH_REMOVE FILE "${file}")
execute_process(COMMAND chmod ${permissions} "${file}")
endfunction(remove_rpath)
else(APPLE)
MESSAGE("Unknown platform, deployment will not work.")
endif(APPLE)