Atlas - macros.cmake
Home / ext / SDL / cmake Lines: 14 | Size: 17838 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1macro(add_to_alloptions _NEWNAME) 2 list(APPEND ALLOPTIONS ${_NEWNAME}) 3endmacro() 4 5macro(set_option _NAME _DESC) 6 add_to_alloptions(${_NAME}) 7 if(${ARGC} EQUAL 3) 8 set(_DEFLT ${ARGV2}) 9 else() 10 set(_DEFLT OFF) 11 endif() 12 option(${_NAME} ${_DESC} ${_DEFLT}) 13endmacro() 14 15macro(dep_option _NAME _DESC _DEFLT _DEPTEST _FAILDFLT) 16 add_to_alloptions("${_NAME}") 17 cmake_dependent_option("${_NAME}" "${_DESC}" "${_DEFLT}" "${_DEPTEST}" "${_FAILDFLT}") 18endmacro() 19 20macro(option_string _NAME _DESC _VALUE) 21 add_to_alloptions(${_NAME}) 22 set(${_NAME} ${_VALUE} CACHE STRING "${_DESC}") 23 set(HAVE_${_NAME} ${_VALUE}) 24ENDMACRO() 25 26macro(message_bool_option _NAME _VALUE) 27 set(_PAD "\t") 28 if(${ARGC} EQUAL 3) 29 set(_PAD ${ARGV2}) 30 endif() 31 if(${_VALUE}) 32 message(STATUS " ${_NAME}:${_PAD}ON") 33 else() 34 message(STATUS " ${_NAME}:${_PAD}OFF") 35 endif() 36endmacro() 37 38macro(message_tested_option _NAME) 39 set(_REQVALUE ${${_NAME}}) 40 set(_PAD " ") 41 if(${ARGC} EQUAL 2) 42 set(_PAD ${ARGV1}) 43 endif() 44 string(SUBSTRING "${_NAME}" 0 4 _NAMESTART) 45 if(_NAMESTART STREQUAL "SDL_") 46 string(SUBSTRING "${_NAME}" 4 -1 _STRIPPEDNAME) 47 else() 48 set(_STRIPPEDNAME "${_NAME}") 49 endif() 50 if(NOT HAVE_${_STRIPPEDNAME}) 51 set(HAVE_${_STRIPPEDNAME} OFF) 52 elseif("${HAVE_${_STRIPPEDNAME}}" MATCHES "1|TRUE|YES|Y") 53 set(HAVE_${_STRIPPEDNAME} ON) 54 endif() 55 message(STATUS " ${_NAME}${_PAD}(Wanted: ${_REQVALUE}): ${HAVE_${_STRIPPEDNAME}}") 56endmacro() 57 58function(find_stringlength_longest_item inList outLength) 59 set(maxLength 0) 60 foreach(item IN LISTS ${inList}) 61 string(LENGTH "${item}" slen) 62 if(slen GREATER maxLength) 63 set(maxLength ${slen}) 64 endif() 65 endforeach() 66 set("${outLength}" ${maxLength} PARENT_SCOPE) 67endfunction() 68 69function(message_dictlist inList) 70 find_stringlength_longest_item(${inList} maxLength) 71 foreach(name IN LISTS ${inList}) 72 # Get the padding 73 string(LENGTH ${name} nameLength) 74 math(EXPR padLength "(${maxLength} + 1) - ${nameLength}") 75 string(RANDOM LENGTH ${padLength} ALPHABET " " padding) 76 message_tested_option(${name} ${padding}) 77 endforeach() 78endfunction() 79 80if(APPLE) 81 include(CheckOBJCSourceCompiles) 82 enable_language(OBJC) 83endif() 84 85function(SDL_detect_linker) 86 if(CMAKE_VERSION VERSION_LESS 3.29) 87 if(NOT DEFINED SDL_CMAKE_C_COMPILER_LINKER_ID) 88 execute_process(COMMAND ${CMAKE_LINKER} -v OUTPUT_VARIABLE LINKER_OUTPUT ERROR_VARIABLE LINKER_OUTPUT) 89 string(REGEX REPLACE "[\r\n]" " " LINKER_OUTPUT "${LINKER_OUTPUT}") 90 if(LINKER_OUTPUT MATCHES ".*Microsoft.*") 91 set(linker MSVC) 92 else() 93 set(linker GNUlike) 94 endif() 95 message(STATUS "Linker identification: ${linker}") 96 set(SDL_CMAKE_C_COMPILER_LINKER_ID "${linker}" CACHE STRING "Linker identification") 97 mark_as_advanced(SDL_CMAKE_C_COMPILER_LINKER_ID) 98 endif() 99 set(CMAKE_C_COMPILER_LINKER_ID "${SDL_CMAKE_C_COMPILER_LINKER_ID}" PARENT_SCOPE) 100 endif() 101endfunction() 102 103function(read_absolute_symlink DEST PATH) 104 file(READ_SYMLINK "${PATH}" p) 105 if(NOT IS_ABSOLUTE "${p}") 106 get_filename_component(pdir "${PATH}" DIRECTORY) 107 set(p "${pdir}/${p}") 108 endif() 109 get_filename_component(p "${p}" ABSOLUTE) 110 set("${DEST}" "${p}" PARENT_SCOPE) 111endfunction() 112 113function(win32_implib_identify_dll DEST IMPLIB) 114 cmake_parse_arguments(ARGS "NOTFATAL" "" "" ${ARGN}) 115 if(CMAKE_DLLTOOL) 116 execute_process( 117 COMMAND "${CMAKE_DLLTOOL}" --identify "${IMPLIB}" 118 RESULT_VARIABLE retcode 119 OUTPUT_VARIABLE stdout 120 ERROR_VARIABLE stderr) 121 if(NOT retcode EQUAL 0) 122 if(NOT ARGS_NOTFATAL) 123 message(FATAL_ERROR "${CMAKE_DLLTOOL} failed.") 124 else() 125 set("${DEST}" "${DEST}-NOTFOUND" PARENT_SCOPE) 126 return() 127 endif() 128 endif() 129 string(STRIP "${stdout}" result) 130 set(${DEST} "${result}" PARENT_SCOPE) 131 elseif(MSVC) 132 get_filename_component(CMAKE_C_COMPILER_DIRECTORY "${CMAKE_C_COMPILER}" DIRECTORY CACHE) 133 find_program(CMAKE_DUMPBIN NAMES dumpbin PATHS "${CMAKE_C_COMPILER_DIRECTORY}") 134 if(CMAKE_DUMPBIN) 135 execute_process( 136 COMMAND "${CMAKE_DUMPBIN}" "-headers" "${IMPLIB}" 137 RESULT_VARIABLE retcode 138 OUTPUT_VARIABLE stdout 139 ERROR_VARIABLE stderr) 140 if(NOT retcode EQUAL 0) 141 if(NOT ARGS_NOTFATAL) 142 message(FATAL_ERROR "dumpbin failed.") 143 else() 144 set(${DEST} "${DEST}-NOTFOUND" PARENT_SCOPE) 145 return() 146 endif() 147 endif() 148 string(REGEX MATCH "DLL name[ ]+:[ ]+([^\n]+)\n" match "${stdout}") 149 if(NOT match) 150 if(NOT ARGS_NOTFATAL) 151 message(FATAL_ERROR "dumpbin did not find any associated dll for ${IMPLIB}.") 152 else() 153 set(${DEST} "${DEST}-NOTFOUND" PARENT_SCOPE) 154 return() 155 endif() 156 endif() 157 set(result "${CMAKE_MATCH_1}") 158 set(${DEST} "${result}" PARENT_SCOPE) 159 else() 160 message(FATAL_ERROR "Cannot find dumpbin, please set CMAKE_DUMPBIN cmake variable") 161 endif() 162 else() 163 if(NOT ARGS_NOTFATAL) 164 message(FATAL_ERROR "Don't know how to identify dll from import library. Set CMAKE_DLLTOOL (for mingw) or CMAKE_DUMPBIN (for MSVC)") 165 else() 166 set(${DEST} "${DEST}-NOTFOUND") 167 endif() 168 endif() 169endfunction() 170 171function(get_actual_target) 172 set(dst "${ARGV0}") 173 set(target "${${dst}}") 174 set(input "${target}") 175 get_target_property(alias "${target}" ALIASED_TARGET) 176 while(alias) 177 set(target "${alias}") 178 get_target_property(alias "${target}" ALIASED_TARGET) 179 endwhile() 180 message(DEBUG "get_actual_target(\"${input}\") -> \"${target}\"") 181 set("${dst}" "${target}" PARENT_SCOPE) 182endfunction() 183 184function(target_get_dynamic_library DEST TARGET) 185 set(result) 186 get_actual_target(TARGET) 187 if(WIN32) 188 # Use the target dll of the import library 189 set(props_to_check IMPORTED_IMPLIB) 190 if(CMAKE_BUILD_TYPE) 191 list(APPEND props_to_check IMPORTED_IMPLIB_${CMAKE_BUILD_TYPE}) 192 endif() 193 list(APPEND props_to_check IMPORTED_LOCATION) 194 if(CMAKE_BUILD_TYPE) 195 list(APPEND props_to_check IMPORTED_LOCATION_${CMAKE_BUILD_TYPE}) 196 endif() 197 foreach (config_type ${CMAKE_CONFIGURATION_TYPES} RELEASE DEBUG RELWITHDEBINFO MINSIZEREL) 198 list(APPEND props_to_check IMPORTED_IMPLIB_${config_type}) 199 list(APPEND props_to_check IMPORTED_LOCATION_${config_type}) 200 endforeach() 201 202 foreach(prop_to_check ${props_to_check}) 203 if(NOT result) 204 get_target_property(propvalue "${TARGET}" ${prop_to_check}) 205 if(propvalue AND EXISTS "${propvalue}") 206 win32_implib_identify_dll(result "${propvalue}" NOTFATAL) 207 endif() 208 endif() 209 endforeach() 210 else() 211 if(UNIX AND NOT APPLE) 212 find_program(READELF_BIN NAMES readelf) 213 endif() 214 # 1. find the target library a file might be symbolic linking to 215 # 2. if readelf is available, parse the output of `readelf -d` and output the "(SONAME)" line 216 # 3. Else: 217 # 1. find all other files in the same folder that symbolic link to it 218 # 2. sort all these files, and select the 1st item on Linux, and last on macOS 219 set(location_properties IMPORTED_LOCATION) 220 if(CMAKE_BUILD_TYPE) 221 list(APPEND location_properties IMPORTED_LOCATION_${CMAKE_BUILD_TYPE}) 222 endif() 223 foreach (config_type ${CMAKE_CONFIGURATION_TYPES} RELEASE DEBUG RELWITHDEBINFO MINSIZEREL) 224 list(APPEND location_properties IMPORTED_LOCATION_${config_type}) 225 endforeach() 226 if(APPLE) 227 set(valid_shared_library_regex "\\.[0-9]+\\.dylib$") 228 else() 229 set(valid_shared_library_regex "\\.so\\.([0-9.]+)?[0-9]") 230 endif() 231 foreach(location_property ${location_properties}) 232 if(NOT result) 233 get_target_property(library_path "${TARGET}" ${location_property}) 234 message(DEBUG "get_target_property(${TARGET} ${location_property}) -> ${library_path}") 235 if(EXISTS "${library_path}") 236 if(READELF_BIN) 237 execute_process(COMMAND "${READELF_BIN}" -d "${library_path}" RESULTS_VARIABLE readelf_result OUTPUT_VARIABLE readelf_output) 238 if(readelf_output) 239 string(REGEX MATCH "\\(SONAME\\).*\\[([0-9A-Za-z_.-]+)\\]" soname "${readelf_output}") 240 if(soname) 241 set(result "${CMAKE_MATCH_1}") 242 endif() 243 endif() 244 endif() 245 if(NOT result) 246 get_filename_component(library_path "${library_path}" ABSOLUTE) 247 while (IS_SYMLINK "${library_path}") 248 read_absolute_symlink(library_path "${library_path}") 249 endwhile() 250 message(DEBUG "${TARGET} -> ${library_path}") 251 get_filename_component(libdir "${library_path}" DIRECTORY) 252 file(GLOB subfiles "${libdir}/*") 253 set(similar_files "${library_path}") 254 foreach(subfile ${subfiles}) 255 if(IS_SYMLINK "${subfile}") 256 read_absolute_symlink(subfile_target "${subfile}") 257 while(IS_SYMLINK "${subfile_target}") 258 read_absolute_symlink(subfile_target "${subfile_target}") 259 endwhile() 260 get_filename_component(subfile_target "${subfile_target}" ABSOLUTE) 261 if(subfile_target STREQUAL library_path AND subfile MATCHES "${valid_shared_library_regex}") 262 list(APPEND similar_files "${subfile}") 263 endif() 264 endif() 265 endforeach() 266 list(SORT similar_files) 267 message(DEBUG "files that are similar to \"${library_path}\"=${similar_files}") 268 if(APPLE) 269 list(REVERSE similar_files) 270 endif() 271 list(GET similar_files 0 item) 272 get_filename_component(result "${item}" NAME) 273 endif() 274 endif() 275 endif() 276 endforeach() 277 endif() 278 if(result) 279 string(TOLOWER "${result}" result_lower) 280 if(WIN32 OR OS2) 281 if(NOT result_lower MATCHES ".*dll") 282 message(FATAL_ERROR "\"${result}\" is not a .dll library") 283 endif() 284 elseif(APPLE) 285 if(NOT result_lower MATCHES ".*dylib.*") 286 message(FATAL_ERROR "\"${result}\" is not a .dylib shared library") 287 endif() 288 else() 289 if(NOT result_lower MATCHES ".*so.*") 290 message(FATAL_ERROR "\"${result}\" is not a .so shared library") 291 endif() 292 endif() 293 else() 294 get_target_property(target_type ${TARGET} TYPE) 295 if(target_type MATCHES "SHARED_LIBRARY|MODULE_LIBRARY") 296 # OK 297 elseif(target_type MATCHES "STATIC_LIBRARY|OBJECT_LIBRARY|INTERFACE_LIBRARY|EXECUTABLE") 298 message(SEND_ERROR "${TARGET} is not a shared library, but has type=${target_type}") 299 else() 300 message(WARNING "Unable to extract dynamic library from target=${TARGET}, type=${target_type}.") 301 endif() 302 # TARGET_SONAME_FILE is not allowed for DLL target platforms. 303 if(WIN32) 304 set(result "$<TARGET_FILE_NAME:${TARGET}>") 305 else() 306 set(result "$<TARGET_SONAME_FILE_NAME:${TARGET}>") 307 endif() 308 endif() 309 set(${DEST} ${result} PARENT_SCOPE) 310endfunction() 311 312function(check_linker_supports_version_file VAR) 313 SDL_detect_linker() 314 if(CMAKE_C_COMPILER_LINKER_ID MATCHES "^(MSVC)$") 315 set(${VAR} FALSE) 316 else() 317 cmake_push_check_state(RESET) 318 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/dummy.sym" "n_0 {\n global:\n func;\n local: *;\n};\n") 319 list(APPEND CMAKE_REQUIRED_LINK_OPTIONS "-Wl,--version-script=${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/dummy.sym") 320 check_c_source_compiles("int func(void) {return 0;} int main(int argc,char*argv[]){(void)argc;(void)argv;return func();}" ${VAR} FAIL_REGEX "(unsupported|syntax error|unrecognized option)") 321 cmake_pop_check_state() 322 endif() 323 set(${VAR} "${${VAR}}" PARENT_SCOPE) 324endfunction() 325 326if(CMAKE_VERSION VERSION_LESS 3.18) 327 function(check_linker_flag LANG FLAG VAR) 328 cmake_push_check_state(RESET) 329 list(APPEND CMAKE_REQUIRED_LINK_OPTIONS ${FLAG}) 330 if(LANG STREQUAL "C") 331 include(CheckCSourceCompiles) 332 check_c_source_compiles("int main(int argc,char*argv[]){(void)argc;(void)argv;return 0;}" ${VAR} FAIL_REGEX "(unsupported|syntax error)") 333 elseif(LANG STREQUAL "CXX") 334 include(CheckCXXSourceCompiles) 335 check_cxx_source_compiles("int main(int argc,char*argv[]){(void)argc;(void)argv;return 0;}" ${VAR} FAIL_REGEX "(unsupported|syntax error)") 336 else() 337 message(FATAL_ERROR "Unsupported language: ${LANG}") 338 endif() 339 cmake_pop_check_state() 340 endfunction() 341else() 342 cmake_policy(SET CMP0057 NEW) # Support new if() IN_LIST operator. (used inside check_linker_flag, used in CMake 3.18) 343 include(CheckLinkerFlag) 344endif() 345 346if(APPLE) 347 check_language(OBJC) 348 if(NOT CMAKE_OBJC_COMPILER) 349 message(WARNING "Cannot find working OBJC compiler.") 350 endif() 351endif() 352 353function(PrintEnabledBackends _SUBSYS _REGEXP) 354 get_cmake_property(_ALLVARS VARIABLES) 355 foreach(_VAR IN LISTS _ALLVARS) 356 if(_VAR AND _VAR MATCHES "${_REGEXP}") 357 string(TOLOWER "${CMAKE_MATCH_1}" _LOWERED) 358 if(NOT _LOWERED MATCHES "available|default|dynamic") # a little hack 359 if(${_VAR}_DYNAMIC) 360 list(APPEND _ENABLED_BACKENDS "${_LOWERED}(dynamic)") 361 else() 362 list(APPEND _ENABLED_BACKENDS "${_LOWERED}") 363 endif() 364 endif() 365 endif() 366 endforeach() 367 368 if(_ENABLED_BACKENDS STREQUAL "") 369 set(_SPACEDOUT "(none)") 370 else() 371 string(REPLACE ";" " " _SPACEDOUT "${_ENABLED_BACKENDS}") 372 endif() 373 message(STATUS " ${_SUBSYS}: ${_SPACEDOUT}") 374endfunction() 375 376function(SDL_PrintSummary) 377 ##### Info output ##### 378 message(STATUS "") 379 message(STATUS "SDL3 was configured with the following options:") 380 message(STATUS "") 381 message(STATUS "Platform: ${CMAKE_SYSTEM}") 382 message(STATUS "64-bit: ${ARCH_64}") 383 message(STATUS "Compiler: ${CMAKE_C_COMPILER}") 384 message(STATUS "Revision: ${SDL_REVISION}") 385 message(STATUS "Vendor: ${SDL_VENDOR_INFO}") 386 message(STATUS "") 387 message(STATUS "Subsystems:") 388 389 find_stringlength_longest_item(SDL_SUBSYSTEMS maxLength) 390 foreach(_SUB IN LISTS SDL_SUBSYSTEMS) 391 string(LENGTH ${_SUB} _SUBLEN) 392 math(EXPR _PADLEN "(${maxLength} + 1) - ${_SUBLEN}") 393 string(RANDOM LENGTH ${_PADLEN} ALPHABET " " _PADDING) 394 string(TOUPPER ${_SUB} _OPT) 395 message_bool_option(${_SUB} SDL_${_OPT} ${_PADDING}) 396 endforeach() 397 message(STATUS "") 398 message(STATUS "Options:") 399 list(SORT ALLOPTIONS) 400 message_dictlist(ALLOPTIONS) 401 message(STATUS "") 402 message(STATUS " Build Shared Library: ${SDL_SHARED}") 403 message(STATUS " Build Static Library: ${SDL_STATIC}") 404 if(APPLE) 405 message(STATUS " Build libraries as Apple Framework: ${SDL_FRAMEWORK}") 406 endif() 407 message(STATUS "") 408 409 message(STATUS "Enabled backends:") 410 PrintEnabledBackends("Video drivers" "^SDL_VIDEO_DRIVER_([A-Z0-9]*)$") 411 if(SDL_VIDEO_DRIVER_X11) 412 PrintEnabledBackends("X11 libraries" "^SDL_VIDEO_DRIVER_X11_([A-Z0-9]*)$") 413 endif() 414 PrintEnabledBackends("Render drivers" "^SDL_VIDEO_RENDER_([A-Z0-9_]*)$") 415 PrintEnabledBackends("GPU drivers" "^SDL_GPU_([A-Z0-9]*)$") 416 PrintEnabledBackends("Audio drivers" "^SDL_AUDIO_DRIVER_([A-Z0-9]*)$") 417 PrintEnabledBackends("Joystick drivers" "^SDL_JOYSTICK_([A-Z0-9]*)$") 418 PrintEnabledBackends("Camera drivers" "^SDL_CAMERA_DRIVER_([A-Z0-9]*)$") 419 message(STATUS "") 420 421 if(UNIX) 422 message(STATUS "If something was not detected, although the libraries") 423 message(STATUS "were installed, then make sure you have set the") 424 message(STATUS "CMAKE_C_FLAGS and CMAKE_PREFIX_PATH CMake variables correctly.") 425 message(STATUS "") 426 endif() 427 428 if(UNIX AND NOT (ANDROID OR APPLE OR EMSCRIPTEN OR HAIKU OR RISCOS)) 429 if(NOT (HAVE_X11 OR HAVE_WAYLAND)) 430 if(NOT SDL_UNIX_CONSOLE_BUILD) 431 message(FATAL_ERROR 432 "SDL could not find X11 or Wayland development libraries on your system. " 433 "This means SDL will not be able to create windows on a typical unix operating system. " 434 "Most likely, this is not wanted." 435 "\n" 436 "On Linux, install the packages listed at " 437 "https://wiki.libsdl.org/SDL3/README-linux#build-dependencies " 438 "\n" 439 "If you really don't need desktop windows, the documentation tells you how to skip this check. " 440 "https://github.com/libsdl-org/SDL/blob/main/docs/README-cmake.md#cmake-fails-to-build-without-x11-or-wayland-support\n" 441 ) 442 endif() 443 endif() 444 endif() 445endfunction() 446 447function(SDL_missing_dependency NAME OPTION) 448 if(LINUX) 449 message( FATAL_ERROR 450 "Couldn't find dependency package for ${NAME}. Please install the needed packages or configure with -D${OPTION}=OFF" 451 "\n" 452 "The full set of dependencies is available at " 453 "https://wiki.libsdl.org/SDL3/README-linux#build-dependencies " 454 "\n" 455 ) 456 else() 457 message( FATAL_ERROR 458 "Couldn't find dependency package for ${NAME}. Please install the needed packages or configure with -D${OPTION}=OFF" 459 ) 460 endif() 461endfunction() 462 463function(SDL_install_pdb TARGET DIRECTORY) 464 get_property(type TARGET ${TARGET} PROPERTY TYPE) 465 if(type MATCHES "^(SHARED_LIBRARY|EXECUTABLE)$") 466 install(FILES $<TARGET_PDB_FILE:${TARGET}> DESTINATION "${DIRECTORY}" OPTIONAL) 467 elseif(type STREQUAL "STATIC_LIBRARY") 468 # FIXME: Use $<TARGET_COMPILE_PDB_FILE:${TARGET} once it becomes available (https://gitlab.kitware.com/cmake/cmake/-/issues/25244) 469 if(CMAKE_GENERATOR MATCHES "^Visual Studio.*") 470 install(CODE "file(INSTALL DESTINATION \"\${CMAKE_INSTALL_PREFIX}/${DIRECTORY}\" TYPE FILE OPTIONAL FILES \"${CMAKE_CURRENT_BINARY_DIR}/\${CMAKE_INSTALL_CONFIG_NAME}/${TARGET}.pdb\")") 471 else() 472 install(CODE "file(INSTALL DESTINATION \"\${CMAKE_INSTALL_PREFIX}/${DIRECTORY}\" TYPE FILE OPTIONAL FILES \"${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TARGET}.dir/${TARGET}.pdb\")") 473 endif() 474 endif() 475endfunction() 476[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.