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