# list command no longer ignores empty elements cmake_policy(SET CMP0007 NEW) function(Execute) list(POP_FRONT ARGV outlist) execute_process( COMMAND ${ARGV} OUTPUT_VARIABLE cmd_out OUTPUT_STRIP_TRAILING_WHITESPACE ) string(REPLACE "\n" ";" cmd_out "${cmd_out}") list(TRANSFORM cmd_out STRIP) set(${outlist} ${cmd_out} PARENT_SCOPE) endfunction() function(GatherRuntimePaths source) Execute(output otool -l ${source}) set (line_index 0) foreach (line ${output}) if(line MATCHES "^.*cmd LC_RPATH") set(line_index 1) continue() endif() if (line_index EQUAL 1) set(line_index 2) continue() endif() if (line_index EQUAL 2) string(REGEX REPLACE "^.*path" "" extracted_path ${line}) string(REGEX REPLACE "\\(offset .*\\)$" "" extracted_path ${extracted_path}) string(STRIP ${extracted_path} extracted_path) list(APPEND runpaths ${extracted_path}) set(line_index 0) continue() endif() endforeach() set(runpaths ${runpaths} PARENT_SCOPE) endfunction() function(GatherSFMLLibrariesForCopying libraries postcmds) foreach(library ${libraries}) Execute(output otool -L ${library}) foreach(line ${output}) if(line MATCHES "^.*libsfml.*.[^0-9].[^0-9].[^0-9].*\\.dylib ") string(REGEX REPLACE "dylib .*" "dylib" line "${line}") if(line MATCHES "^@rpath/") get_filename_component(refname "${line}" NAME) list(APPEND postcmds "sh -c 'install_name_tool -change ${line} @executable_path/../Frameworks/${refname} ${library}'") list(APPEND libs ${dylib_location}) endif() elseif(line MATCHES "^@rpath/../Frameworks/.*.framework/Versions/.*/.*") string(REGEX MATCH "^@rpath/../Frameworks/(.*)/Versions/.*$" _ ${line}) list(APPEND frameworksToCopy ${CMAKE_MATCH_1}) endif() endforeach() endforeach() set(postcmds ${postcmds} PARENT_SCOPE) set(frameworksToCopy ${frameworksToCopy} PARENT_SCOPE) endfunction() function (InstallSFMLDependencies frameworks postcmds destination) foreach (framework ${frameworks}) unset(frameworkLocation) string(REGEX MATCH "(.*).framework" _ ${framework}) string(APPEND frameworkLocation ${SFML_FRAMEWORKS_LOCATION} "/" ${framework}) file(INSTALL ${frameworkLocation} DESTINATION ${destination}) endforeach() endfunction() function(AdjustSFMLDependencies libraries destination) foreach (libraryFilename ${libraries}) string(REGEX MATCH "(.*).framework" _ ${libraryFilename}) string(CONCAT libraryName ${CMAKE_MATCH_1}) string(CONCAT frameworkLocation ${destination} "/" ${libraryFilename} "/" ${libraryName}) Execute(output otool -L ${frameworkLocation}) foreach (oldLocation ${output}) string(REGEX REPLACE " \\\(compatibility .*" "" oldLocation ${oldLocation}) if(oldLocation MATCHES "^@rpath") string(REPLACE "@rpath/" "@executable_path/" newLocation ${oldLocation}) execute_process( COMMAND sh -c "install_name_tool -change ${oldLocation} ${newLocation} ${frameworkLocation}" COMMAND_ECHO STDOUT ) endif() endforeach() endforeach() endfunction() function(AdjustSFMLLibraries libraries) foreach(library ${libraries}) Execute(output otool -L ${library}) foreach(oldLocation ${output}) string(REGEX REPLACE " \\\(compatibility .*" "" oldLocation ${oldLocation}) if(oldLocation MATCHES "^@rpath") string(REPLACE "@rpath/" "@executable_path/" newLocation ${oldLocation}) execute_process( COMMAND sh -c "install_name_tool -change ${oldLocation} ${newLocation} ${library}" COMMAND_ECHO STDOUT ) endif() endforeach() endforeach() endfunction() function(GatherLibrariesForCopying source) if (CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin") # Gather runtime paths first. if(NOT source MATCHES "^@rpath") GatherRuntimePaths(${source}) endif() Execute(output otool -L ${source}) get_filename_component(LibraryName "${source}" NAME) if(LibraryName MATCHES ".*dylib") string(PREPEND LibraryName "${DST}/") else() set(LibraryName "${source}") endif() foreach (line ${output}) if(line MATCHES "^@rpath/../Frameworks/.*.framework/Versions/.*/.*") continue() endif() if(line MATCHES "^@rpath") string(REGEX REPLACE "^@rpath/" "" filename ${line}) string(REGEX REPLACE "dylib .*" "dylib" filename ${filename}) set(dylib_found 0) foreach (runpath ${runpaths}) string(CONCAT dylib_location ${runpath} "/" ${filename}) if (EXISTS ${dylib_location}) set(dylib_location ${dylib_location} PARENT_SCOPE) set(dylib_found 1) break() endif() endforeach() if(dylib_found EQUAL 0) message(FATAL_ERROR "Unable to find dynamic library ${filename} within the runtime paths.") endif() endif() # Dynamic Libraries if(line MATCHES "^.*libwx.*\\.dylib " ) string(REGEX REPLACE "dylib .*" "dylib" line "${line}") if(NOT line STREQUAL "${source}" AND NOT line MATCHES "@executable") set(lib ${line}) if(line MATCHES "^@rpath/") list(APPEND libs ${dylib_location}) else() list(APPEND libs ${lib}) endif() get_filename_component(refname "${lib}" NAME) list(APPEND postcmds "sh -c 'install_name_tool -change ${lib} @executable_path/../Frameworks/${refname} ${LibraryName}'") GatherLibrariesForCopying(${lib}) endif() elseif(line MATCHES "^.*libsfml.*.[^0-9].[^0-9].[^0-9].*\\.dylib ") string(REGEX REPLACE "dylib .*" "dylib" line "${line}") set(lib ${line}) if(line MATCHES "^@rpath/") get_filename_component(refname "${dylib_location}" NAME) list(APPEND postcmds "sh -c 'install_name_tool -change ${lib} @executable_path/../Frameworks/${refname} ${LibraryName}'") list(APPEND libs ${dylib_location}) elseif(line MATCHES "^@executable_path/") continue() else() get_filename_component(refname "${lib}" NAME) list(APPEND postcmds "sh -c 'install_name_tool -change ${lib} @executable_path/../Frameworks/${refname} ${LibraryName}'") list(APPEND libs ${lib}) endif() get_filename_component(libraryPath "${LibraryName}" DIRECTORY) string(APPEND libraryPath "/../Frameworks/${refname}") list(APPEND sfmllibs ${libraryPath}) elseif(line MATCHES "^.*libcurl.[0-9]\\.dylib " OR line MATCHES "^.*libxml2.[0-9]\\.dylib ") string(REGEX REPLACE "dylib .*" "dylib" line "${line}") set(lib ${line}) if(line MATCHES "^@rpath/") get_filename_component(refname "${dylib_location}" NAME) list(APPEND postcmds "sh -c 'install_name_tool -change ${lib} @executable_path/../Frameworks/${refname} ${LibraryName}'") list(APPEND libs ${dylib_location}) elseif(line MATCHES "^@executable_path/") continue() else() get_filename_component(refname "${lib}" NAME) list(APPEND postcmds "sh -c 'install_name_tool -change ${lib} @executable_path/../Frameworks/${refname} ${LibraryName}'") list(APPEND libs ${lib}) endif() endif() endforeach() endif() set(libs ${libs} PARENT_SCOPE) set(sfmllibs ${sfmllibs} PARENT_SCOPE) set(postcmds ${postcmds} PARENT_SCOPE) endfunction() GatherLibrariesForCopying(${SRC}) list(REMOVE_DUPLICATES libs) file(INSTALL ${libs} DESTINATION ${DST} FOLLOW_SYMLINK_CHAIN) GatherSFMLLibrariesForCopying("${sfmllibs}" "${postcmds}") InstallSFMLDependencies("${frameworksToCopy}" "${postcmds}" "${DST}") foreach(cmd ${postcmds}) execute_process( COMMAND sh -c "${cmd}" COMMAND_ECHO STDOUT ) endforeach() AdjustSFMLLibraries("${sfmllibs}") AdjustSFMLDependencies("${frameworksToCopy}" ${DST})