From 8325b97f022849edadec9839c3b9a4c8c97477bb Mon Sep 17 00:00:00 2001 From: cfillion Date: Sat, 11 Nov 2023 08:58:29 -0500 Subject: [PATCH 1/2] add Windows ARM64EC builds (Windows 11, REAPER 7.04+) https://devblogs.microsoft.com/windows-music-dev/load-x64-plug-ins-like-vsts-from-your-arm-code-using-arm64ec/ https://devblogs.microsoft.com/cppblog/arm64ec-support-in-visual-studio/ https://techcommunity.microsoft.com/t5/windows-os-platform-blog/getting-to-know-arm64ec-defines-and-intrinsic-functions/ba-p/2957235 --- .appveyor.yml | 19 ++- .../arm64ec-windows-static.cmake | 3 + src/platform.cpp | 11 +- src/platform.hpp | 9 +- test/platform.cpp | 135 ++++++++++-------- 5 files changed, 100 insertions(+), 77 deletions(-) create mode 100644 cmake/vcpkg-triplets/arm64ec-windows-static.cmake diff --git a/.appveyor.yml b/.appveyor.yml index 273577e9..9b89da88 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -14,7 +14,8 @@ build_script: - cmake --build build test_script: - - '[ "$ARCH" = "arm64" ] || cmake --build build --target test' + - sh: '[[ "$ARCH" = arm64 ]] || cmake --build build --target test' + - cmd: 'if NOT "%ARCH%" == "arm64ec" cmake --build build --target test' for: - matrix: { only: [ appveyor_build_worker_image: &linux Ubuntu1804 ] } @@ -113,11 +114,14 @@ for: - matrix: { only: [ appveyor_build_worker_image: &windows Visual Studio 2022 ] } cache: - - build\vcpkg_installed -> vcpkg.json + - build\vcpkg_installed -> vcpkg.json, cmake\vcpkg-triplets\arm64ec-windows-static.cmake install: - - if "%ARCH%" == "x64" call "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" - - if "%ARCH%" == "x86" call "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars32.bat" + - if "%ARCH%" == "x64" call "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" + - if "%ARCH%" == "x86" call "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars32.bat" + - if "%ARCH%" == "arm64ec" call "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsamd64_arm64.bat" + - if "%ARCH%" == "arm64ec" set CFLAGS=-arm64EC & set CXXFLAGS=-arm64EC build_script: + - set VCPKG_OVERLAY_TRIPLETS=cmake\vcpkg-triplets - cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DVCPKG_TARGET_TRIPLET=%ARCH%-windows-static -DCMAKE_TOOLCHAIN_FILE=C:\Tools\vcpkg\scripts\buildsystems\vcpkg.cmake @@ -128,12 +132,15 @@ for: environment: matrix: - - job_name: Windows 64-bit + - job_name: Windows x86 64-bit appveyor_build_worker_image: *windows ARCH: x64 - - job_name: Windows 32-bit + - job_name: Windows x86 32-bit appveyor_build_worker_image: *windows ARCH: x86 + - job_name: Windows ARM 64-bit EC + appveyor_build_worker_image: *windows + ARCH: arm64ec - job_name: macOS x86 64-bit appveyor_build_worker_image: macos-mojave ARCH: x86_64 diff --git a/cmake/vcpkg-triplets/arm64ec-windows-static.cmake b/cmake/vcpkg-triplets/arm64ec-windows-static.cmake new file mode 100644 index 00000000..ebd39906 --- /dev/null +++ b/cmake/vcpkg-triplets/arm64ec-windows-static.cmake @@ -0,0 +1,3 @@ +set(VCPKG_TARGET_ARCHITECTURE arm64ec) +set(VCPKG_CRT_LINKAGE static) +set(VCPKG_LIBRARY_LINKAGE static) diff --git a/src/platform.cpp b/src/platform.cpp index fa04a40f..0078963e 100644 --- a/src/platform.cpp +++ b/src/platform.cpp @@ -46,7 +46,9 @@ const Platform::Enum Platform::Current = Platform:: # endif #elif _WIN32 -# ifdef _WIN64 +# ifdef _M_ARM64EC + Windows_arm64ec +# elif _M_X64 Windows_x64 # else Windows_x86 @@ -76,9 +78,10 @@ auto Platform::parse(const char *platform) -> Enum { "linux-armv7l", Linux_armv7l }, { "linux-aarch64", Linux_aarch64 }, - { "windows", Windows_Any }, - { "win32", Windows_x86 }, - { "win64", Windows_x64 }, + { "windows", Windows_Any }, + { "win32", Windows_x86 }, + { "win64", Windows_x64 }, + { "windows-arm64ec", Windows_arm64ec }, }; for(auto &[key, value] : map) { diff --git a/src/platform.hpp b/src/platform.hpp index 277da197..c1fe20f4 100644 --- a/src/platform.hpp +++ b/src/platform.hpp @@ -34,11 +34,12 @@ class Platform { Linux_aarch64 = 1<<6, Linux_Any = Linux_i686 | Linux_x86_64 | Linux_armv7l | Linux_aarch64, - Windows_x86 = 1<<7, - Windows_x64 = 1<<8, - Windows_Any = Windows_x86 | Windows_x64, + Windows_x86 = 1<<7, + Windows_x64 = 1<<8, + Windows_arm64ec = 1<<9, + Windows_Any = Windows_x86 | Windows_x64 | Windows_arm64ec, - Generic = Darwin_Any | Linux_Any | Windows_Any, + Generic = Darwin_Any | Linux_Any | Windows_Any, }; static const Enum Current; diff --git a/test/platform.cpp b/test/platform.cpp index e5f40e9c..9b06b6df 100644 --- a/test/platform.cpp +++ b/test/platform.cpp @@ -20,9 +20,10 @@ TEST_CASE("platform from string", M) { REQUIRE(Platform("all") == Platform::Generic); SECTION("windows") { - REQUIRE(Platform("windows") == Platform::Windows_Any); - REQUIRE(Platform("win32") == Platform::Windows_x86); - REQUIRE(Platform("win64") == Platform::Windows_x64); + REQUIRE(Platform("windows") == Platform::Windows_Any); + REQUIRE(Platform("win32") == Platform::Windows_x86); + REQUIRE(Platform("win64") == Platform::Windows_x64); + REQUIRE(Platform("windows-arm64ec") == Platform::Windows_arm64ec); } SECTION("macOS") { @@ -47,84 +48,92 @@ TEST_CASE("test platform", M) { {Platform::Generic, true }, #ifdef __APPLE__ - {Platform::Linux_Any, false}, - {Platform::Linux_x86_64, false}, - {Platform::Linux_i686, false}, - {Platform::Linux_armv7l, false}, - {Platform::Linux_aarch64, false}, - {Platform::Windows_Any, false}, - {Platform::Windows_x64, false}, - {Platform::Windows_x86, false}, - - {Platform::Darwin_Any, true }, + {Platform::Linux_Any, false}, + {Platform::Linux_x86_64, false}, + {Platform::Linux_i686, false}, + {Platform::Linux_armv7l, false}, + {Platform::Linux_aarch64, false}, + {Platform::Windows_Any, false}, + {Platform::Windows_x64, false}, + {Platform::Windows_x86, false}, + {Platform::Windows_arm64ec, false}, + + {Platform::Darwin_Any, true }, # ifdef __x86_64__ - {Platform::Darwin_i386, false}, - {Platform::Darwin_x86_64, true }, - {Platform::Darwin_arm64, false}, + {Platform::Darwin_i386, false}, + {Platform::Darwin_x86_64, true }, + {Platform::Darwin_arm64, false}, # elif __i386__ - {Platform::Darwin_i386, true }, - {Platform::Darwin_x86_64, false}, - {Platform::Darwin_arm64, false}, + {Platform::Darwin_i386, true }, + {Platform::Darwin_x86_64, false}, + {Platform::Darwin_arm64, false}, # elif __arm64__ - {Platform::Darwin_i386, false}, - {Platform::Darwin_x86_64, false}, - {Platform::Darwin_arm64, true }, + {Platform::Darwin_i386, false}, + {Platform::Darwin_x86_64, false}, + {Platform::Darwin_arm64, true }, # else # error Untested architecture # endif #elif __linux__ - {Platform::Darwin_Any, false}, - {Platform::Darwin_i386, false}, - {Platform::Darwin_x86_64, false}, - {Platform::Darwin_arm64, false}, - {Platform::Windows_Any, false}, - {Platform::Windows_x86, false}, - {Platform::Windows_x64, false}, - - {Platform::Linux_Any, true }, + {Platform::Darwin_Any, false}, + {Platform::Darwin_i386, false}, + {Platform::Darwin_x86_64, false}, + {Platform::Darwin_arm64, false}, + {Platform::Windows_Any, false}, + {Platform::Windows_x86, false}, + {Platform::Windows_x64, false}, + {Platform::Windows_arm64ec, false}, + + {Platform::Linux_Any, true }, # ifdef __x86_64__ - {Platform::Linux_i686, false}, - {Platform::Linux_x86_64, true }, - {Platform::Linux_armv7l, false}, - {Platform::Linux_aarch64, false}, + {Platform::Linux_i686, false}, + {Platform::Linux_x86_64, true }, + {Platform::Linux_armv7l, false}, + {Platform::Linux_aarch64, false}, # elif __i686__ - {Platform::Linux_i686, true }, - {Platform::Linux_x86_64, false}, - {Platform::Linux_armv7l, false}, - {Platform::Linux_aarch64, false}, + {Platform::Linux_i686, true }, + {Platform::Linux_x86_64, false}, + {Platform::Linux_armv7l, false}, + {Platform::Linux_aarch64, false}, # elif __ARM_ARCH_7A__ - {Platform::Linux_i686, false}, - {Platform::Linux_x86_64, false}, - {Platform::Linux_armv7l, true }, - {Platform::Linux_aarch64, false}, + {Platform::Linux_i686, false}, + {Platform::Linux_x86_64, false}, + {Platform::Linux_armv7l, true }, + {Platform::Linux_aarch64, false}, # elif __aarch64__ - {Platform::Linux_i686, false}, - {Platform::Linux_x86_64, false}, - {Platform::Linux_armv7l, false}, - {Platform::Linux_aarch64, true }, + {Platform::Linux_i686, false}, + {Platform::Linux_x86_64, false}, + {Platform::Linux_armv7l, false}, + {Platform::Linux_aarch64, true }, # else # error Untested architecture # endif #elif _WIN32 - {Platform::Darwin_Any, false}, - {Platform::Darwin_i386, false}, - {Platform::Darwin_x86_64, false}, - {Platform::Darwin_arm64, false}, - {Platform::Linux_Any, false}, - {Platform::Linux_x86_64, false}, - {Platform::Linux_i686, false}, - {Platform::Linux_armv7l, false}, - {Platform::Linux_aarch64, false}, - - {Platform::Windows_Any, true }, -# ifdef _WIN64 - {Platform::Windows_x86, false}, - {Platform::Windows_x64, true }, + {Platform::Darwin_Any, false}, + {Platform::Darwin_i386, false}, + {Platform::Darwin_x86_64, false}, + {Platform::Darwin_arm64, false}, + {Platform::Linux_Any, false}, + {Platform::Linux_x86_64, false}, + {Platform::Linux_i686, false}, + {Platform::Linux_armv7l, false}, + {Platform::Linux_aarch64, false}, + + {Platform::Windows_Any, true }, +# ifdef _M_ARM64EC + {Platform::Windows_x86, false}, + {Platform::Windows_x64, false}, + {Platform::Windows_arm64ec, true }, +# elif _M_X64 + {Platform::Windows_x86, false}, + {Platform::Windows_x64, true }, + {Platform::Windows_arm64ec, false}, # else - {Platform::Windows_x86, true }, - {Platform::Windows_x64, false}, + {Platform::Windows_x86, true }, + {Platform::Windows_x64, false}, + {Platform::Windows_arm64ec, false}, # endif #else From 5cfa34158b1174c3adeaef11ca90b3765d7bec96 Mon Sep 17 00:00:00 2001 From: cfillion Date: Tue, 29 Oct 2024 15:32:27 -0400 Subject: [PATCH 2/2] install x64 binaries when packages don't provide arm64ec ones --- src/index_v1.cpp | 29 +++++++++++++++++++++-------- src/platform.cpp | 7 +++++-- src/platform.hpp | 5 +++-- test/platform.cpp | 1 + 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/index_v1.cpp b/src/index_v1.cpp index 5eaf3145..2d0491a6 100644 --- a/src/index_v1.cpp +++ b/src/index_v1.cpp @@ -22,11 +22,11 @@ #include -static void LoadMetadataV1(XmlNode , Metadata *); -static void LoadCategoryV1(XmlNode , Index *); -static void LoadPackageV1(XmlNode , Category *); -static void LoadVersionV1(XmlNode , Package *); -static void LoadSourceV1(XmlNode , Version *); +static void LoadMetadataV1(XmlNode, Metadata *); +static void LoadCategoryV1(XmlNode, Index *); +static void LoadPackageV1(XmlNode, Category *); +static void LoadVersionV1(XmlNode, Package *); +static void LoadSourceV1(XmlNode, Version *, bool hasArm64Ec); void Index::loadV1(XmlNode root, Index *ri) { @@ -117,8 +117,21 @@ void LoadVersionV1(XmlNode verNode, Package *pkg) XmlNode node = verNode.firstChild("source"); + bool hasArm64Ec = false; +#if defined(_WIN32) && defined(_M_ARM64EC) while(node) { - LoadSourceV1(node, ver); + const char *platform = *node.attribute("platform"); + if(platform && Platform(platform) == Platform::Windows_arm64ec) { + hasArm64Ec = true; + break; + } + node = node.nextSibling("source"); + } + node = verNode.firstChild("source"); +#endif + + while(node) { + LoadSourceV1(node, ver, hasArm64Ec); node = node.nextSibling("source"); } @@ -133,7 +146,7 @@ void LoadVersionV1(XmlNode verNode, Package *pkg) ptr.release(); } -void LoadSourceV1(XmlNode node, Version *ver) +void LoadSourceV1(XmlNode node, Version *ver, const bool hasArm64Ec) { const XmlString &platform = node.attribute("platform"), &type = node.attribute("type"), @@ -146,7 +159,7 @@ void LoadSourceV1(XmlNode node, Version *ver) std::unique_ptr ptr(src); src->setChecksum(checksum.value_or("")); - src->setPlatform(platform.value_or("all")); + src->setPlatform(Platform(platform.value_or("all"), hasArm64Ec)); src->setTypeOverride(Package::getType(type.value_or(""))); int sections = 0; diff --git a/src/platform.cpp b/src/platform.cpp index 0078963e..663b7399 100644 --- a/src/platform.cpp +++ b/src/platform.cpp @@ -62,7 +62,7 @@ const Platform::Enum Platform::Current = Platform:: static_assert(Platform::Current != Platform::Unknown, "The current operating system or architecture is not supported."); -auto Platform::parse(const char *platform) -> Enum +auto Platform::parse(const char *platform, const bool hasArm64Ec) -> Enum { constexpr std::pair map[] { { "all", Generic }, @@ -85,8 +85,11 @@ auto Platform::parse(const char *platform) -> Enum }; for(auto &[key, value] : map) { - if(!strcmp(platform, key)) + if(!strcmp(platform, key)) { + if(!hasArm64Ec && value == Windows_x64) + return Windows_x64_arm64ec; return value; + } } return Unknown; diff --git a/src/platform.hpp b/src/platform.hpp index c1fe20f4..8ca3383f 100644 --- a/src/platform.hpp +++ b/src/platform.hpp @@ -38,6 +38,7 @@ class Platform { Windows_x64 = 1<<8, Windows_arm64ec = 1<<9, Windows_Any = Windows_x86 | Windows_x64 | Windows_arm64ec, + Windows_x64_arm64ec = Windows_x64 | Windows_arm64ec, Generic = Darwin_Any | Linux_Any | Windows_Any, }; @@ -46,7 +47,7 @@ class Platform { Platform() : m_value(Generic) {} Platform(Enum val) : m_value(val) {} - Platform(const char *str) : m_value(parse(str)) {} + Platform(const char *str, bool hasArm64Ec = true) : m_value(parse(str, hasArm64Ec)) {} Enum value() const { return m_value; } bool test() const; @@ -55,7 +56,7 @@ class Platform { Platform &operator=(Enum n) { m_value = n; return *this; } private: - static Enum parse(const char *); + static Enum parse(const char *, bool hasArm64Ec); Enum m_value; }; diff --git a/test/platform.cpp b/test/platform.cpp index 9b06b6df..32fd46ed 100644 --- a/test/platform.cpp +++ b/test/platform.cpp @@ -23,6 +23,7 @@ TEST_CASE("platform from string", M) { REQUIRE(Platform("windows") == Platform::Windows_Any); REQUIRE(Platform("win32") == Platform::Windows_x86); REQUIRE(Platform("win64") == Platform::Windows_x64); + REQUIRE(Platform("win64", false) == Platform::Windows_x64_arm64ec); REQUIRE(Platform("windows-arm64ec") == Platform::Windows_arm64ec); }