Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Setup CMake to build for macOS
[xestiaab/.git] / source / CMakeFunctions / CopyLibraries.cmake
1 # list command no longer ignores empty elements
2 cmake_policy(SET CMP0007 NEW)
4 function(Execute)
5     list(POP_FRONT ARGV outlist)
7     execute_process(
8         COMMAND ${ARGV}
9         OUTPUT_VARIABLE cmd_out
10         OUTPUT_STRIP_TRAILING_WHITESPACE
11     )
13     string(REPLACE "\n" ";" cmd_out "${cmd_out}")
14     list(TRANSFORM cmd_out STRIP)
15     set(${outlist} ${cmd_out} PARENT_SCOPE)
16 endfunction()
18 function(GatherRuntimePaths source)
19     Execute(output otool -l ${source})
21     set (line_index 0)
22     foreach (line ${output})
23         if(line MATCHES "^.*cmd LC_RPATH")
24             set(line_index 1)
25             continue()
26         endif()
28         if (line_index EQUAL 1)
29             set(line_index 2)
30             continue()
31         endif()
33         if (line_index EQUAL 2)
34             string(REGEX REPLACE "^.*path" "" extracted_path ${line})
35             string(REGEX REPLACE "\\(offset .*\\)$" "" extracted_path ${extracted_path})
36             string(STRIP ${extracted_path} extracted_path)
37             list(APPEND runpaths ${extracted_path})
38             set(line_index 0)
39             continue()
40         endif()
41     endforeach()
43     set(runpaths ${runpaths} PARENT_SCOPE)
44 endfunction()
46 function(GatherSFMLLibrariesForCopying libraries postcmds)
47    foreach(library ${libraries})
48        Execute(output otool -L ${library})
50        foreach(line ${output})
51            if(line MATCHES "^.*libsfml.*.[^0-9].[^0-9].[^0-9].*\\.dylib ")
52                 string(REGEX REPLACE "dylib .*" "dylib" line "${line}")
54                 if(line MATCHES "^@rpath/")
55                     get_filename_component(refname "${line}" NAME)
56                     list(APPEND postcmds "sh -c 'install_name_tool -change ${line} @executable_path/../Frameworks/${refname} ${library}'")
57                     list(APPEND libs ${dylib_location})
58                 endif()
59            elseif(line MATCHES "^@rpath/../Frameworks/.*.framework/Versions/.*/.*")
60                 string(REGEX MATCH "^@rpath/../Frameworks/(.*)/Versions/.*$" _ ${line})
61                 list(APPEND frameworksToCopy ${CMAKE_MATCH_1})
62            endif()
63        endforeach()
64    endforeach()
66     set(postcmds ${postcmds} PARENT_SCOPE)
67     set(frameworksToCopy ${frameworksToCopy} PARENT_SCOPE)
68 endfunction()
70 function (InstallSFMLDependencies frameworks postcmds destination)
71     foreach (framework ${frameworks})
72         unset(frameworkLocation)
73         string(REGEX MATCH "(.*).framework" _ ${framework})
74         string(APPEND frameworkLocation ${SFML_FRAMEWORKS_LOCATION} "/" ${framework})
75         file(INSTALL ${frameworkLocation} DESTINATION ${destination})
76     endforeach()
77 endfunction()
79 function(AdjustSFMLDependencies libraries destination)
80     foreach (libraryFilename ${libraries})
81         string(REGEX MATCH "(.*).framework" _ ${libraryFilename})
82         string(CONCAT libraryName ${CMAKE_MATCH_1})
83         string(CONCAT frameworkLocation ${destination} "/" ${libraryFilename} "/" ${libraryName})
84         Execute(output otool -L ${frameworkLocation})
86         foreach (oldLocation ${output})
87             string(REGEX REPLACE " \\\(compatibility .*" "" oldLocation ${oldLocation})
88             if(oldLocation MATCHES "^@rpath")
89                 string(REPLACE "@rpath/" "@executable_path/" newLocation ${oldLocation})
90                 execute_process(
91                    COMMAND sh -c "install_name_tool -change ${oldLocation} ${newLocation} ${frameworkLocation}"
92                    COMMAND_ECHO STDOUT
93                 )
94             endif()
95         endforeach()
96     endforeach()
97 endfunction()
99 function(AdjustSFMLLibraries libraries)
100     foreach(library ${libraries})
101         Execute(output otool -L ${library})
103         foreach(oldLocation ${output})
104             string(REGEX REPLACE " \\\(compatibility .*" "" oldLocation ${oldLocation})
105             if(oldLocation MATCHES "^@rpath")
106                 string(REPLACE "@rpath/" "@executable_path/" newLocation ${oldLocation})
107                 execute_process(
108                    COMMAND sh -c "install_name_tool -change ${oldLocation} ${newLocation} ${library}"
109                    COMMAND_ECHO STDOUT
110                 )
111             endif()
112         endforeach()
113     endforeach()
114 endfunction()
116 function(GatherLibrariesForCopying source)
117     if (CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin")
118         # Gather runtime paths first.
119         if(NOT source MATCHES "^@rpath")
120             GatherRuntimePaths(${source})
121         endif()
123         Execute(output otool -L ${source})
125         get_filename_component(LibraryName "${source}" NAME)
126     
127         if(LibraryName MATCHES ".*dylib")
128             string(PREPEND LibraryName "${DST}/")
129         else()
130             set(LibraryName "${source}")
131         endif()
133         foreach (line ${output})
134             if(line MATCHES "^@rpath/../Frameworks/.*.framework/Versions/.*/.*")
135                 continue()
136             endif()
138             if(line MATCHES "^@rpath")
139                 string(REGEX REPLACE "^@rpath/" "" filename ${line})
140                 string(REGEX REPLACE "dylib .*" "dylib" filename ${filename})
142                 set(dylib_found 0)                
143                 foreach (runpath ${runpaths})
144                     string(CONCAT dylib_location ${runpath} "/" ${filename})
145                     if (EXISTS ${dylib_location})
146                         set(dylib_location ${dylib_location} PARENT_SCOPE)
147                         set(dylib_found 1)
148                         break()
149                     endif()
150                 endforeach()
152                 if(dylib_found EQUAL 0)
153                     message(FATAL_ERROR "Unable to find dynamic library ${filename} within the runtime paths.")
154                 endif()
155             endif()
157             # Dynamic Libraries
158             if(line MATCHES "^.*libwx.*\\.dylib " )
159                 string(REGEX REPLACE "dylib .*" "dylib" line "${line}")
160                 if(NOT line STREQUAL "${source}" AND NOT line MATCHES "@executable")
161                     set(lib ${line})
162                     if(line MATCHES "^@rpath/")
163                         list(APPEND libs ${dylib_location})
164                     else()
165                         list(APPEND libs ${lib})
166                     endif()
167                     get_filename_component(refname "${lib}" NAME)
168                     list(APPEND postcmds "sh -c 'install_name_tool -change ${lib} @executable_path/../Frameworks/${refname} ${LibraryName}'")
169                     
170                     GatherLibrariesForCopying(${lib})
171                 endif()
172             elseif(line MATCHES "^.*libsfml.*.[^0-9].[^0-9].[^0-9].*\\.dylib ")
173                 string(REGEX REPLACE "dylib .*" "dylib" line "${line}")
174                 set(lib ${line})
175                 if(line MATCHES "^@rpath/")
176                     get_filename_component(refname "${dylib_location}" NAME)
177                     list(APPEND postcmds "sh -c 'install_name_tool -change ${lib} @executable_path/../Frameworks/${refname} ${LibraryName}'")
178                     list(APPEND libs ${dylib_location})
179                 elseif(line MATCHES "^@executable_path/")
180                     continue()
181                 else()
182                     get_filename_component(refname "${lib}" NAME)
183                     list(APPEND postcmds "sh -c 'install_name_tool -change ${lib} @executable_path/../Frameworks/${refname} ${LibraryName}'")
184                     list(APPEND libs ${lib})
185                 endif()
186                 get_filename_component(libraryPath "${LibraryName}" DIRECTORY)
187                 string(APPEND libraryPath "/../Frameworks/${refname}")
188                 list(APPEND sfmllibs ${libraryPath})
189             elseif(line MATCHES "^.*libcurl.[0-9]\\.dylib " OR
190                    line MATCHES "^.*libxml2.[0-9]\\.dylib ")
191                 string(REGEX REPLACE "dylib .*" "dylib" line "${line}")
192                 set(lib ${line})
194                 if(line MATCHES "^@rpath/")
195                     get_filename_component(refname "${dylib_location}" NAME)
196                     list(APPEND postcmds "sh -c 'install_name_tool -change ${lib} @executable_path/../Frameworks/${refname} ${LibraryName}'")
197                     list(APPEND libs ${dylib_location})
198                 elseif(line MATCHES "^@executable_path/")
199                     continue()
200                 else()
201                     get_filename_component(refname "${lib}" NAME)
202                     list(APPEND postcmds "sh -c 'install_name_tool -change ${lib} @executable_path/../Frameworks/${refname} ${LibraryName}'")
203                     list(APPEND libs ${lib})
204                 endif()
205             endif()
206         endforeach()
207     endif()
209     set(libs ${libs} PARENT_SCOPE)
210     set(sfmllibs ${sfmllibs} PARENT_SCOPE)
211     set(postcmds ${postcmds} PARENT_SCOPE)
212 endfunction()
214 GatherLibrariesForCopying(${SRC})
216 list(REMOVE_DUPLICATES libs)
217 file(INSTALL ${libs} DESTINATION ${DST} FOLLOW_SYMLINK_CHAIN)
219 GatherSFMLLibrariesForCopying("${sfmllibs}" "${postcmds}")
220 InstallSFMLDependencies("${frameworksToCopy}" "${postcmds}" "${DST}")
222 foreach(cmd ${postcmds})
223     execute_process(
224         COMMAND sh -c "${cmd}"
225         COMMAND_ECHO STDOUT
226     )
227 endforeach()
229 AdjustSFMLLibraries("${sfmllibs}")
230 AdjustSFMLDependencies("${frameworksToCopy}" ${DST})
Xestia Software Development
Yn Maystri
© 2006 - 2019 Xestia Software Development
Software

Xestia Address Book
Xestia Calendar
Development

Xestia Gelforn
Everything else

About
News
Privacy Policy