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