Merge branch 'release/3.0' into merge/master-to-release/3.0
[platform/upstream/coreclr.git] / functions.cmake
1 function(clr_unknown_arch)
2     if (WIN32)
3         message(FATAL_ERROR "Only AMD64, ARM64, ARM and I386 are supported")
4     elseif(CLR_CROSS_COMPONENTS_BUILD)
5         message(FATAL_ERROR "Only AMD64, I386 host are supported for linux cross-architecture component")
6     else()
7         message(FATAL_ERROR "Only AMD64, ARM64 and ARM are supported")
8     endif()
9 endfunction()
10
11 # Build a list of compiler definitions by putting -D in front of each define.
12 function(get_compile_definitions DefinitionName)
13     # Get the current list of definitions
14     get_directory_property(COMPILE_DEFINITIONS_LIST COMPILE_DEFINITIONS)
15
16     foreach(DEFINITION IN LISTS COMPILE_DEFINITIONS_LIST)
17         if (${DEFINITION} MATCHES "^\\$<\\$<CONFIG:([^>]+)>:([^>]+)>$")
18             # The entries that contain generator expressions must have the -D inside of the
19             # expression. So we transform e.g. $<$<CONFIG:Debug>:_DEBUG> to $<$<CONFIG:Debug>:-D_DEBUG>
20             set(DEFINITION "$<$<CONFIG:${CMAKE_MATCH_1}>:-D${CMAKE_MATCH_2}>")
21         else()
22             set(DEFINITION -D${DEFINITION})
23         endif()
24         list(APPEND DEFINITIONS ${DEFINITION})
25     endforeach()
26     set(${DefinitionName} ${DEFINITIONS} PARENT_SCOPE)
27 endfunction(get_compile_definitions)
28
29 # Build a list of include directories
30 function(get_include_directories IncludeDirectories)
31     get_directory_property(dirs INCLUDE_DIRECTORIES)
32     foreach(dir IN LISTS dirs)
33
34       if (CLR_CMAKE_PLATFORM_ARCH_ARM AND WIN32)
35         list(APPEND INC_DIRECTORIES /I${dir})
36       else()
37         list(APPEND INC_DIRECTORIES -I${dir})
38       endif(CLR_CMAKE_PLATFORM_ARCH_ARM AND WIN32)
39
40     endforeach()
41     set(${IncludeDirectories} ${INC_DIRECTORIES} PARENT_SCOPE)
42 endfunction(get_include_directories)
43
44 # Build a list of include directories for consumption by the assembler
45 function(get_include_directories_asm IncludeDirectories)
46     get_directory_property(dirs INCLUDE_DIRECTORIES)
47
48     if (CLR_CMAKE_PLATFORM_ARCH_ARM AND WIN32)
49         list(APPEND INC_DIRECTORIES "-I ")
50     endif()
51
52     foreach(dir IN LISTS dirs)
53       if (CLR_CMAKE_PLATFORM_ARCH_ARM AND WIN32)
54         list(APPEND INC_DIRECTORIES ${dir};)
55       else()
56         list(APPEND INC_DIRECTORIES -I${dir})
57       endif()
58     endforeach()
59
60     set(${IncludeDirectories} ${INC_DIRECTORIES} PARENT_SCOPE)
61 endfunction(get_include_directories_asm)
62
63 # Set the passed in RetSources variable to the list of sources with added current source directory
64 # to form absolute paths.
65 # The parameters after the RetSources are the input files.
66 function(convert_to_absolute_path RetSources)
67     set(Sources ${ARGN})
68     foreach(Source IN LISTS Sources)
69         list(APPEND AbsolutePathSources ${CMAKE_CURRENT_SOURCE_DIR}/${Source})
70     endforeach()
71     set(${RetSources} ${AbsolutePathSources} PARENT_SCOPE)
72 endfunction(convert_to_absolute_path)
73
74 #Preprocess exports definition file
75 function(preprocess_def_file inputFilename outputFilename)
76   get_compile_definitions(PREPROCESS_DEFINITIONS)
77   get_include_directories(ASM_INCLUDE_DIRECTORIES)
78   add_custom_command(
79     OUTPUT ${outputFilename}
80     COMMAND ${CMAKE_CXX_COMPILER} ${ASM_INCLUDE_DIRECTORIES} /P /EP /TC ${PREPROCESS_DEFINITIONS}  /Fi${outputFilename}  ${inputFilename}
81     DEPENDS ${inputFilename}
82     COMMENT "Preprocessing ${inputFilename} - ${CMAKE_CXX_COMPILER} ${ASM_INCLUDE_DIRECTORIES} /P /EP /TC ${PREPROCESS_DEFINITIONS}  /Fi${outputFilename}  ${inputFilename}"
83   )
84
85   set_source_files_properties(${outputFilename}
86                               PROPERTIES GENERATED TRUE)
87 endfunction()
88
89 function(generate_exports_file inputFilename outputFilename)
90   if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
91     set(AWK_SCRIPT generateexportedsymbols.awk)
92   else()
93     set(AWK_SCRIPT generateversionscript.awk)
94   endif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
95
96   add_custom_command(
97     OUTPUT ${outputFilename}
98     COMMAND ${AWK} -f ${CMAKE_SOURCE_DIR}/${AWK_SCRIPT} ${inputFilename} >${outputFilename}
99     DEPENDS ${inputFilename} ${CMAKE_SOURCE_DIR}/${AWK_SCRIPT}
100     COMMENT "Generating exports file ${outputFilename}"
101   )
102   set_source_files_properties(${outputFilename}
103                               PROPERTIES GENERATED TRUE)
104 endfunction()
105
106 function(generate_exports_file_prefix inputFilename outputFilename prefix)
107
108   if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
109     set(AWK_SCRIPT generateexportedsymbols.awk)
110   else()
111     set(AWK_SCRIPT generateversionscript.awk)
112     if (NOT ${prefix} STREQUAL "")
113         set(AWK_VARS ${AWK_VARS} -v prefix=${prefix})
114     endif()
115   endif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
116
117   add_custom_command(
118     OUTPUT ${outputFilename}
119     COMMAND ${AWK} -f ${CMAKE_SOURCE_DIR}/${AWK_SCRIPT} ${AWK_VARS} ${inputFilename} >${outputFilename}
120     DEPENDS ${inputFilename} ${CMAKE_SOURCE_DIR}/${AWK_SCRIPT}
121     COMMENT "Generating exports file ${outputFilename}"
122   )
123   set_source_files_properties(${outputFilename}
124                               PROPERTIES GENERATED TRUE)
125 endfunction()
126
127 function(add_precompiled_header header cppFile targetSources)
128   if(MSVC)
129     set(precompiledBinary "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/stdafx.pch")
130
131     set_source_files_properties(${cppFile}
132                                 PROPERTIES COMPILE_FLAGS "/Yc\"${header}\" /Fp\"${precompiledBinary}\""
133                                            OBJECT_OUTPUTS "${precompiledBinary}")
134     set_source_files_properties(${${targetSources}}
135                                 PROPERTIES COMPILE_FLAGS "/Yu\"${header}\" /Fp\"${precompiledBinary}\""
136                                            OBJECT_DEPENDS "${precompiledBinary}")
137     # Add cppFile to SourcesVar
138     set(${targetSources} ${${targetSources}} ${cppFile} PARENT_SCOPE)
139   endif(MSVC)
140 endfunction()
141
142 function(strip_symbols targetName outputFilename)
143   if (CLR_CMAKE_PLATFORM_UNIX)
144     if (STRIP_SYMBOLS)
145
146       # On the older version of cmake (2.8.12) used on Ubuntu 14.04 the TARGET_FILE
147       # generator expression doesn't work correctly returning the wrong path and on
148       # the newer cmake versions the LOCATION property isn't supported anymore.
149       if (CMAKE_VERSION VERSION_EQUAL 3.0 OR CMAKE_VERSION VERSION_GREATER 3.0)
150           set(strip_source_file $<TARGET_FILE:${targetName}>)
151       else()
152           get_property(strip_source_file TARGET ${targetName} PROPERTY LOCATION)
153       endif()
154
155       if (CMAKE_SYSTEM_NAME STREQUAL Darwin)
156         set(strip_destination_file ${strip_source_file}.dwarf)
157
158         add_custom_command(
159           TARGET ${targetName}
160           POST_BUILD
161           VERBATIM
162           COMMAND ${DSYMUTIL} --flat --minimize ${strip_source_file}
163           COMMAND ${STRIP} -S ${strip_source_file}
164           COMMENT Stripping symbols from ${strip_source_file} into file ${strip_destination_file}
165         )
166       else (CMAKE_SYSTEM_NAME STREQUAL Darwin)
167         set(strip_destination_file ${strip_source_file}.dbg)
168
169         add_custom_command(
170           TARGET ${targetName}
171           POST_BUILD
172           VERBATIM
173           COMMAND ${OBJCOPY} --only-keep-debug ${strip_source_file} ${strip_destination_file}
174           COMMAND ${OBJCOPY} --strip-debug ${strip_source_file}
175           COMMAND ${OBJCOPY} --add-gnu-debuglink=${strip_destination_file} ${strip_source_file}
176           COMMENT Stripping symbols from ${strip_source_file} into file ${strip_destination_file}
177         )
178       endif (CMAKE_SYSTEM_NAME STREQUAL Darwin)
179
180       set(${outputFilename} ${strip_destination_file} PARENT_SCOPE)
181     endif (STRIP_SYMBOLS)
182   endif(CLR_CMAKE_PLATFORM_UNIX)
183 endfunction()
184
185 function(install_clr targetName)
186   list(FIND CLR_CROSS_COMPONENTS_LIST ${targetName} INDEX)
187   if (NOT DEFINED CLR_CROSS_COMPONENTS_LIST OR NOT ${INDEX} EQUAL -1)
188     strip_symbols(${targetName} strip_destination_file)
189     # On the older version of cmake (2.8.12) used on Ubuntu 14.04 the TARGET_FILE
190     # generator expression doesn't work correctly returning the wrong path and on
191     # the newer cmake versions the LOCATION property isn't supported anymore.
192     if(CMAKE_VERSION VERSION_EQUAL 3.0 OR CMAKE_VERSION VERSION_GREATER 3.0)
193        set(install_source_file $<TARGET_FILE:${targetName}>)
194     else()
195         get_property(install_source_file TARGET ${targetName} PROPERTY LOCATION)
196     endif()
197
198     install(PROGRAMS ${install_source_file} DESTINATION .)
199     if(WIN32)
200         install(FILES ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${targetName}.pdb DESTINATION PDB)
201     else()
202         install(FILES ${strip_destination_file} DESTINATION .)
203     endif()
204     if(CLR_CMAKE_PGO_INSTRUMENT)
205         if(WIN32)
206             install(FILES ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${targetName}.pgd DESTINATION PGD OPTIONAL)
207         endif()
208     endif()
209   endif()
210 endfunction()
211
212 # Disable PAX mprotect that would prevent JIT and other codegen in coreclr from working.
213 # PAX mprotect prevents:
214 # - changing the executable status of memory pages that were
215 #   not originally created as executable,
216 # - making read-only executable pages writable again,
217 # - creating executable pages from anonymous memory,
218 # - making read-only-after-relocations (RELRO) data pages writable again.
219 function(disable_pax_mprotect targetName)
220   if (NOT PAXCTL STREQUAL "PAXCTL-NOTFOUND")
221     add_custom_command(
222       TARGET ${targetName}
223       POST_BUILD
224       VERBATIM
225       COMMAND ${PAXCTL} -c -m $<TARGET_FILE:${targetName}>
226     )
227   endif()
228 endfunction()
229
230 function(_add_executable)
231     if(NOT WIN32)
232       add_executable(${ARGV} ${VERSION_FILE_PATH})
233       disable_pax_mprotect(${ARGV})
234     else()
235       add_executable(${ARGV})
236     endif(NOT WIN32)
237     list(FIND CLR_CROSS_COMPONENTS_LIST ${ARGV0} INDEX)
238     if (DEFINED CLR_CROSS_COMPONENTS_LIST AND ${INDEX} EQUAL -1)
239      set_target_properties(${ARGV0} PROPERTIES EXCLUDE_FROM_ALL 1)
240     endif()
241 endfunction()
242
243 function(_add_library)
244     if(NOT WIN32)
245       add_library(${ARGV} ${VERSION_FILE_PATH})
246     else()
247       add_library(${ARGV})
248     endif(NOT WIN32)
249     list(FIND CLR_CROSS_COMPONENTS_LIST ${ARGV0} INDEX)
250     if (DEFINED CLR_CROSS_COMPONENTS_LIST AND ${INDEX} EQUAL -1)
251      set_target_properties(${ARGV0} PROPERTIES EXCLUDE_FROM_ALL 1)
252     endif()
253 endfunction()
254
255 function(_install)
256     if(NOT DEFINED CLR_CROSS_COMPONENTS_BUILD)
257       install(${ARGV})
258     endif()
259 endfunction()
260
261 function(verify_dependencies targetName errorMessage)
262     set(SANITIZER_BUILD OFF)
263
264     if (CLR_CMAKE_PLATFORM_UNIX)
265         if (UPPERCASE_CMAKE_BUILD_TYPE STREQUAL DEBUG OR UPPERCASE_CMAKE_BUILD_TYPE STREQUAL CHECKED)
266             string(FIND "$ENV{DEBUG_SANITIZERS}" "asan" __ASAN_POS)
267             string(FIND "$ENV{DEBUG_SANITIZERS}" "ubsan" __UBSAN_POS)
268             if ((${__ASAN_POS} GREATER -1) OR (${__UBSAN_POS} GREATER -1))
269                 set(SANITIZER_BUILD ON)
270             endif()
271         endif()
272     endif()
273
274     # We don't need to verify dependencies on OSX, since missing dependencies
275     # result in link error over there.
276     # Also don't verify dependencies for Asan build because in this case shared
277     # libraries can contain undefined symbols
278     if (NOT CLR_CMAKE_PLATFORM_DARWIN AND NOT CLR_CMAKE_PLATFORM_ANDROID AND NOT SANITIZER_BUILD)
279         add_custom_command(
280             TARGET ${targetName}
281             POST_BUILD
282             VERBATIM
283             COMMAND ${CMAKE_SOURCE_DIR}/verify-so.sh
284                 $<TARGET_FILE:${targetName}>
285                 ${errorMessage}
286             COMMENT "Verifying ${targetName} dependencies"
287         )
288     endif()
289 endfunction()
290
291 function(add_library_clr)
292     _add_library(${ARGV})
293 endfunction()
294
295 function(add_executable_clr)
296     _add_executable(${ARGV})
297 endfunction()