Chris Bieneman | 1dd58a7 | 2016-04-28 18:22:01 +0000 | [diff] [blame] | 1 | include(CMakePushCheckState) |
| 2 | include(CheckSymbolExists) |
| 3 | |
Alexey Samsonov | 163ab9d | 2013-01-18 16:05:21 +0000 | [diff] [blame] | 4 | # Because compiler-rt spends a lot of time setting up custom compile flags, |
| 5 | # define a handy helper function for it. The compile flags setting in CMake |
| 6 | # has serious issues that make its syntax challenging at best. |
| 7 | function(set_target_compile_flags target) |
Aaron Ballman | e927a17 | 2014-10-23 22:13:52 +0000 | [diff] [blame] | 8 | set(argstring "") |
Alexey Samsonov | 163ab9d | 2013-01-18 16:05:21 +0000 | [diff] [blame] | 9 | foreach(arg ${ARGN}) |
| 10 | set(argstring "${argstring} ${arg}") |
| 11 | endforeach() |
| 12 | set_property(TARGET ${target} PROPERTY COMPILE_FLAGS "${argstring}") |
| 13 | endfunction() |
| 14 | |
| 15 | function(set_target_link_flags target) |
Aaron Ballman | e927a17 | 2014-10-23 22:13:52 +0000 | [diff] [blame] | 16 | set(argstring "") |
Alexey Samsonov | 163ab9d | 2013-01-18 16:05:21 +0000 | [diff] [blame] | 17 | foreach(arg ${ARGN}) |
| 18 | set(argstring "${argstring} ${arg}") |
| 19 | endforeach() |
| 20 | set_property(TARGET ${target} PROPERTY LINK_FLAGS "${argstring}") |
| 21 | endfunction() |
| 22 | |
Peter Collingbourne | cbdea32 | 2013-10-25 23:03:34 +0000 | [diff] [blame] | 23 | # Set the variable var_PYBOOL to True if var holds a true-ish string, |
| 24 | # otherwise set it to False. |
| 25 | macro(pythonize_bool var) |
| 26 | if (${var}) |
| 27 | set(${var}_PYBOOL True) |
| 28 | else() |
| 29 | set(${var}_PYBOOL False) |
| 30 | endif() |
| 31 | endmacro() |
Alexey Samsonov | b73db72 | 2014-02-18 07:52:40 +0000 | [diff] [blame] | 32 | |
Alexey Samsonov | 32956d6 | 2014-03-13 09:31:36 +0000 | [diff] [blame] | 33 | # Appends value to all lists in ARGN, if the condition is true. |
Kuba Brecka | 14c0c59 | 2014-10-15 22:47:54 +0000 | [diff] [blame] | 34 | macro(append_list_if condition value) |
Alexey Samsonov | 32956d6 | 2014-03-13 09:31:36 +0000 | [diff] [blame] | 35 | if(${condition}) |
| 36 | foreach(list ${ARGN}) |
| 37 | list(APPEND ${list} ${value}) |
| 38 | endforeach() |
Alexey Samsonov | b73db72 | 2014-02-18 07:52:40 +0000 | [diff] [blame] | 39 | endif() |
| 40 | endmacro() |
| 41 | |
Alexey Samsonov | fe7e28c | 2014-03-13 11:31:10 +0000 | [diff] [blame] | 42 | # Appends value to all strings in ARGN, if the condition is true. |
| 43 | macro(append_string_if condition value) |
| 44 | if(${condition}) |
| 45 | foreach(str ${ARGN}) |
| 46 | set(${str} "${${str}} ${value}") |
| 47 | endforeach() |
| 48 | endif() |
| 49 | endmacro() |
| 50 | |
Filipe Cabecinhas | b08c76f | 2016-03-05 10:01:04 +0000 | [diff] [blame] | 51 | macro(append_rtti_flag polarity list) |
| 52 | if(polarity) |
| 53 | append_list_if(COMPILER_RT_HAS_FRTTI_FLAG -frtti ${list}) |
| 54 | append_list_if(COMPILER_RT_HAS_GR_FLAG /GR ${list}) |
| 55 | else() |
| 56 | append_list_if(COMPILER_RT_HAS_FNO_RTTI_FLAG -fno-rtti ${list}) |
| 57 | append_list_if(COMPILER_RT_HAS_GR_FLAG /GR- ${list}) |
| 58 | endif() |
Alexey Samsonov | b73db72 | 2014-02-18 07:52:40 +0000 | [diff] [blame] | 59 | endmacro() |
Yury Gribov | 8e49b47 | 2015-04-09 08:06:49 +0000 | [diff] [blame] | 60 | |
| 61 | macro(append_have_file_definition filename varname list) |
| 62 | check_include_file("${filename}" "${varname}") |
Reid Kleckner | aa90296 | 2015-05-20 16:56:17 +0000 | [diff] [blame] | 63 | if (NOT ${varname}) |
Yury Gribov | 8e49b47 | 2015-04-09 08:06:49 +0000 | [diff] [blame] | 64 | set("${varname}" 0) |
| 65 | endif() |
| 66 | list(APPEND ${list} "${varname}=${${varname}}") |
| 67 | endmacro() |
Chris Bieneman | 361231e | 2015-08-13 20:38:16 +0000 | [diff] [blame] | 68 | |
Daniel Sanders | de098c9 | 2016-01-27 09:28:01 +0000 | [diff] [blame] | 69 | macro(list_intersect output input1 input2) |
Chris Bieneman | 361231e | 2015-08-13 20:38:16 +0000 | [diff] [blame] | 70 | set(${output}) |
| 71 | foreach(it ${${input1}}) |
| 72 | list(FIND ${input2} ${it} index) |
| 73 | if( NOT (index EQUAL -1)) |
| 74 | list(APPEND ${output} ${it}) |
| 75 | endif() |
| 76 | endforeach() |
| 77 | endmacro() |
Chris Bieneman | 5a5b21d | 2016-02-17 16:57:38 +0000 | [diff] [blame] | 78 | |
| 79 | # Takes ${ARGN} and puts only supported architectures in @out_var list. |
| 80 | function(filter_available_targets out_var) |
| 81 | set(archs ${${out_var}}) |
| 82 | foreach(arch ${ARGN}) |
| 83 | list(FIND COMPILER_RT_SUPPORTED_ARCH ${arch} ARCH_INDEX) |
| 84 | if(NOT (ARCH_INDEX EQUAL -1) AND CAN_TARGET_${arch}) |
| 85 | list(APPEND archs ${arch}) |
| 86 | endif() |
| 87 | endforeach() |
| 88 | set(${out_var} ${archs} PARENT_SCOPE) |
| 89 | endfunction() |
| 90 | |
| 91 | function(check_compile_definition def argstring out_var) |
| 92 | if("${def}" STREQUAL "") |
| 93 | set(${out_var} TRUE PARENT_SCOPE) |
| 94 | return() |
| 95 | endif() |
| 96 | cmake_push_check_state() |
| 97 | set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${argstring}") |
| 98 | check_symbol_exists(${def} "" ${out_var}) |
| 99 | cmake_pop_check_state() |
| 100 | endfunction() |
| 101 | |
| 102 | # test_target_arch(<arch> <def> <target flags...>) |
| 103 | # Checks if architecture is supported: runs host compiler with provided |
| 104 | # flags to verify that: |
| 105 | # 1) <def> is defined (if non-empty) |
| 106 | # 2) simple file can be successfully built. |
| 107 | # If successful, saves target flags for this architecture. |
| 108 | macro(test_target_arch arch def) |
| 109 | set(TARGET_${arch}_CFLAGS ${ARGN}) |
Etienne Bergeron | 7e2fc3b | 2016-06-21 14:46:32 +0000 | [diff] [blame] | 110 | set(TARGET_${arch}_LINKFLAGS ${ARGN}) |
Chris Bieneman | 5a5b21d | 2016-02-17 16:57:38 +0000 | [diff] [blame] | 111 | set(argstring "") |
| 112 | foreach(arg ${ARGN}) |
| 113 | set(argstring "${argstring} ${arg}") |
| 114 | endforeach() |
| 115 | check_compile_definition("${def}" "${argstring}" HAS_${arch}_DEF) |
| 116 | if(NOT HAS_${arch}_DEF) |
| 117 | set(CAN_TARGET_${arch} FALSE) |
Chris Bieneman | aa3d2c1 | 2016-05-03 19:48:11 +0000 | [diff] [blame] | 118 | elseif(TEST_COMPILE_ONLY) |
| 119 | try_compile_only(CAN_TARGET_${arch} ${TARGET_${arch}_CFLAGS}) |
Chris Bieneman | 5a5b21d | 2016-02-17 16:57:38 +0000 | [diff] [blame] | 120 | else() |
| 121 | set(argstring "${CMAKE_EXE_LINKER_FLAGS} ${argstring}") |
| 122 | try_compile(CAN_TARGET_${arch} ${CMAKE_BINARY_DIR} ${SIMPLE_SOURCE} |
| 123 | COMPILE_DEFINITIONS "${TARGET_${arch}_CFLAGS}" |
| 124 | OUTPUT_VARIABLE TARGET_${arch}_OUTPUT |
| 125 | CMAKE_FLAGS "-DCMAKE_EXE_LINKER_FLAGS:STRING=${argstring}") |
| 126 | endif() |
| 127 | if(${CAN_TARGET_${arch}}) |
| 128 | list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch}) |
Francis Ricci | b04a721 | 2016-07-20 18:06:31 +0000 | [diff] [blame^] | 129 | elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" STREQUAL "${arch}" AND |
Chris Bieneman | 5a5b21d | 2016-02-17 16:57:38 +0000 | [diff] [blame] | 130 | COMPILER_RT_HAS_EXPLICIT_DEFAULT_TARGET_TRIPLE) |
| 131 | # Bail out if we cannot target the architecture we plan to test. |
| 132 | message(FATAL_ERROR "Cannot compile for ${arch}:\n${TARGET_${arch}_OUTPUT}") |
| 133 | endif() |
| 134 | endmacro() |
Chris Bieneman | 648d3bc | 2016-06-03 17:34:02 +0000 | [diff] [blame] | 135 | |
| 136 | macro(detect_target_arch) |
| 137 | check_symbol_exists(__arm__ "" __ARM) |
| 138 | check_symbol_exists(__aarch64__ "" __AARCH64) |
| 139 | check_symbol_exists(__x86_64__ "" __X86_64) |
| 140 | check_symbol_exists(__i686__ "" __I686) |
| 141 | check_symbol_exists(__i386__ "" __I386) |
| 142 | check_symbol_exists(__mips__ "" __MIPS) |
| 143 | check_symbol_exists(__mips64__ "" __MIPS64) |
| 144 | check_symbol_exists(__s390x__ "" __S390X) |
| 145 | check_symbol_exists(__wasm32__ "" __WEBASSEMBLY32) |
| 146 | check_symbol_exists(__wasm64__ "" __WEBASSEMBLY64) |
| 147 | if(__ARM) |
| 148 | add_default_target_arch(arm) |
| 149 | elseif(__AARCH64) |
| 150 | add_default_target_arch(aarch64) |
| 151 | elseif(__X86_64) |
| 152 | add_default_target_arch(x86_64) |
| 153 | elseif(__I686) |
| 154 | add_default_target_arch(i686) |
| 155 | elseif(__I386) |
| 156 | add_default_target_arch(i386) |
| 157 | elseif(__MIPS64) # must be checked before __MIPS |
| 158 | add_default_target_arch(mips64) |
| 159 | elseif(__MIPS) |
| 160 | add_default_target_arch(mips) |
| 161 | elseif(__S390X) |
| 162 | add_default_target_arch(s390x) |
| 163 | elseif(__WEBASSEMBLY32) |
| 164 | add_default_target_arch(wasm32) |
| 165 | elseif(__WEBASSEMBLY64) |
| 166 | add_default_target_arch(wasm64) |
| 167 | endif() |
| 168 | endmacro() |