Add Windows ARM64 build support (#6635)

This commit is contained in:
Qshadow
2026-06-06 23:01:40 +03:00
committed by GitHub
parent ef014a35e6
commit f45d65381f
3 changed files with 59 additions and 14 deletions
+16 -1
View File
@@ -81,10 +81,24 @@ add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/utf-8>)
add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/Zc:preprocessor>)
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
if(NOT CMAKE_VS_PLATFORM_NAME)
set(CMAKE_VS_PLATFORM_NAME "x64")
endif()
if("${CMAKE_VS_PLATFORM_NAME}" MATCHES "^[Aa][Rr][Mm]64$")
set(SOH_WINDOWS_ARM64 TRUE)
else()
set(SOH_WINDOWS_ARM64 FALSE)
endif()
include(CMake/automate-vcpkg.cmake)
set(VCPKG_TRIPLET x64-windows-static)
set(VCPKG_TARGET_TRIPLET x64-windows-static)
if(SOH_WINDOWS_ARM64)
set(VCPKG_TRIPLET arm64-windows-static)
set(VCPKG_TARGET_TRIPLET arm64-windows-static)
endif()
vcpkg_bootstrap()
vcpkg_install_packages(zlib bzip2 libzip libpng sdl2 sdl2-net glew glfw3 nlohmann-json tinyxml2 spdlog libogg libvorbis opus opusfile)
@@ -103,7 +117,8 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
message("${CMAKE_VS_PLATFORM_NAME} architecture in use")
if(NOT ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64"
OR "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32"))
OR "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32"
OR SOH_WINDOWS_ARM64))
message(FATAL_ERROR "${CMAKE_VS_PLATFORM_NAME} arch is not supported!")
endif()
endif()
+18 -7
View File
@@ -22,10 +22,21 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
if(NOT CMAKE_VS_PLATFORM_NAME)
set(CMAKE_VS_PLATFORM_NAME "x64")
endif()
if("${CMAKE_VS_PLATFORM_NAME}" MATCHES "^[Aa][Rr][Mm]64$")
set(SOH_WINDOWS_ARM64 TRUE)
else()
set(SOH_WINDOWS_ARM64 FALSE)
endif()
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64" OR SOH_WINDOWS_ARM64)
set(SOH_WINDOWS_64BIT TRUE)
else()
set(SOH_WINDOWS_64BIT FALSE)
endif()
message("${CMAKE_VS_PLATFORM_NAME} architecture in use")
if(NOT ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64"
OR "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32"))
OR "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32"
OR SOH_WINDOWS_ARM64))
message(FATAL_ERROR "${CMAKE_VS_PLATFORM_NAME} arch is not supported!")
endif()
endif()
@@ -235,7 +246,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
set_target_properties(${PROJECT_NAME} PROPERTIES
VS_GLOBAL_KEYWORD "Win32Proj"
)
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
if(SOH_WINDOWS_64BIT)
set_target_properties(${PROJECT_NAME} PROPERTIES
INTERPROCEDURAL_OPTIMIZATION_RELEASE "TRUE"
)
@@ -259,7 +270,7 @@ endif()
################################################################################
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
get_property(MSVC_RUNTIME_LIBRARY_DEFAULT TARGET ${PROJECT_NAME} PROPERTY MSVC_RUNTIME_LIBRARY)
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
if(SOH_WINDOWS_64BIT)
string(CONCAT "MSVC_RUNTIME_LIBRARY_STR"
$<$<CONFIG:Debug>:
MultiThreadedDebug
@@ -329,7 +340,7 @@ target_include_directories(${PROJECT_NAME} PRIVATE assets
)
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
if(SOH_WINDOWS_64BIT)
target_compile_definitions(${PROJECT_NAME} PRIVATE
"$<$<CONFIG:Debug>:"
"_DEBUG;"
@@ -410,7 +421,7 @@ endif()
# Compile and link options
################################################################################
if(MSVC)
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
if(SOH_WINDOWS_64BIT)
target_compile_options(${PROJECT_NAME} PRIVATE
$<$<CONFIG:Debug>:
/w;
@@ -447,7 +458,7 @@ if(MSVC)
${DEFAULT_CXX_EXCEPTION_HANDLING}
)
endif()
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
if(SOH_WINDOWS_64BIT)
target_link_options(${PROJECT_NAME} PRIVATE
$<$<CONFIG:Debug>:
/INCREMENTAL
@@ -635,7 +646,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
link_libraries(Opus::opus)
find_package(OpusFile CONFIG REQUIRED)
link_libraries(OpusFile::opusfile CONFIG REQUIRED)
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
if(SOH_WINDOWS_64BIT)
set(ADDITIONAL_LIBRARY_DEPENDENCIES
"libultraship;"
"ZAPDLib;"
+25 -6
View File
@@ -12,11 +12,18 @@
#pragma GCC target("sse4.2")
#endif
// Include headers for the CRC32 intrinsic and cpuid instruction on windows. No need to do any other checks because it
// assumes the target will support CRC32
// Include headers for the CRC32 intrinsic and CPU feature checks on Windows x86/x64/ARM64.
#ifdef _WIN32
#include <immintrin.h>
#if defined(_M_X64) || defined(_M_IX86) || defined(_M_ARM64)
#include <intrin.h>
#if defined(_M_X64) || defined(_M_IX86)
#include <immintrin.h>
#elif defined(_M_ARM64)
#include <Windows.h>
#endif
#else
#define NO_CRC_INTRIN
#endif
// Same as above but these platforms use slightly different headers
#elif ((defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))))
#include <nmmintrin.h>
@@ -27,12 +34,18 @@
#define NO_CRC_INTRIN
#endif
#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32)
#if defined(_MSC_VER) && defined(_M_ARM64)
#define INTRIN_CRC32_64(crc, data) crc = __crc32cd(crc, data)
#define INTRIN_CRC32_32(crc, data) crc = __crc32cw(crc, data)
#define INTRIN_CRC32_16(crc, data) crc = __crc32ch(crc, data)
#define INTRIN_CRC32_8(crc, data) crc = __crc32cb(crc, data)
#elif defined(__aarch64__) && defined(__ARM_FEATURE_CRC32)
#define INTRIN_CRC32_64(crc, value) __asm__("crc32cx %w[c], %w[c], %x[v]" : [c] "+r"(crc) : [v] "r"(value))
#define INTRIN_CRC32_32(crc, value) __asm__("crc32cw %w[c], %w[c], %w[v]" : [c] "+r"(crc) : [v] "r"(value))
#define INTRIN_CRC32_16(crc, value) __asm__("crc32ch %w[c], %w[c], %w[v]" : [c] "+r"(crc) : [v] "r"(value))
#define INTRIN_CRC32_8(crc, value) __asm__("crc32cb %w[c], %w[c], %w[v]" : [c] "+r"(crc) : [v] "r"(value))
#elif defined(__GNUC__) || defined(_MSC_VER)
#elif ((defined(__GNUC__) || defined(_MSC_VER)) && \
(defined(_M_X64) || defined(_M_IX86) || defined(__x86_64__) || defined(__i386__)))
#define INTRIN_CRC32_64(crc, data) crc = _mm_crc32_u64(crc, data)
#define INTRIN_CRC32_32(crc, data) crc = _mm_crc32_u32(crc, data)
#define INTRIN_CRC32_16(crc, data) crc = _mm_crc32_u16(crc, data)
@@ -78,7 +91,7 @@ static uint32_t CRC32IntrinImpl(unsigned char* data, size_t dataSize) {
uint32_t ret = 0xFFFFFFFF;
int64_t sizeSigned = dataSize;
// Only 64bit platforms support doing a CRC32 operation on a 64bit value
#if defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__)
#if defined(_M_X64) || defined(_M_ARM64) || defined(__x86_64__) || defined(__aarch64__)
while ((sizeSigned -= sizeof(uint64_t)) >= 0) {
INTRIN_CRC32_64(ret, *(uint64_t*)data);
data += sizeof(uint64_t);
@@ -122,6 +135,11 @@ static uint32_t CRC32TableImpl(unsigned char* data, size_t dataSize) {
uint32_t CRC32C(unsigned char* data, size_t dataSize) {
#ifndef NO_CRC_INTRIN
// Test to make sure the CPU supports the CRC32 intrinsic
#if defined(_WIN32) && defined(_M_ARM64)
if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE)) {
return CRC32IntrinImpl(data, dataSize);
}
#else
unsigned int cpuidData[4];
#ifdef _WIN32
__cpuid(cpuidData, 1);
@@ -135,6 +153,7 @@ uint32_t CRC32C(unsigned char* data, size_t dataSize) {
if (cpuidData[2] & (1 << 20)) { // bit_SSE4_2
return CRC32IntrinImpl(data, dataSize);
}
#endif
#endif // NO_CRC_INTRIN
return CRC32TableImpl(data, dataSize);
}