1# Copy library during build and, on the Mac, modify the dependent 2# library paths. 3# 4# Defines required: 5# 6# SRC source library name 7# DST destination directory 8# 9 10# enable IN_LIST operator 11cmake_policy(SET CMP0057 NEW) 12 13message( "==================================================================" ) 14message( "Copying shared libraries:" ) 15message( "==================================================================" ) 16 17# list command no longer ignores empty elements. 18cmake_policy( SET CMP0007 NEW ) 19 20function( execute ) 21 list( POP_FRONT ARGV outlist ) 22 23 execute_process( 24 COMMAND 25 ${ARGV} 26 OUTPUT_VARIABLE 27 cmd_out 28# COMMAND_ECHO STDOUT 29 OUTPUT_STRIP_TRAILING_WHITESPACE 30 ) 31 32#message("OUTPUT\n${cmd_out}") 33 34 # Convert output to list and strip 35 string( REPLACE "\n" ";" cmd_out "${cmd_out}" ) 36 list( TRANSFORM cmd_out STRIP ) 37 38 set( ${outlist} ${cmd_out} PARENT_SCOPE ) 39endfunction() 40 41set( VISITED ) 42set( postcmds ) 43function( gather_libs src ) 44 list( APPEND VISITED "${src}" ) 45 if( CMAKE_HOST_SYSTEM_NAME MATCHES "Windows" ) 46 execute( output cmd /k dumpbin /dependents ${src} ) 47 48 foreach( line ${output} ) 49 set( lib ${WXWIN}/${line} ) 50 51 if( EXISTS "${lib}" AND NOT "${lib}" IN_LIST VISITED ) 52 list( APPEND libs ${lib} ) 53 54 gather_libs( ${lib} ) 55 elseif ( EXISTS "${DST}/${line}" AND NOT "${DST}/${line}" IN_LIST VISITED ) 56 gather_libs( "${DST}/${line}" ) 57 endif() 58 endforeach() 59 elseif( CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin" ) 60 message(STATUS "Checking ${src} for libraries...") 61 62 execute( output otool -L ${src} ) 63 64 set( libname "${src}" ) 65 66 set( words ) 67 foreach( line ${output} ) 68 if( line MATCHES "^.*\\.dylib " ) 69 string( REGEX REPLACE "dylib .*" "dylib" line "${line}" ) 70 71 get_filename_component( dylib_name "${line}" NAME) 72 73 message(STATUS "Checking out ${line}") 74 set( lib "${WXWIN}/${dylib_name}" ) 75 76 if( NOT lib STREQUAL "${src}" AND NOT line MATCHES "@executable" AND EXISTS "${lib}" ) 77 message(STATUS "\tProcessing ${lib}...") 78 79 list( APPEND libs ${lib} ) 80 81 get_filename_component( refname "${lib}" NAME ) 82 83 message(STATUS "\t\tAdding ${refname} to ${src}") 84 85 list( APPEND words "-change ${line} @executable_path/../Frameworks/${refname}" ) 86 87 if( 88 # Don't do depth first search from modules: assume the fixup 89 # of .dylib libraries was already done when this function 90 # was visited for the executable 91 NOT src MATCHES "\\.so$" 92 AND NOT "${lib}" IN_LIST VISITED 93 ) 94 gather_libs( ${lib} ) 95 endif() 96 endif() 97 endif() 98 endforeach() 99 if( words ) 100 # There is at least one dependency to rename 101 list( PREPEND words "install_name_tool" ) 102 list( APPEND words "${src}" ) 103 string( JOIN " " postcmd ${words} ) 104 list( APPEND postcmds "${postcmd}" ) 105 endif() 106 elseif( CMAKE_HOST_SYSTEM_NAME MATCHES "Linux" ) 107 message(STATUS "Executing LD_LIBRARY_PATH='${WXWIN}' ldd ${src}") 108 109 execute( output sh -c "LD_LIBRARY_PATH='${WXWIN}' ldd ${src}" ) 110 111 get_filename_component( libname "${src}" NAME ) 112 113 foreach( line ${output} ) 114 string( REGEX REPLACE "(.*) => .* \\(.*$" "\\1" line "${line}" ) 115 116 message (STATUS "\tChecking ${line}...") 117 118 set(line "${WXWIN}/${line}") 119 120 if (EXISTS "${line}" AND NOT "${line}" IN_LIST VISITED) 121 message (STATUS "\tAdding ${line}...") 122 123 set( lib ${line} ) 124 125 list( APPEND libs ${lib} ) 126 127 gather_libs( ${lib} ) 128 endif() 129 130 endforeach() 131 endif() 132 133 set( libs ${libs} PARENT_SCOPE ) 134 set( postcmds ${postcmds} PARENT_SCOPE ) 135 set( VISITED ${VISITED} PARENT_SCOPE ) 136endfunction() 137 138gather_libs( "${SRC}" ) 139 140list( REMOVE_DUPLICATES postcmds ) 141 142foreach( cmd ${postcmds} ) 143 execute_process( 144 COMMAND 145 sh -c "${cmd}" 146 COMMAND_ECHO STDOUT 147 ) 148endforeach() 149 150# This .cmake file is invoked on Darwin for modules too. 151# Do the INSTALL only for the executable. 152if( NOT SRC MATCHES "\\.so$" ) 153 list( REMOVE_DUPLICATES libs ) 154 file( INSTALL ${libs} DESTINATION ${DST} FOLLOW_SYMLINK_CHAIN ) 155endif() 156