DuckStationUtils.cmake (8642B)
1 function(disable_compiler_warnings_for_target target) 2 if(MSVC) 3 target_compile_options(${target} PRIVATE "/W0") 4 else() 5 target_compile_options(${target} PRIVATE "-w") 6 endif() 7 endfunction() 8 9 function(detect_operating_system) 10 message(STATUS "CMake Version: ${CMAKE_VERSION}") 11 message(STATUS "CMake System Name: ${CMAKE_SYSTEM_NAME}") 12 13 # LINUX wasn't added until CMake 3.25. 14 if (CMAKE_VERSION VERSION_LESS 3.25.0 AND CMAKE_SYSTEM_NAME MATCHES "Linux") 15 # Have to make it visible in this scope as well for below. 16 set(LINUX TRUE PARENT_SCOPE) 17 set(LINUX TRUE) 18 endif() 19 20 if(WIN32) 21 message(STATUS "Building for Windows.") 22 elseif(APPLE AND NOT IOS) 23 message(STATUS "Building for MacOS.") 24 elseif(LINUX) 25 message(STATUS "Building for Linux.") 26 elseif(BSD) 27 message(STATUS "Building for *BSD.") 28 else() 29 message(FATAL_ERROR "Unsupported platform.") 30 endif() 31 endfunction() 32 33 function(detect_compiler) 34 if(MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 35 set(COMPILER_CLANG_CL TRUE PARENT_SCOPE) 36 set(IS_SUPPORTED_COMPILER TRUE PARENT_SCOPE) 37 message(STATUS "Building with Clang-CL.") 38 elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") 39 set(COMPILER_CLANG TRUE PARENT_SCOPE) 40 set(IS_SUPPORTED_COMPILER TRUE PARENT_SCOPE) 41 message(STATUS "Building with Clang/LLVM.") 42 elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 43 set(COMPILER_GCC TRUE PARENT_SCOPE) 44 set(IS_SUPPORTED_COMPILER FALSE PARENT_SCOPE) 45 message(STATUS "Building with GNU GCC.") 46 elseif(MSVC) 47 set(IS_SUPPORTED_COMPILER TRUE PARENT_SCOPE) 48 message(STATUS "Building with MSVC.") 49 else() 50 message(FATAL_ERROR "Unknown compiler: ${CMAKE_CXX_COMPILER_ID}") 51 endif() 52 endfunction() 53 54 function(detect_architecture) 55 if(APPLE AND NOT "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "") 56 # Universal binaries. 57 if("x86_64" IN_LIST CMAKE_OSX_ARCHITECTURES) 58 message(STATUS "Building x86_64 MacOS binaries.") 59 set(CPU_ARCH_X64 TRUE PARENT_SCOPE) 60 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Xarch_x86_64 -msse4.1" PARENT_SCOPE) 61 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Xarch_x86_64 -msse4.1" PARENT_SCOPE) 62 endif() 63 if("arm64" IN_LIST CMAKE_OSX_ARCHITECTURES) 64 message(STATUS "Building ARM64 MacOS binaries.") 65 set(CPU_ARCH_ARM64 TRUE PARENT_SCOPE) 66 endif() 67 elseif(("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64" OR "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "amd64" OR 68 "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AMD64" OR "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "x86_64") AND 69 CMAKE_SIZEOF_VOID_P EQUAL 8) 70 message(STATUS "Building x86_64 binaries.") 71 set(CPU_ARCH_X64 TRUE PARENT_SCOPE) 72 if(NOT MSVC OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 73 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse4.1" PARENT_SCOPE) 74 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1" PARENT_SCOPE) 75 endif() 76 elseif(("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64" OR "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "arm64") AND 77 CMAKE_SIZEOF_VOID_P EQUAL 8) # Might have an A64 kernel, e.g. Raspbian. 78 message(STATUS "Building ARM64 binaries.") 79 set(CPU_ARCH_ARM64 TRUE PARENT_SCOPE) 80 elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "arm" OR "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7-a" OR 81 "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7l" OR 82 (("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64" OR "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "arm64") 83 AND CMAKE_SIZEOF_VOID_P EQUAL 4)) 84 message(STATUS "Building ARM32 binaries.") 85 set(CPU_ARCH_ARM32 TRUE PARENT_SCOPE) 86 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -marm -march=armv7-a -mfpu=neon-vfpv4" PARENT_SCOPE) 87 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -marm -march=armv7-a -mfpu=neon-vfpv4" PARENT_SCOPE) 88 elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "riscv64") 89 message(STATUS "Building RISC-V 64 binaries.") 90 set(CPU_ARCH_RISCV64 TRUE PARENT_SCOPE) 91 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -finline-atomics" PARENT_SCOPE) 92 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -finline-atomics" PARENT_SCOPE) 93 94 # Still need this, apparently. 95 link_libraries("-latomic") 96 97 if(NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") 98 # Frame pointers generate an annoying amount of code on leaf functions. 99 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer" PARENT_SCOPE) 100 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fomit-frame-pointer" PARENT_SCOPE) 101 endif() 102 else() 103 message(FATAL_ERROR "Unknown system processor: ${CMAKE_SYSTEM_PROCESSOR}") 104 endif() 105 endfunction() 106 107 function(detect_page_size) 108 # This is only needed for ARM64, or if the user hasn't overridden it explicitly. 109 if(NOT CPU_ARCH_ARM64 OR HOST_PAGE_SIZE) 110 return() 111 endif() 112 113 if(NOT LINUX) 114 # For universal Apple builds, we use preprocessor macros to determine page size. 115 # Similar for Windows, except it's always 4KB. 116 return() 117 endif() 118 119 if(CMAKE_CROSSCOMPILING) 120 message(WARNING "Cross-compiling and can't determine page size, assuming default.") 121 return() 122 endif() 123 124 message(STATUS "Determining host page size") 125 set(detect_page_size_file ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c) 126 file(WRITE ${detect_page_size_file} " 127 #include <stdio.h> 128 #include <stdlib.h> 129 #include <unistd.h> 130 int main() { 131 int res = sysconf(_SC_PAGESIZE); 132 printf(\"%d\", res); 133 return (res > 0) ? EXIT_SUCCESS : EXIT_FAILURE; 134 }") 135 try_run( 136 detect_page_size_run_result 137 detect_page_size_compile_result 138 ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY} 139 ${detect_page_size_file} 140 RUN_OUTPUT_VARIABLE detect_page_size_output) 141 if(NOT detect_page_size_compile_result OR NOT detect_page_size_run_result EQUAL 0) 142 message(FATAL_ERROR "Could not determine host page size.") 143 else() 144 message(STATUS "Host page size: ${detect_page_size_output}") 145 set(HOST_PAGE_SIZE ${detect_page_size_output} CACHE STRING "Reported host page size") 146 endif() 147 endfunction() 148 149 function(detect_cache_line_size) 150 # This is only needed for ARM64, or if the user hasn't overridden it explicitly. 151 if(NOT CPU_ARCH_ARM64 OR HOST_CACHE_LINE_SIZE) 152 return() 153 endif() 154 155 if(NOT LINUX) 156 # For universal Apple builds, we use preprocessor macros to determine page size. 157 # Similar for Windows, except it's always 64 bytes. 158 return() 159 endif() 160 161 if(CMAKE_CROSSCOMPILING) 162 message(WARNING "Cross-compiling and can't determine page size, assuming default.") 163 return() 164 endif() 165 166 message(STATUS "Determining host cache line size") 167 set(detect_cache_line_size_file ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c) 168 file(WRITE ${detect_cache_line_size_file} " 169 #include <stdio.h> 170 #include <stdlib.h> 171 #include <unistd.h> 172 int main() { 173 int l1i = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); 174 int l1d = sysconf(_SC_LEVEL1_ICACHE_LINESIZE); 175 int res = (l1i > l1d) ? l1i : l1d; 176 for (int index = 0; index < 16; index++) { 177 char buf[128]; 178 snprintf(buf, sizeof(buf), \"/sys/devices/system/cpu/cpu0/cache/index%d/coherency_line_size\", index); 179 FILE* fp = fopen(buf, \"rb\"); 180 if (!fp) 181 break; 182 fread(buf, sizeof(buf), 1, fp); 183 fclose(fp); 184 int val = atoi(buf); 185 res = (val > res) ? val : res; 186 } 187 printf(\"%d\", res); 188 return (res > 0) ? EXIT_SUCCESS : EXIT_FAILURE; 189 }") 190 try_run( 191 detect_cache_line_size_run_result 192 detect_cache_line_size_compile_result 193 ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY} 194 ${detect_cache_line_size_file} 195 RUN_OUTPUT_VARIABLE detect_cache_line_size_output) 196 if(NOT detect_cache_line_size_compile_result OR NOT detect_cache_line_size_run_result EQUAL 0) 197 message(FATAL_ERROR "Could not determine host cache line size.") 198 else() 199 message(STATUS "Host cache line size: ${detect_cache_line_size_output}") 200 set(HOST_CACHE_LINE_SIZE ${detect_cache_line_size_output} CACHE STRING "Reported host cache line size") 201 endif() 202 endfunction() 203 204 function(get_scm_version) 205 if(SCM_VERSION) 206 return() 207 endif() 208 209 find_package(Git) 210 if(EXISTS "${PROJECT_SOURCE_DIR}/.git" AND GIT_FOUND) 211 execute_process( 212 COMMAND ${GIT_EXECUTABLE} describe --dirty 213 WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" 214 OUTPUT_VARIABLE LOCAL_SCM_VERSION 215 OUTPUT_STRIP_TRAILING_WHITESPACE 216 ) 217 endif() 218 if(NOT LOCAL_SCM_VERSION) 219 set(SCM_VERSION "unknown" PARENT_SCOPE) 220 else() 221 set(SCM_VERSION ${LOCAL_SCM_VERSION} PARENT_SCOPE) 222 endif() 223 endfunction() 224 225 function(install_imported_dep_library name) 226 get_target_property(SONAME "${name}" IMPORTED_SONAME_RELEASE) 227 get_target_property(LOCATION "${name}" IMPORTED_LOCATION_RELEASE) 228 install(FILES "${LOCATION}" RENAME "${SONAME}" DESTINATION "${CMAKE_INSTALL_PREFIX}") 229 endfunction()