Backported #6865: Disable websockets command line option
[platform/upstream/freerdp.git] / cmake / MergeStaticLibs.cmake
1  
2 #    Copyright (C) 2012 Modelon AB
3
4 #    This program is free software: you can redistribute it and/or modify
5 #    it under the terms of the BSD style license.
6
7 #    This program is distributed in the hope that it will be useful,
8 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
9 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 #    FMILIB_License.txt file for more details.
11
12 #    You should have received a copy of the FMILIB_License.txt file
13 #    along with this program. If not, contact Modelon AB <http://www.modelon.com>.
14
15 # Merge_static_libs(output_library lib1 lib2 ... libn) merges a number of static
16 # libs into a single static library
17 function(merge_static_libs output_library)
18         set(output_target "${output_library}")
19         string(REGEX REPLACE "-" "_" output_library ${output_library})
20         set(libs ${ARGV})
21         list(REMOVE_AT libs 0)
22         
23         # Create a dummy file that the target will depend on
24         set(dummyfile ${CMAKE_CURRENT_BINARY_DIR}/${output_library}_dummy.c)
25         file(WRITE ${dummyfile} "const char * dummy = \"${dummyfile}\";")
26         
27         add_library(${output_target} STATIC ${dummyfile})
28
29         if("${CMAKE_CFG_INTDIR}" STREQUAL ".")
30                 set(multiconfig FALSE)
31         else()
32                 set(multiconfig TRUE)
33         endif()
34         
35         # First get the file names of the libraries to be merged        
36         foreach(lib ${libs})
37                 get_target_property(libtype ${lib} TYPE)
38                 if(NOT libtype STREQUAL "STATIC_LIBRARY")
39                         message(FATAL_ERROR "Merge_static_libs can only process static libraries")
40                 endif()
41                 if(multiconfig)
42                         foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES})
43                                 get_target_property("libfile_${CONFIG_TYPE}" ${lib} "LOCATION_${CONFIG_TYPE}")
44                                 list(APPEND libfiles_${CONFIG_TYPE} ${libfile_${CONFIG_TYPE}})
45                         endforeach()
46                 else()
47                         get_target_property(libfile ${lib} LOCATION)
48                         list(APPEND libfiles "${libfile}")
49                 endif(multiconfig)
50         endforeach()
51
52         # Just to be sure: cleanup from duplicates
53         if(multiconfig) 
54                 foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES})
55                         list(REMOVE_DUPLICATES libfiles_${CONFIG_TYPE})
56                         set(libfiles ${libfiles} ${libfiles_${CONFIG_TYPE}})
57                 endforeach()
58         endif()
59         list(REMOVE_DUPLICATES libfiles)
60
61         # Now the easy part for MSVC and for MAC
62   if(MSVC)
63     # lib.exe does the merging of libraries just need to conver the list into string
64         foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES})
65                 set(flags "")
66                 foreach(lib ${libfiles_${CONFIG_TYPE}})
67                         set(flags "${flags} ${lib}")
68                 endforeach()
69                 string(TOUPPER "STATIC_LIBRARY_FLAGS_${CONFIG_TYPE}" PROPNAME)
70                 set_target_properties(${output_target} PROPERTIES ${PROPNAME} "${flags}")
71         endforeach()
72         
73   elseif(APPLE)
74     # Use OSX's libtool to merge archives
75         if(multiconfig)
76                 message(FATAL_ERROR "Multiple configurations are not supported")
77         endif()
78         get_target_property(outfile ${output_target} LOCATION)  
79         add_custom_command(TARGET ${output_target} POST_BUILD
80                 COMMAND rm ${outfile}
81                 COMMAND /usr/bin/libtool -static -o ${outfile} 
82                 ${libfiles}
83         )
84   else() 
85   # general UNIX - need to "ar -x" and then "ar -ru"
86         if(multiconfig)
87                 message(FATAL_ERROR "Multiple configurations are not supported")
88         endif()
89         get_target_property(outfile ${output_target} LOCATION)
90         message(STATUS "output file location is ${outfile}")
91         foreach(lib ${libfiles})
92                 # objlistfile will contain the list of object files for the library
93                 set(objlistfile ${lib}.objlist)
94                 set(objdir ${lib}.objdir)
95                 set(objlistcmake  ${objlistfile}.cmake)
96                 get_filename_component(libname ${lib} NAME_WE)
97
98                 if(${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/cmake.check_cache IS_NEWER_THAN ${objlistcmake})
99
100                         file(WRITE ${objlistcmake} "
101                                 # delete previous object files
102                                 message(STATUS \"Removing previous object files from ${lib}\")
103                                 EXECUTE_PROCESS(COMMAND ls .
104                                         WORKING_DIRECTORY ${objdir}
105                                         COMMAND xargs -I {} rm {}
106                                         WORKING_DIRECTORY ${objdir})
107                                 # Extract object files from the library
108                                 message(STATUS \"Extracting object files from ${lib}\")
109                                 EXECUTE_PROCESS(COMMAND ${CMAKE_AR} -x ${lib}
110                                         WORKING_DIRECTORY ${objdir})
111                                 # Prefixing object files to avoid conflicts
112                                 message(STATUS \"Prefixing object files to avoid conflicts\")
113                                 EXECUTE_PROCESS(COMMAND ls .
114                                         WORKING_DIRECTORY ${objdir}
115                                         COMMAND xargs -I {} mv {} ${libname}_{}
116                                         WORKING_DIRECTORY ${objdir})
117                                 # save the list of object files
118                                 EXECUTE_PROCESS(COMMAND ls . 
119                                         OUTPUT_FILE ${objlistfile}
120                                         WORKING_DIRECTORY ${objdir})
121                         ")
122                                 
123                         file(MAKE_DIRECTORY ${objdir})
124                                 
125                         add_custom_command(
126                                 OUTPUT ${objlistfile}
127                                 COMMAND ${CMAKE_COMMAND} -P ${objlistcmake}
128                                 DEPENDS ${lib})
129                         
130                 endif()
131                 
132                 list(APPEND extrafiles "${objlistfile}")
133                 # relative path is needed by ar under MSYS
134                 file(RELATIVE_PATH objlistfilerpath ${objdir} ${objlistfile})
135                 add_custom_command(TARGET ${output_target} POST_BUILD
136                         COMMAND ${CMAKE_COMMAND} -E echo "Running: ${CMAKE_AR} ru ${outfile} @${objlistfilerpath}"
137                         COMMAND ${CMAKE_AR} ru "${outfile}" @"${objlistfilerpath}"
138                         #COMMAND ld -r -static -o "${outfile}" --whole-archive @"${objlistfilerpath}"
139                         WORKING_DIRECTORY ${objdir})
140         endforeach()
141         add_custom_command(TARGET ${output_target} POST_BUILD
142                         COMMAND ${CMAKE_COMMAND} -E echo "Running: ${CMAKE_RANLIB} ${outfile}"
143                         COMMAND ${CMAKE_RANLIB} ${outfile})
144   endif()
145   file(WRITE ${dummyfile}.base "const char* ${output_library}_sublibs=\"${libs}\";")
146   add_custom_command( 
147                 OUTPUT ${dummyfile}
148                 COMMAND ${CMAKE_COMMAND} -E copy ${dummyfile}.base ${dummyfile}
149                 DEPENDS ${libs} ${extrafiles})
150
151 endfunction()