Skip to content

Commit

Permalink
cmake: detect CPU architecture in 1 compilation
Browse files Browse the repository at this point in the history
  • Loading branch information
madebr committed May 26, 2024
1 parent 3af4f12 commit bba7685
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 154 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ jobs:
-B build_x64 -A x64
cmake --build build_x64 --config Release --verbose
ctest --test-dir build_x64 --no-tests=error -C Release --output-on-failure
- name: 'CMake (configure + build + tests) arm64'
- name: 'CMake (configure + build) arm64'
run: |
$env:PATH += ";${{ steps.bin.outputs.path }}/x86"
cmake -S "${{ steps.src.outputs.path }}/cmake/test" `
Expand Down
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,16 @@ list(APPEND CMAKE_MODULE_PATH "${SDL3_SOURCE_DIR}/cmake")
include("${SDL3_SOURCE_DIR}/cmake/macros.cmake")
include("${SDL3_SOURCE_DIR}/cmake/sdlchecks.cmake")
include("${SDL3_SOURCE_DIR}/cmake/sdlcompilers.cmake")
include("${SDL3_SOURCE_DIR}/cmake/sdlcpu.cmake")
include("${SDL3_SOURCE_DIR}/cmake/sdlmanpages.cmake")
include("${SDL3_SOURCE_DIR}/cmake/sdlplatform.cmake")
include("${SDL3_SOURCE_DIR}/cmake/sdltargets.cmake")
include("${SDL3_SOURCE_DIR}/cmake/CheckCPUArchitecture.cmake")
include("${SDL3_SOURCE_DIR}/cmake/GetGitRevisionDescription.cmake")
include("${SDL3_SOURCE_DIR}/cmake/3rdparty.cmake")
include("${SDL3_SOURCE_DIR}/cmake/PreseedMSVCCache.cmake")

SDL_DetectCompiler()
SDL_DetectCPUArchitecture()
SDL_DetectTargetCPUArchitectures(SDL_CPUS)
SDL_Preseed_CMakeCache()

# Increment this if there is an incompatible change - but if that happens,
Expand Down
7 changes: 5 additions & 2 deletions VisualC/pkg-support/cmake/sdl3-config-version.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,11 @@ if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "")
set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()

include("${CMAKE_CURRENT_LIST_DIR}/sdlcpu.cmake")
SDL_DetectTargetCPUArchitectures(_detected_archs)

# check that the installed version has a compatible architecture as the one which is currently searching:
if(NOT (CMAKE_SYSTEM_PROCESSOR MATCHES "([aA][mM][dD]64|[xX]86((_|-)64)?|[iI][34567]86|[aA][aA][rR][cC][hH]64|[aA][rR][mM]64)"))
set(PACKAGE_VERSION "${PACKAGE_VERSION} (x86,x64,arm64)")
if(NOT(SDL_CPU_X86 OR SDL_CPU_X64 OR SDL_CPU_ARM64))
set(PACKAGE_VERSION "${PACKAGE_VERSION} (X86,X64,ARM64)")
set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()
46 changes: 18 additions & 28 deletions VisualC/pkg-support/cmake/sdl3-config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -30,34 +30,24 @@ endmacro()

set(SDL3_FOUND TRUE)

if(CMAKE_SYSTEM_PROCESSOR MATCHES "([aA][mM][dD]64|[xX]86(_|-64)?|[iI][34567]86)")
if(CMAKE_SIZEOF_VOID_P EQUAL "4")
set(_sdl_arch_subdir "x86")
elseif(CMAKE_SIZEOF_VOID_P EQUAL "8")
set(_sdl_arch_subdir "x64")
else()
set(SDL3_FOUND FALSE)
return()
endif()
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "([aA][aA][rR][cC][hH]64|[aA][rR][mM]64)")
if(CMAKE_SIZEOF_VOID_P EQUAL "8")
set(_sdl_arch_subdir "arm64")
else()
set(SDL3_FOUND FALSE)
return()
endif()
if(SDL_CPU_X86)
set(_sdl_arch_subdir "x86")
elseif(SDL_CPU_X64)
set(_sdl_arch_subdir "x64")
elseif(SDL_CPU_ARM64)
set(_sdl_arch_subdir "arm64")
else()
set(SDL3_FOUND FALSE)
return()
endif()

get_filename_component(_sdl3_prefix "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE)
set_and_check(_sdl3_prefix "${_sdl3_prefix}")
set(_sdl3_include_dirs "${_sdl3_prefix}/include;${_sdl3_prefix}/include/SDL3")
set(_sdl3_include_dirs "${_sdl3_prefix}/include")

set(_sdl3_library "${_sdl3_prefix}/lib/${_sdl_arch_subdir}/SDL3.lib")
set(_sdl3_dll_library "${_sdl3_prefix}/lib/${_sdl_arch_subdir}/SDL3.dll")
set(_sdl3test_library "${_sdl3_prefix}/lib/${_sdl_arch_subdir}/SDL3_test.lib")
set(_sdl3_implib "${_sdl3_prefix}/lib/${_sdl_arch_subdir}/SDL3.lib")
set(_sdl3_dll "${_sdl3_prefix}/lib/${_sdl_arch_subdir}/SDL3.dll")
set(_sdl3test_lib "${_sdl3_prefix}/lib/${_sdl_arch_subdir}/SDL3_test.lib")

unset(_sdl_arch_subdir)
unset(_sdl3_prefix)
Expand All @@ -75,14 +65,14 @@ endif()
set(SDL3_Headers_FOUND TRUE)
unset(_sdl3_include_dirs)

if(EXISTS "${_sdl3_library}" AND EXISTS "${_sdl3_dll_library}")
if(EXISTS "${_sdl3_implib}" AND EXISTS "${_sdl3_dll}")
if(NOT TARGET SDL3::SDL3-shared)
add_library(SDL3::SDL3-shared SHARED IMPORTED)
set_target_properties(SDL3::SDL3-shared
PROPERTIES
INTERFACE_LINK_LIBRARIES "SDL3::Headers"
IMPORTED_IMPLIB "${_sdl3_library}"
IMPORTED_LOCATION "${_sdl3_dll_library}"
IMPORTED_IMPLIB "${_sdl3_implib}"
IMPORTED_LOCATION "${_sdl3_dll}"
COMPATIBLE_INTERFACE_BOOL "SDL3_SHARED"
INTERFACE_SDL3_SHARED "ON"
COMPATIBLE_INTERFACE_STRING "SDL_VERSION"
Expand All @@ -93,18 +83,18 @@ if(EXISTS "${_sdl3_library}" AND EXISTS "${_sdl3_dll_library}")
else()
set(SDL3_SDL3-shared_FOUND FALSE)
endif()
unset(_sdl3_library)
unset(_sdl3_dll_library)
unset(_sdl3_implib)
unset(_sdl3_dll)

set(SDL3_SDL3-static_FOUND FALSE)

if(EXISTS "${_sdl3test_library}")
if(EXISTS "${_sdl3test_lib}")
if(NOT TARGET SDL3::SDL3_test)
add_library(SDL3::SDL3_test STATIC IMPORTED)
set_target_properties(SDL3::SDL3_test
PROPERTIES
INTERFACE_LINK_LIBRARIES "SDL3::Headers"
IMPORTED_LOCATION "${_sdl3test_library}"
IMPORTED_LOCATION "${_sdl3test_lib}"
COMPATIBLE_INTERFACE_STRING "SDL_VERSION"
INTERFACE_SDL_VERSION "SDL3"
)
Expand All @@ -113,7 +103,7 @@ if(EXISTS "${_sdl3test_library}")
else()
set(SDL3_SDL3_test_FOUND FALSE)
endif()
unset(_sdl3test_library)
unset(_sdl3test_lib)

if(SDL3_SDL3-shared_FOUND)
set(SDL3_SDL3_FOUND TRUE)
Expand Down
1 change: 1 addition & 0 deletions build-scripts/build-release.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ def zip_directory(zf: zipfile.ZipFile, directory: Path, arcrelpath: str):
zip_directory(zf, directory=self.root / "include/SDL3", arcrelpath="include/SDL3")
zip_directory(zf, directory=self.root / "docs", arcrelpath="docs")
zip_directory(zf, directory=self.root / "VisualC/pkg-support/cmake", arcrelpath="cmake")
zip_file(zf, path=self.root / "cmake/sdlcpu.cmake", arcrelpath="cmake/sdlcpu.cmake")

for txt in ("BUGS.txt", "README-SDL.txt", "WhatsNew.txt"):
zip_file(zf, path=self.root / txt, arcrelpath=txt)
Expand Down
48 changes: 0 additions & 48 deletions cmake/CheckCPUArchitecture.cmake

This file was deleted.

149 changes: 149 additions & 0 deletions cmake/sdlcpu.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
function(SDL_DetectTargetCPUArchitectures DETECTED_ARCHS)

set(DETECTABLE_ARCHS ARM32 ARM64 EMSCRIPTEN LOONGARCH64 POWERPC32 POWERPC64 X86 X64)

if(APPLE AND CMAKE_OSX_ARCHITECTURES)
foreach(arch IN LISTS DETECTABLE_ARCHS)
set(SDL_CPU_${arch} "0")
endforeach()
set(detected_archs)
foreach(osx_arch IN LISTS CMAKE_OSX_ARCHITECTURES)
if(osx_arch STREQUAL "x86_64")
set(SDL_CPU_X64 "1")
list(APPEND detected_archs "X64")
elseif(osx_arch STREQUAL "arm64")
set(SDL_CPU_ARM64 "1")
list(APPEND detected_archs "ARM64")
endif()
endforeach()
set("${DETECTED_ARCHS}" "${detected_archs}" PARENT_SCOPE)
return()
endif()

set(detected_archs)
foreach(arch IN LISTS DETECTABLE_ARCHS)
if(SDL_CPU_${arch})
list(APPEND detected_archs "${arch}")
endif()
endforeach()

if(detected_archs)
set("${DETECTED_ARCHS}" "${detected_archs}" PARENT_SCOPE)
return()
endif()

set(src_arch_detect [=====[

#if defined(__arm__) || defined(_M_ARM)
#define ARCH_ARM32 "1"
#else
#define ARCH_ARM32 "0"
#endif
const char *arch_arm32 = "INFO<ARM32=" ARCH_ARM32 ">";

#if defined(__aarch64__) || defined(_M_ARM64)
#define ARCH_ARM64 "1"
#else
#define ARCH_ARM64 "0"
#endif
const char *arch_arm64 = "INFO<ARM64=" ARCH_ARM64 ">";

#if defined(__EMSCRIPTEN__)
#define ARCH_EMSCRIPTEN "1"
#else
#define ARCH_EMSCRIPTEN "0"
#endif
const char *arch_emscripten = "INFO<EMSCRIPTEN=" ARCH_EMSCRIPTEN ">";

#if defined(__loongarch64)
#define ARCH_LOONGARCH64 "1"
#else
#define ARCH_LOONGARCH64 "0"
#endif
const char *arch_loongarch64 = "INFO<LOONGARCH64=" ARCH_LOONGARCH64 ">";

#if (defined(__PPC__) || defined(__powerpc__)) && !defined(__powerpc64__)
#define ARCH_POWERPC32 "1"
#else
#define ARCH_POWERPC32 "0"
#endif
const char *arch_powerpc32 = "INFO<ARCH_POWERPC32=" ARCH_POWERPC32 ">";

#if defined(__PPC64__) || defined(__powerpc64__)
#define ARCH_POWERPC64 "1"
#else
#define ARCH_POWERPC64 "0"
#endif
const char *arch_powerpc64 = "INFO<POWERPC64=" ARCH_POWERPC64 ">";

#if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) ||defined( __i386) || defined(_M_IX86)
#define ARCH_X86 "1"
#else
#define ARCH_X86 "0"
#endif
const char *arch_x86 = "INFO<X86=" ARCH_X86 ">";

#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)
#define ARCH_X64 "1"
#else
#define ARCH_X64 "0"
#endif
const char *arch_x64 = "INFO<X64=" ARCH_X64 ">";

int main(int argc, char *argv[]) {
(void) argv;
int result = argc;
result += arch_arm32[argc];
result += arch_arm64[argc];
result += arch_emscripten[argc];
result += arch_loongarch64[argc];
result += arch_powerpc32[argc];
result += arch_powerpc64[argc];
result += arch_x86[argc];
result += arch_x64[argc];
return result;
}
]=====])

set(path_src_arch_detect "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp/SDL_detect_arch.c")
file(WRITE "${path_src_arch_detect}" "${src_arch_detect}")
set(path_dir_arch_detect "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp/SDL_detect_arch")
set(path_bin_arch_detect "${path_dir_arch_detect}/bin")

set(msg "Detecting Target CPU Architecture")
message(STATUS "${msg}")

try_compile(COMPILED_RES
"${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp/SDL_detect_arch"
SOURCES "${path_src_arch_detect}"
COPY_FILE "${path_bin_arch_detect}"
)
if(NOT COMPILED_RES)
message(STATUS "${msg} - <ERROR>")
message(WARNING "Failed to compile source detecting the target CPU architecture")
endif()

set(re "INFO<([A-Z0-9]+)=([01])>")
file(STRINGS "${path_bin_arch_detect}" infos REGEX "${re}")

set(detected_archs)

foreach(info_arch_01 IN LISTS infos)
string(REGEX MATCH "${re}" A "${info_arch_01}")
if(NOT "${CMAKE_MATCH_1}" IN_LIST DETECTABLE_ARCHS)
message(WARNING "Unknown architecture: \"${CMAKE_MATCH_1}\"")
continue()
endif()
set(arch "${CMAKE_MATCH_1}")
set(arch_01 "${CMAKE_MATCH_2}")
if(arch_01)
list(APPEND detected_archs "${arch}")
endif()
set("SDL_CPU_${arch}" "${arch_01}" CACHE BOOL "Detected architecture ${arch}")
endforeach()

message(STATUS "${msg} - ${detected_archs}")

set("${DETECTED_ARCHS}" "${detected_archs}" PARENT_SCOPE)

endfunction()
Loading

0 comments on commit bba7685

Please sign in to comment.