1 2include(CheckCXXSourceCompiles) 3 4if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") 5 set(FRUIT_ADDITIONAL_REQUIRED_FLAG_LIST ${FRUIT_ADDITIONAL_COMPILE_FLAGS_GNU}) 6elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "^Clang$") 7 set(FRUIT_ADDITIONAL_REQUIRED_FLAG_LIST ${FRUIT_ADDITIONAL_COMPILE_FLAGS_Clang}) 8elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel") 9 set(FRUIT_ADDITIONAL_REQUIRED_FLAG_LIST ${FRUIT_ADDITIONAL_COMPILE_FLAGS_Intel}) 10elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "AppleClang") 11 set(FRUIT_ADDITIONAL_REQUIRED_FLAG_LIST ${FRUIT_ADDITIONAL_COMPILE_FLAGS_AppleClang}) 12elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC") 13 set(FRUIT_ADDITIONAL_REQUIRED_FLAG_LIST ${FRUIT_ADDITIONAL_COMPILE_FLAGS_MSVC}) 14endif() 15 16# `CMAKE_REQUIRED_FLAGS` does not accept variables of type list, convert to string. 17foreach(FRUIT_ADDITIONAL_REQUIRED_FLAG_LIST_ITEM IN LISTS FRUIT_ADDITIONAL_REQUIRED_FLAG_LIST) 18 set(FRUIT_ADDITIONAL_REQUIRED_FLAGS "${FRUIT_ADDITIONAL_REQUIRED_FLAGS} ${FRUIT_ADDITIONAL_REQUIRED_FLAG_LIST_ITEM}") 19endforeach() 20 21if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") 22 set(CMAKE_REQUIRED_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE} ${FRUIT_ADDITIONAL_REQUIRED_FLAGS} ${FRUIT_CXX_STANDARD_FLAGS}") 23else() 24 set(CMAKE_REQUIRED_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG} ${FRUIT_ADDITIONAL_REQUIRED_FLAGS} ${FRUIT_CXX_STANDARD_FLAGS}") 25endif() 26 27CHECK_CXX_SOURCE_COMPILES(" 28int main() {} 29" 30FRUIT_TRIVIAL_SOURCE_COMPILES) 31 32if (NOT "${FRUIT_TRIVIAL_SOURCE_COMPILES}") 33 message(FATAL_ERROR "A trivial program with an empty main doesn't compile, something is wrong with your compiler and/or with your compiler flags.") 34endif() 35 36CHECK_CXX_SOURCE_COMPILES(" 37template <typename T, typename U> 38struct Pair {}; 39 40struct Map : public Pair<int, float>, Pair<int, char> {}; 41 42template <typename Value> 43Value f(Pair<int, Value>*) { return Value(); } 44 45int main() { 46 f((Map*)0); 47} 48" 49FRUIT_HAS_CLANG_ARBITRARY_OVERLOAD_RESOLUTION_BUG) 50 51CHECK_CXX_SOURCE_COMPILES(" 52int main() { 53 bool b = __has_trivial_copy(int); 54 (void) b; 55 return 0; 56} 57" 58FRUIT_HAS_HAS_TRIVIAL_COPY) 59 60CHECK_CXX_SOURCE_COMPILES(" 61int main() { 62 bool b = __is_trivially_copyable(int); 63 (void) b; 64 return 0; 65} 66" 67FRUIT_HAS_IS_TRIVIALLY_COPYABLE) 68 69CHECK_CXX_SOURCE_COMPILES(" 70#include <cstddef> 71using X = max_align_t; 72int main() { 73 return 0; 74} 75" 76FRUIT_HAS_MAX_ALIGN_T) 77 78CHECK_CXX_SOURCE_COMPILES(" 79#include <type_traits> 80int main() { 81 bool b = std::is_trivially_copyable<int>::value; 82 (void) b; 83 return 0; 84} 85" 86FRUIT_HAS_STD_IS_TRIVIALLY_COPYABLE) 87 88CHECK_CXX_SOURCE_COMPILES(" 89#include <type_traits> 90int main() { 91 bool b = std::is_trivially_copy_constructible<int>::value; 92 (void) b; 93 return 0; 94} 95" 96FRUIT_HAS_STD_IS_TRIVIALLY_COPY_CONSTRUCTIBLE) 97 98CHECK_CXX_SOURCE_COMPILES(" 99#include <cstddef> 100using X = std::max_align_t; 101int main() { 102 return 0; 103} 104" 105FRUIT_HAS_STD_MAX_ALIGN_T) 106 107CHECK_CXX_SOURCE_COMPILES(" 108#include <typeinfo> 109int main() { 110 (void) typeid(int); 111 return 0; 112} 113" 114FRUIT_HAS_TYPEID) 115 116CHECK_CXX_SOURCE_COMPILES(" 117#include <typeinfo> 118int main() { 119 constexpr static const std::type_info& x = typeid(int); 120 (void) x; 121 return 0; 122} 123" 124FRUIT_HAS_CONSTEXPR_TYPEID) 125 126CHECK_CXX_SOURCE_COMPILES(" 127#include <cxxabi.h> 128int main() { 129 auto* p = abi::__cxa_demangle; 130 (void) p; 131 return 0; 132} 133" 134FRUIT_HAS_CXA_DEMANGLE) 135 136if("${FRUIT_ENABLE_COVERAGE}") 137 set(FRUIT_HAS_ALWAYS_INLINE_ATTRIBUTE OFF) 138 set(FRUIT_HAS_FORCEINLINE OFF) 139else() 140CHECK_CXX_SOURCE_COMPILES(" 141__attribute__((always_inline)) 142void f() { 143} 144 145int main() { 146 return 0; 147} 148" 149FRUIT_HAS_ALWAYS_INLINE_ATTRIBUTE) 150 151CHECK_CXX_SOURCE_COMPILES(" 152__forceinline 153void f() { 154} 155 156int main() { 157 return 0; 158} 159" 160FRUIT_HAS_FORCEINLINE) 161 162endif() 163 164CHECK_CXX_SOURCE_COMPILES(" 165[[deprecated]] void f(); 166 167int main() { 168 return 0; 169} 170" 171FRUIT_HAS_ATTRIBUTE_DEPRECATED) 172 173CHECK_CXX_SOURCE_COMPILES(" 174void f() __attribute__((deprecated)); 175 176int main() { 177 return 0; 178} 179" 180FRUIT_HAS_GCC_ATTRIBUTE_DEPRECATED) 181 182CHECK_CXX_SOURCE_COMPILES(" 183__declspec(deprecated) void f(); 184 185int main() { 186 return 0; 187} 188" 189FRUIT_HAS_DECLSPEC_DEPRECATED) 190 191CHECK_CXX_SOURCE_COMPILES(" 192int f() { 193 static int x = 1; 194 if (x == 1) { 195 return 0; 196 } else { 197 __assume(0); 198 // Note: the lack of return here is intentional 199 } 200} 201 202int main() { 203 return f(); 204} 205" 206FRUIT_HAS_MSVC_ASSUME) 207 208CHECK_CXX_SOURCE_COMPILES(" 209int f() { 210 static int x = 1; 211 if (x == 1) { 212 return 0; 213 } else { 214 __builtin_unreachable(); 215 // Note: the lack of return here is intentional 216 } 217} 218 219int main() { 220 return f(); 221} 222" 223FRUIT_HAS_BUILTIN_UNREACHABLE) 224 225 226if (NOT "${FRUIT_HAS_STD_MAX_ALIGN_T}" AND NOT "${FRUIT_HAS_MAX_ALIGN_T}") 227 message(WARNING "The current C++ standard library doesn't support std::max_align_t nor ::max_align_t. Attempting to use std::max_align_t anyway, but it most likely won't work.") 228endif() 229 230if(NOT "${FRUIT_HAS_STD_IS_TRIVIALLY_COPYABLE}" AND NOT "${FRUIT_HAS_IS_TRIVIALLY_COPYABLE}" 231 AND NOT "${FRUIT_HAS_HAS_TRIVIAL_COPY}") 232 message(WARNING "The current standard library doesn't support std::is_trivially_copyable<T>, and the current compiler doesn't support __is_trivially_copyable(T) nor __has_trivial_copy(T). Attemping to use std::is_trivially_copyable<T> anyway, but it most likely won't work.") 233endif() 234 235if (NOT "${FRUIT_HAS_ATTRIBUTE_DEPRECATED}" AND NOT "${FRUIT_HAS_GCC_ATTRIBUTE_DEPRECATED}" AND NOT "${FRUIT_HAS_DECLSPEC_DEPRECATED}") 236 message(WARNING "No supported way to mark functions as deprecated was found. Continuing anyway, without the 'deprecated' markers.") 237endif() 238 239configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fruit-config-base.h.in ${CMAKE_CURRENT_BINARY_DIR}/../include/fruit/impl/fruit-config-base.h) 240 241install(FILES ${CMAKE_CURRENT_BINARY_DIR}/../include/fruit/impl/fruit-config-base.h 242 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fruit/impl) 243