summaryrefslogtreecommitdiff
path: root/neozip/cmake
diff options
context:
space:
mode:
Diffstat (limited to 'neozip/cmake')
-rw-r--r--neozip/cmake/detect-arch.c17
-rw-r--r--neozip/cmake/detect-arch.cmake173
-rw-r--r--neozip/cmake/detect-coverage.cmake50
-rw-r--r--neozip/cmake/detect-install-dirs.cmake43
-rw-r--r--neozip/cmake/detect-intrinsics.cmake770
-rw-r--r--neozip/cmake/detect-sanitizer.cmake164
-rw-r--r--neozip/cmake/fallback-macros.cmake29
-rw-r--r--neozip/cmake/toolchain-aarch64.cmake24
-rw-r--r--neozip/cmake/toolchain-arm.cmake29
-rw-r--r--neozip/cmake/toolchain-armhf.cmake25
-rw-r--r--neozip/cmake/toolchain-e2k-lcc.cmake44
-rw-r--r--neozip/cmake/toolchain-llvm-mingw-aarch64.cmake41
-rw-r--r--neozip/cmake/toolchain-llvm-mingw-armv7.cmake41
-rw-r--r--neozip/cmake/toolchain-llvm-mingw-i686.cmake41
-rw-r--r--neozip/cmake/toolchain-llvm-mingw-x86_64.cmake41
-rw-r--r--neozip/cmake/toolchain-loongarch64-gcc.cmake28
-rw-r--r--neozip/cmake/toolchain-mingw-i686.cmake35
-rw-r--r--neozip/cmake/toolchain-mingw-x86_64.cmake34
-rw-r--r--neozip/cmake/toolchain-mips.cmake29
-rw-r--r--neozip/cmake/toolchain-mips64.cmake29
-rw-r--r--neozip/cmake/toolchain-powerpc.cmake25
-rw-r--r--neozip/cmake/toolchain-powerpc64-clang.cmake16
-rw-r--r--neozip/cmake/toolchain-powerpc64-power9.cmake25
-rw-r--r--neozip/cmake/toolchain-powerpc64.cmake25
-rw-r--r--neozip/cmake/toolchain-powerpc64le-clang.cmake16
-rw-r--r--neozip/cmake/toolchain-powerpc64le-power9.cmake25
-rw-r--r--neozip/cmake/toolchain-powerpc64le.cmake25
-rw-r--r--neozip/cmake/toolchain-riscv-clang.cmake16
-rw-r--r--neozip/cmake/toolchain-riscv.cmake25
-rw-r--r--neozip/cmake/toolchain-s390x.cmake25
-rw-r--r--neozip/cmake/toolchain-sparc64.cmake25
31 files changed, 1935 insertions, 0 deletions
diff --git a/neozip/cmake/detect-arch.c b/neozip/cmake/detect-arch.c
new file mode 100644
index 0000000000..8e9310d0c2
--- /dev/null
+++ b/neozip/cmake/detect-arch.c
@@ -0,0 +1,17 @@
+/* detect-arch.c -- Detect compiler architecture and print to stderr
+ * containing a simple arch identifier.
+ * Copyright (C) 2019 Hans Kristian Rosbach
+ * Licensed under the Zlib license, see LICENSE.md for details
+ */
+
+#include <stdio.h>
+
+#include "../zarch.h"
+
+int main(void) {
+ fprintf(stderr, "archfound " ARCH_NAME "\n");
+#ifdef ARCH_VERSION_STR
+ fprintf(stderr, "archversion " ARCH_VERSION_STR "\n");
+#endif
+ return 0;
+}
diff --git a/neozip/cmake/detect-arch.cmake b/neozip/cmake/detect-arch.cmake
new file mode 100644
index 0000000000..991fe18296
--- /dev/null
+++ b/neozip/cmake/detect-arch.cmake
@@ -0,0 +1,173 @@
+# detect-arch.cmake -- Detect compiler architecture and set ARCH and BASEARCH
+# Copyright (C) 2019 Hans Kristian Rosbach
+# Licensed under the Zlib license, see LICENSE.md for details
+if(CMAKE_OSX_ARCHITECTURES)
+ # If multiple architectures are requested (universal build), pick only the first
+ list(GET CMAKE_OSX_ARCHITECTURES 0 ARCH)
+elseif(MSVC)
+ set(ARCH ${MSVC_C_ARCHITECTURE_ID})
+elseif(EMSCRIPTEN)
+ set(ARCH "wasm32")
+endif()
+
+if(NOT ARCH OR ARCH STREQUAL "")
+ # Compile detect-arch.c and read the architecture name from the binary
+ try_compile(
+ COMPILE_RESULT
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_LIST_DIR}/detect-arch.c
+ CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
+ COPY_FILE ${CMAKE_CURRENT_BINARY_DIR}/detect-arch.bin
+ )
+ if(COMPILE_RESULT)
+ # Find archfound tag, and extract the arch word into ARCH variable
+ file(STRINGS ${CMAKE_CURRENT_BINARY_DIR}/detect-arch.bin RAWOUTPUT REGEX "archfound [a-zA-Z0-9_]+")
+ string(REGEX REPLACE ".*archfound ([a-zA-Z0-9_]+).*" "\\1" ARCH "${RAWOUTPUT}")
+
+ # Find archversion tag, and extract the archversion word into ARCHVERSION variable
+ file(STRINGS ${CMAKE_CURRENT_BINARY_DIR}/detect-arch.bin RAWOUTPUT REGEX "archversion [0-9]+")
+ string(REGEX REPLACE ".*archversion ([0-9]+).*" "\\1" ARCHVERSION "${RAWOUTPUT}")
+ endif()
+
+ if(NOT ARCH)
+ set(ARCH unknown)
+ endif()
+ if(NOT ARCHVERSION)
+ set(ARCHVERSION 0)
+ endif()
+endif()
+
+# Make sure we have ARCH set
+if(NOT ARCH OR ARCH STREQUAL "unknown")
+ set(ARCH ${CMAKE_SYSTEM_PROCESSOR})
+ message(STATUS "Arch not recognized, falling back to cmake arch: '${ARCH}'")
+else()
+ message(STATUS "Arch detected: '${ARCH}'")
+endif()
+
+# Convert ARCH to lowercase
+string(TOLOWER "${ARCH}" ARCH)
+
+# Base arch detection
+if("${ARCH}" MATCHES "(x86(_32|_64)?|amd64|x64|i[3-6]86)")
+ set(BASEARCH "x86")
+ set(BASEARCH_X86_FOUND TRUE)
+ if("${ARCH}" MATCHES "(x86_64|amd64|x64)")
+ set(ARCH_BITS 64)
+ else()
+ set(ARCH_BITS 32)
+ endif()
+elseif("${ARCH}" MATCHES "(aarch64|arm64(ec)?|aarch32|arm(v[0-9])?|cortex)")
+ set(BASEARCH "arm")
+ set(BASEARCH_ARM_FOUND TRUE)
+ if("${ARCH}" MATCHES "(aarch64|arm64(ec)?)")
+ set(ARCH_BITS 64)
+ else()
+ set(ARCH_BITS 32)
+ endif()
+elseif("${ARCH}" MATCHES "(ppc|powerpc)(64)?(le)?")
+ set(BASEARCH "ppc")
+ set(BASEARCH_PPC_FOUND TRUE)
+ if("${ARCH}" MATCHES "(ppc|powerpc)64(le)?")
+ set(ARCH_BITS 64)
+ else()
+ set(ARCH_BITS 32)
+ endif()
+elseif("${ARCH}" MATCHES "alpha")
+ set(BASEARCH "alpha")
+ set(BASEARCH_ALPHA_FOUND TRUE)
+ set(ARCH_BITS 64)
+elseif("${ARCH}" MATCHES "blackfin")
+ set(BASEARCH "blackfin")
+ set(BASEARCH_BLACKFIN_FOUND TRUE)
+ set(ARCH_BITS 32)
+elseif("${ARCH}" MATCHES "ia64")
+ set(BASEARCH "ia64")
+ set(BASEARCH_IA64_FOUND TRUE)
+ set(ARCH_BITS 64)
+elseif("${ARCH}" MATCHES "mips(isa)?(64)?")
+ set(BASEARCH "mips")
+ set(BASEARCH_MIPS_FOUND TRUE)
+ if("${ARCH}" MATCHES "mips(isa)?64")
+ set(ARCH_BITS 64)
+ else()
+ set(ARCH_BITS 32)
+ endif()
+elseif("${ARCH}" MATCHES "m68k")
+ set(BASEARCH "m68k")
+ set(BASEARCH_M68K_FOUND TRUE)
+ set(ARCH_BITS 32)
+elseif("${ARCH}" MATCHES "sh")
+ set(BASEARCH "sh")
+ set(BASEARCH_SH_FOUND TRUE)
+ set(ARCH_BITS 32)
+elseif("${ARCH}" MATCHES "sparc(v)?[89]?(64)?")
+ set(BASEARCH "sparc")
+ set(BASEARCH_SPARC_FOUND TRUE)
+ if("${ARCH}" MATCHES "(sparc64|sparc(v)?9)")
+ set(ARCH_BITS 64)
+ else()
+ set(ARCH_BITS 32)
+ endif()
+elseif("${ARCH}" MATCHES "s3[679]0x?")
+ set(BASEARCH "s360")
+ set(BASEARCH_S360_FOUND TRUE)
+ if("${ARCH}" MATCHES "s3[679]0x")
+ set(ARCH_BITS 64)
+ else()
+ set(ARCH_BITS 32)
+ endif()
+elseif("${ARCH}" MATCHES "(parisc|hppa)(64)?")
+ set(BASEARCH "parisc")
+ set(BASEARCH_PARISC_FOUND TRUE)
+ if("${ARCH}" MATCHES "(parisc|hppa)64")
+ set(ARCH_BITS 64)
+ else()
+ set(ARCH_BITS 32)
+ endif()
+elseif("${ARCH}" MATCHES "rs6000")
+ set(BASEARCH "rs6000")
+ set(BASEARCH_RS6000_FOUND TRUE)
+ set(ARCH_BITS 32)
+elseif("${ARCH}" MATCHES "riscv(32|64)")
+ set(BASEARCH "riscv")
+ set(BASEARCH_RISCV_FOUND TRUE)
+ if("${ARCH}" MATCHES "riscv64")
+ set(ARCH_BITS 64)
+ else()
+ set(ARCH_BITS 32)
+ endif()
+elseif("${ARCH}" MATCHES "(loong64|loongarch64)")
+ set(BASEARCH "loongarch")
+ set(BASEARCH_LOONGARCH_FOUND TRUE)
+ set(ARCH_BITS 64)
+elseif("${ARCH}" MATCHES "wasm(32|64)")
+ set(BASEARCH "wasm32")
+ set(BASEARCH_WASM32_FOUND TRUE)
+ if("${ARCH}" MATCHES "wasm64")
+ set(ARCH_BITS 64)
+ else()
+ set(ARCH_BITS 32)
+ endif()
+elseif("${ARCH}" MATCHES "e2k")
+ set(BASEARCH "e2k")
+ set(BASEARCH_E2K_FOUND TRUE)
+ set(ARCH_BITS 64)
+
+ message(STATUS "Arch version ${BASEARCH}v${ARCHVERSION}.")
+else()
+ set(BASEARCH "x86")
+ set(BASEARCH_X86_FOUND TRUE)
+ set(ARCH_BITS 32)
+ message(STATUS "Basearch '${ARCH}' not recognized, defaulting to 'x86'.")
+endif()
+
+if (ARCH_BITS EQUAL 64)
+ set(ARCH_64BIT TRUE)
+ set(ARCH_32BIT FALSE)
+else()
+ set(ARCH_64BIT FALSE)
+ set(ARCH_32BIT TRUE)
+endif()
+
+message(STATUS "Basearch of '${ARCH}' (${ARCH_BITS}bit) has been detected as: '${BASEARCH}'")
diff --git a/neozip/cmake/detect-coverage.cmake b/neozip/cmake/detect-coverage.cmake
new file mode 100644
index 0000000000..ff993cf9ff
--- /dev/null
+++ b/neozip/cmake/detect-coverage.cmake
@@ -0,0 +1,50 @@
+# detect-coverage.cmake -- Detect supported compiler coverage flags
+# Licensed under the Zlib license, see LICENSE.md for details
+
+# Attempt to enable gcov-style code coverage
+macro(add_code_coverage)
+ # Check for --coverage flag support
+ set(CMAKE_REQUIRED_LINK_OPTIONS -coverage)
+ check_c_compiler_flag("--coverage" HAVE_COVERAGE)
+ set(CMAKE_REQUIRED_LINK_OPTIONS)
+ if(HAVE_COVERAGE)
+ # Check for --coverage -fcondition-coverage flag support
+ set(CMAKE_REQUIRED_LINK_OPTIONS -coverage -fcondition-coverage)
+ check_c_compiler_flag("--coverage -fcondition-coverage -Wno-coverage-too-many-conditions" HAVE_CONDITION_COVERAGE)
+ set(CMAKE_REQUIRED_LINK_OPTIONS)
+
+ if(HAVE_CONDITION_COVERAGE)
+ # Both --coverage and -fcondition-coverage supported
+ add_link_options(-coverage -fcondition-coverage)
+ add_compile_options(--coverage -fcondition-coverage -Wno-coverage-too-many-conditions)
+ message(STATUS "Code coverage enabled using: --coverage -fcondition-coverage")
+ else()
+ # Only --coverage supported.
+ add_link_options(-coverage)
+ add_compile_options(--coverage)
+ message(STATUS "Code coverage enabled using: --coverage")
+ endif()
+ else()
+ # Some versions of GCC don't support --coverage shorthand
+ set(CMAKE_REQUIRED_LINK_OPTIONS -lgcov -fprofile-arcs)
+ check_c_compiler_flag("-ftest-coverage -fprofile-arcs" HAVE_TEST_COVERAGE)
+ set(CMAKE_REQUIRED_LINK_OPTIONS)
+
+ if(HAVE_TEST_COVERAGE)
+ add_link_options(-lgcov -fprofile-arcs)
+ add_compile_options(-ftest-coverage -fprofile-arcs)
+ message(STATUS "Code coverage enabled using: -ftest-coverage -fprofile-arcs")
+ else()
+ # Failed to enable coverage, this is fatal to avoid silent failures in CI
+ message(FATAL_ERROR "WITH_CODE_COVERAGE requested, but unable to turn on code coverage with compiler/linker")
+ set(WITH_CODE_COVERAGE OFF)
+ endif()
+ endif()
+
+ # Set optimization level to zero for code coverage builds
+ if (WITH_CODE_COVERAGE)
+ # Use CMake compiler flag variables due to add_compile_options failure on Windows GCC
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0")
+ endif()
+endmacro()
diff --git a/neozip/cmake/detect-install-dirs.cmake b/neozip/cmake/detect-install-dirs.cmake
new file mode 100644
index 0000000000..a7c774f474
--- /dev/null
+++ b/neozip/cmake/detect-install-dirs.cmake
@@ -0,0 +1,43 @@
+# detect-install-dirs.cmake -- Detect install directory parameters
+# Copyright (C) 2021 Hans Kristian Rosbach
+# Licensed under the Zlib license, see LICENSE.md for details
+
+# Determine installation directory for executables
+if (DEFINED BIN_INSTALL_DIR)
+ set(BIN_INSTALL_DIR "${BIN_INSTALL_DIR}" CACHE PATH "Installation directory for executables (Deprecated)" FORCE)
+ set(CMAKE_INSTALL_BINDIR "${BIN_INSTALL_DIR}")
+elseif (DEFINED INSTALL_BIN_DIR)
+ set(CMAKE_INSTALL_BINDIR "${INSTALL_BIN_DIR}")
+endif()
+
+# Determine installation directory for libraries
+if (DEFINED LIB_INSTALL_DIR)
+ set(LIB_INSTALL_DIR "${LIB_INSTALL_DIR}" CACHE PATH "Installation directory for libraries (Deprecated)" FORCE)
+ set(CMAKE_INSTALL_LIBDIR "${LIB_INSTALL_DIR}")
+elseif (DEFINED INSTALL_LIB_DIR)
+ set(CMAKE_INSTALL_LIBDIR "${INSTALL_LIB_DIR}")
+endif()
+
+# Determine installation directory for include files
+if (DEFINED INC_INSTALL_DIR)
+ set(INC_INSTALL_DIR "${INC_INSTALL_DIR}" CACHE PATH "Installation directory for headers (Deprecated)" FORCE)
+ set(CMAKE_INSTALL_INCLUDEDIR "${INC_INSTALL_DIR}")
+elseif (DEFINED INSTALL_INC_DIR)
+ set(CMAKE_INSTALL_INCLUDEDIR "${INSTALL_INC_DIR}")
+endif()
+
+# Define GNU standard installation directories
+include(GNUInstallDirs)
+
+# Determine installation directory for pkgconfig files
+if (DEFINED PKGCONFIG_INSTALL_DIR)
+ set(PKGCONFIG_INSTALL_DIR "${PKGCONFIG_INSTALL_DIR}" CACHE PATH "Installation directory for pkgconfig (.pc) files" FORCE)
+elseif (DEFINED INSTALL_PKGCONFIG_DIR)
+ set(PKGCONFIG_INSTALL_DIR "${INSTALL_PKGCONFIG_DIR}" CACHE PATH "Installation directory for pkgconfig (.pc) files" FORCE)
+elseif (DEFINED CMAKE_INSTALL_PKGCONFIGDIR)
+ set(PKGCONFIG_INSTALL_DIR "${CMAKE_INSTALL_PKGCONFIGDIR}" CACHE PATH "Installation directory for pkgconfig (.pc) files" FORCE)
+elseif (DEFINED CMAKE_INSTALL_FULL_PKGCONFIGDIR)
+ set(PKGCONFIG_INSTALL_DIR "${CMAKE_INSTALL_FULL_PKGCONFIGDIR}" CACHE PATH "Installation directory for pkgconfig (.pc) files" FORCE)
+else()
+ set(PKGCONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files")
+endif()
diff --git a/neozip/cmake/detect-intrinsics.cmake b/neozip/cmake/detect-intrinsics.cmake
new file mode 100644
index 0000000000..c524c17bbe
--- /dev/null
+++ b/neozip/cmake/detect-intrinsics.cmake
@@ -0,0 +1,770 @@
+# detect-intrinsics.cmake -- Detect compiler intrinsics support
+# Licensed under the Zlib license, see LICENSE.md for details
+
+macro(check_armv8_compiler_flag)
+ if(NOT NATIVEFLAG)
+ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+ check_c_compiler_flag("-march=armv8-a+crc" HAVE_MARCH_ARMV8_CRC)
+ if(HAVE_MARCH_ARMV8_CRC)
+ set(ARMV8FLAG "-march=armv8-a+crc" CACHE INTERNAL "Compiler option to enable ARMv8 support")
+ else()
+ check_c_compiler_flag("-march=armv8-a+crc+simd" HAVE_MARCH_ARMV8_CRC_SIMD)
+ if(HAVE_MARCH_ARMV8_CRC_SIMD)
+ set(ARMV8FLAG "-march=armv8-a+crc+simd" CACHE INTERNAL "Compiler option to enable ARMv8 support")
+ else()
+ check_c_compiler_flag("-Wa,-march=armv8-a+crc" HAVE_WA_MARCH_ARMV8_CRC)
+ if(HAVE_WA_MARCH_ARMV8_CRC)
+ set(ARMV8FLAG "-Wa,-march=armv8-a+crc" CACHE INTERNAL "Compiler option to enable ARMv8 support")
+ else()
+ check_c_compiler_flag("-Wa,-march=armv8-a+crc+simd" HAVE_WA_MARCH_ARMV8_CRC_SIMD)
+ if(HAVE_WA_MARCH_ARMV8_CRC_SIMD)
+ set(ARMV8FLAG "-Wa,-march=armv8-a+crc+simd" CACHE INTERNAL "Compiler option to enable ARMv8 support")
+ endif()
+ endif()
+ endif()
+ endif()
+ endif()
+ endif()
+ # Check whether compiler supports ARMv8 inline asm
+ set(CMAKE_REQUIRED_FLAGS "${ARMV8FLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "unsigned int f(unsigned int a, unsigned int b) {
+ unsigned int c;
+ #ifdef __aarch64__
+ __asm__( \"crc32w %w0, %w1, %w2\" : \"=r\" (c) : \"r\" (a), \"r\" (b));
+ #else
+ __asm__( \"crc32w %0, %1, %2\" : \"=r\" (c) : \"r\" (a), \"r\" (b));
+ #endif
+ return (int)c;
+ }
+ int main(void) { return f(1,2); }"
+ HAVE_ARMV8_INLINE_ASM
+ )
+ # Check whether compiler supports ARMv8 intrinsics
+ check_c_source_compiles(
+ "#if defined(_MSC_VER)
+ #include <intrin.h>
+ #else
+ #include <arm_acle.h>
+ #endif
+ unsigned int f(unsigned int a, unsigned int b) {
+ return __crc32w(a, b);
+ }
+ int main(void) { return 0; }"
+ HAVE_ARMV8_INTRIN
+ )
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_armv8_pmull_eor3_compiler_flag)
+ if(NOT NATIVEFLAG)
+ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+ check_c_compiler_flag("-march=armv8.2-a+crc+crypto+sha3" HAVE_MARCH_ARMV8_CRYPTO_SHA3)
+ if(HAVE_MARCH_ARMV8_CRYPTO_SHA3)
+ set(PMULLEOR3FLAG "-march=armv8.2-a+crc+crypto+sha3" CACHE INTERNAL "Compiler option to enable ARMv8 PMULL+EOR3 support")
+ else()
+ check_c_compiler_flag("-march=armv8-a+crc+crypto+sha3" HAVE_MARCH_ARMV8A_CRYPTO_SHA3)
+ if(HAVE_MARCH_ARMV8A_CRYPTO_SHA3)
+ set(PMULLEOR3FLAG "-march=armv8-a+crc+crypto+sha3" CACHE INTERNAL "Compiler option to enable ARMv8 PMULL+EOR3 support")
+ endif()
+ endif()
+ endif()
+ endif()
+ # Check whether compiler supports ARMv8 PMULL + EOR3 intrinsics
+ set(CMAKE_REQUIRED_FLAGS "${PMULLEOR3FLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#if defined(_MSC_VER) && (defined(_M_ARM64) || defined(_M_ARM64EC))
+ # include <arm64_neon.h>
+ #else
+ # include <arm_neon.h>
+ #endif
+ #ifdef _MSC_VER
+ __n128 f(__n64 a, __n64 b) {
+ #else
+ poly128_t f(poly64_t a, poly64_t b) {
+ #endif
+ return vmull_p64(a, b);
+ }
+ uint64x2_t g(uint64x2_t a, uint64x2_t b, uint64x2_t c) {
+ return veor3q_u64(a, b, c);
+ }
+ int main(void) { return 0; }"
+ HAVE_ARMV8_PMULL_EOR3_INTRIN
+ )
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_armv6_compiler_flag)
+ if(NOT NATIVEFLAG)
+ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+ check_c_compiler_flag("-march=armv6" HAVE_MARCH_ARMV6)
+ if(HAVE_MARCH_ARMV6)
+ set(ARMV6FLAG "-march=armv6" CACHE INTERNAL "Compiler option to enable ARMv6 support")
+ else()
+ check_c_compiler_flag("-Wa,-march=armv6" HAVE_WA_MARCH_ARMV6)
+ if(HAVE_WA_MARCH_ARMV6)
+ set(ARMV6FLAG "-Wa,-march=armv6" CACHE INTERNAL "Compiler option to enable ARMv6 support")
+ endif()
+ endif()
+ endif()
+ endif()
+ # Check whether compiler supports ARMv6 inline asm
+ set(CMAKE_REQUIRED_FLAGS "${ARMV6FLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "unsigned int f(unsigned int a, unsigned int b) {
+ unsigned int c;
+ __asm__( \"uqsub16 %0, %1, %2\" : \"=r\" (c) : \"r\" (a), \"r\" (b) );
+ return (int)c;
+ }
+ int main(void) { return f(1,2); }"
+ HAVE_ARMV6_INLINE_ASM
+ )
+ # Check whether compiler supports ARMv6 intrinsics
+ check_c_source_compiles(
+ "#if defined(_MSC_VER)
+ #include <intrin.h>
+ #else
+ #include <arm_acle.h>
+ #endif
+ unsigned int f(unsigned int a, unsigned int b) {
+ #if defined(_MSC_VER)
+ return _arm_uqsub16(a, b);
+ #else
+ return __uqsub16(a, b);
+ #endif
+ }
+ int main(void) { return f(1,2); }"
+ HAVE_ARMV6_INTRIN
+ )
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_avx512_intrinsics)
+ if(NOT NATIVEFLAG)
+ if(CMAKE_C_COMPILER_ID MATCHES "Intel")
+ if(CMAKE_HOST_UNIX OR APPLE)
+ set(AVX512FLAG "-mavx512f -mavx512dq -mavx512bw -mavx512vl -mbmi2")
+ else()
+ set(AVX512FLAG "/arch:AVX512")
+ endif()
+ elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "NVHPC")
+ # For CPUs that can benefit from AVX512, it seems GCC generates suboptimal
+ # instruction scheduling unless you specify a reasonable -mtune= target
+ set(AVX512FLAG "-mavx512f -mavx512dq -mavx512bw -mavx512vl -mbmi2")
+ if(NOT MSVC)
+ check_c_compiler_flag("-mtune=cascadelake" HAVE_CASCADE_LAKE)
+ if(HAVE_CASCADE_LAKE)
+ set(AVX512FLAG "${AVX512FLAG} -mtune=cascadelake")
+ else()
+ set(AVX512FLAG "${AVX512FLAG} -mtune=skylake-avx512")
+ endif()
+ unset(HAVE_CASCADE_LAKE)
+ endif()
+ elseif(MSVC)
+ set(AVX512FLAG "/arch:AVX512")
+ endif()
+ endif()
+ # Check whether compiler supports AVX512 intrinsics
+ set(CMAKE_REQUIRED_FLAGS "${AVX512FLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <immintrin.h>
+ __m512i f(__m512i y) {
+ __m512i x = _mm512_set1_epi8(2);
+ return _mm512_sub_epi8(x, y);
+ }
+ int main(void) { return 0; }"
+ HAVE_AVX512_INTRIN
+ )
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_avx512vnni_intrinsics)
+ if(NOT NATIVEFLAG)
+ if(CMAKE_C_COMPILER_ID MATCHES "Intel")
+ if(CMAKE_HOST_UNIX OR APPLE OR CMAKE_C_COMPILER_ID MATCHES "IntelLLVM")
+ set(AVX512VNNIFLAG "-mavx512f -mavx512dq -mavx512bw -mavx512vl -mavx512vnni -mbmi2")
+ else()
+ set(AVX512VNNIFLAG "/arch:AVX512")
+ endif()
+ elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "NVHPC")
+ set(AVX512VNNIFLAG "-mavx512f -mavx512dq -mavx512bw -mavx512vl -mavx512vnni -mbmi2")
+ if(NOT MSVC)
+ check_c_compiler_flag("-mtune=cascadelake" HAVE_CASCADE_LAKE)
+ if(HAVE_CASCADE_LAKE)
+ set(AVX512VNNIFLAG "${AVX512VNNIFLAG} -mtune=cascadelake")
+ else()
+ set(AVX512VNNIFLAG "${AVX512VNNIFLAG} -mtune=skylake-avx512")
+ endif()
+ unset(HAVE_CASCADE_LAKE)
+ endif()
+ elseif(MSVC)
+ set(AVX512VNNIFLAG "/arch:AVX512")
+ endif()
+ endif()
+ # Check whether compiler supports AVX512vnni intrinsics
+ set(CMAKE_REQUIRED_FLAGS "${AVX512VNNIFLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <immintrin.h>
+ int main(void) {
+ const __m512i z512 = _mm512_setzero_si512();
+ const __m256i z256 = _mm256_setzero_si256();
+ volatile __m512i r512 = _mm512_dpbusd_epi32(z512, z512, z512);
+ volatile __m256i r256 = _mm256_dpbusd_epi32(z256, z256, z256);
+ (void)r512;
+ (void)r256;
+ return 0;
+ }"
+ HAVE_AVX512VNNI_INTRIN
+ )
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_avx2_intrinsics)
+ if(NOT NATIVEFLAG)
+ if(CMAKE_C_COMPILER_ID MATCHES "Intel")
+ if(CMAKE_HOST_UNIX OR APPLE)
+ set(AVX2FLAG "-mavx2 -mbmi2")
+ else()
+ set(AVX2FLAG "/arch:AVX2")
+ endif()
+ elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "NVHPC")
+ set(AVX2FLAG "-mavx2 -mbmi2")
+ elseif(MSVC)
+ set(AVX2FLAG "/arch:AVX2")
+ endif()
+ endif()
+ # Check whether compiler supports AVX2 intrinics
+ set(CMAKE_REQUIRED_FLAGS "${AVX2FLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <immintrin.h>
+ __m256i f(__m256i x) {
+ const __m256i y = _mm256_set1_epi16(1);
+ return _mm256_subs_epu16(x, y);
+ }
+ int main(void) { return 0; }"
+ HAVE_AVX2_INTRIN
+ )
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_neon_compiler_flag)
+ if(NOT NATIVEFLAG)
+ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+ if(ARCH_64BIT)
+ set(NEONFLAG "-march=armv8-a+simd")
+ else()
+ set(NEONFLAG "-mfpu=neon")
+ endif()
+ endif()
+ endif()
+ # Check whether compiler supports NEON flag
+ set(CMAKE_REQUIRED_FLAGS "${NEONFLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#if defined(_M_ARM64) || defined(_M_ARM64EC)
+ # include <arm64_neon.h>
+ #else
+ # include <arm_neon.h>
+ #endif
+ int main() { return 0; }"
+ NEON_AVAILABLE FAIL_REGEX "not supported")
+ # Check whether compiler native flag is enough for NEON support
+ # Some GCC versions don't enable FPU (vector unit) when using -march=native
+ if(NEON_AVAILABLE AND NATIVEFLAG AND ARCH_32BIT)
+ check_c_source_compiles(
+ "#include <arm_neon.h>
+ uint8x16_t f(uint8x16_t x, uint8x16_t y) {
+ return vaddq_u8(x, y);
+ }
+ int main(int argc, char* argv[]) {
+ uint8x16_t a = vdupq_n_u8(argc);
+ uint8x16_t b = vdupq_n_u8(argc);
+ uint8x16_t result = f(a, b);
+ return result[0];
+ }"
+ ARM_NEON_SUPPORT_NATIVE
+ )
+ if(NOT ARM_NEON_SUPPORT_NATIVE)
+ set(CMAKE_REQUIRED_FLAGS "${NATIVEFLAG} -mfpu=neon ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <arm_neon.h>
+ uint8x16_t f(uint8x16_t x, uint8x16_t y) {
+ return vaddq_u8(x, y);
+ }
+ int main(int argc, char* argv[]) {
+ uint8x16_t a = vdupq_n_u8(argc);
+ uint8x16_t b = vdupq_n_u8(argc);
+ uint8x16_t result = f(a, b);
+ return result[0];
+ }"
+ ARM_NEON_SUPPORT_NATIVE_MFPU
+ )
+ if(ARM_NEON_SUPPORT_NATIVE_MFPU)
+ set(NEONFLAG "-mfpu=neon")
+ else()
+ # Remove local NEON_AVAILABLE variable and overwrite the cache
+ unset(NEON_AVAILABLE)
+ set(NEON_AVAILABLE "" CACHE INTERNAL "NEON support available" FORCE)
+ endif()
+ endif()
+ endif()
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_neon_ld4_intrinsics)
+ if(NOT NATIVEFLAG)
+ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+ if(ARCH_64BIT)
+ set(NEONFLAG "-march=armv8-a+simd")
+ else()
+ set(NEONFLAG "-mfpu=neon")
+ endif()
+ endif()
+ endif()
+ # Check whether compiler supports loading 4 neon vecs into a register range
+ set(CMAKE_REQUIRED_FLAGS "${NEONFLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#if defined(_MSC_VER) && (defined(_M_ARM64) || defined(_M_ARM64EC))
+ # include <arm64_neon.h>
+ #else
+ # include <arm_neon.h>
+ #endif
+ int32x4x4_t f(int var[16]) { return vld1q_s32_x4(var); }
+ int main(void) { return 0; }"
+ NEON_HAS_LD4)
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_pclmulqdq_intrinsics)
+ if(NOT NATIVEFLAG)
+ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "IntelLLVM" OR CMAKE_C_COMPILER_ID MATCHES "NVHPC")
+ set(PCLMULFLAG "-mpclmul")
+ endif()
+ endif()
+ # Check whether compiler supports PCLMULQDQ intrinsics
+ if(NOT (APPLE AND ARCH_32BIT))
+ # The pclmul code currently crashes on Mac in 32bit mode. Avoid for now.
+ set(CMAKE_REQUIRED_FLAGS "${PCLMULFLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <immintrin.h>
+ #include <wmmintrin.h>
+ __m128i f(__m128i a, __m128i b) { return _mm_clmulepi64_si128(a, b, 0x10); }
+ int main(void) { return 0; }"
+ HAVE_PCLMULQDQ_INTRIN
+ )
+ set(CMAKE_REQUIRED_FLAGS)
+ else()
+ set(HAVE_PCLMULQDQ_INTRIN OFF)
+ endif()
+endmacro()
+
+macro(check_vpclmulqdq_intrinsics)
+ if(NOT NATIVEFLAG)
+ if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|IntelLLVM|NVHPC")
+ set(VPCLMULFLAG "-mvpclmulqdq")
+ endif()
+ endif()
+ # Check whether compiler supports VPCLMULQDQ intrinsics
+ if(NOT (APPLE AND ARCH_32BIT))
+ set(CMAKE_REQUIRED_FLAGS "${VPCLMULFLAG} ${AVX2FLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <immintrin.h>
+ #include <wmmintrin.h>
+ __m256i f(__m256i a) {
+ __m256i b = _mm256_setzero_si256();
+ return _mm256_clmulepi64_epi128(a, b, 0x10);
+ }
+ int main(void) { return 0; }"
+ HAVE_VPCLMULQDQ_INTRIN
+ )
+ set(CMAKE_REQUIRED_FLAGS)
+ else()
+ set(HAVE_VPCLMULQDQ_INTRIN OFF)
+ endif()
+endmacro()
+
+macro(check_ppc_intrinsics)
+ # Check if compiler supports AltiVec
+ set(CMAKE_REQUIRED_FLAGS "-maltivec ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <altivec.h>
+ int main(void)
+ {
+ vector int a = vec_splats(0);
+ vector int b = vec_splats(0);
+ a = vec_add(a, b);
+ return 0;
+ }"
+ HAVE_ALTIVEC
+ )
+ set(CMAKE_REQUIRED_FLAGS)
+
+ if(HAVE_ALTIVEC)
+ set(PPCFLAGS "-maltivec")
+ endif()
+
+ set(CMAKE_REQUIRED_FLAGS "-maltivec -mno-vsx ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <altivec.h>
+ int main(void)
+ {
+ vector int a = vec_splats(0);
+ vector int b = vec_splats(0);
+ a = vec_add(a, b);
+ return 0;
+ }"
+ HAVE_NOVSX
+ )
+ set(CMAKE_REQUIRED_FLAGS)
+
+ if(HAVE_NOVSX)
+ set(PPCFLAGS "${PPCFLAGS} -mno-vsx")
+ endif()
+
+ # Check if we have what we need for AltiVec optimizations
+ set(CMAKE_REQUIRED_FLAGS "${PPCFLAGS} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <sys/auxv.h>
+ #ifdef __FreeBSD__
+ #include <machine/cpu.h>
+ #endif
+ int main() {
+ #if defined(__FreeBSD__) || defined(__OpenBSD__)
+ unsigned long hwcap;
+ elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap));
+ return (hwcap & PPC_FEATURE_HAS_ALTIVEC);
+ #else
+ return (getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC);
+ #endif
+ }"
+ HAVE_VMX
+ )
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_power8_intrinsics)
+ if(NOT NATIVEFLAG)
+ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+ set(POWER8FLAG "-mcpu=power8")
+ endif()
+ endif()
+ # Check if we have what we need for POWER8 optimizations
+ set(CMAKE_REQUIRED_FLAGS "${POWER8FLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <sys/auxv.h>
+ #ifdef __FreeBSD__
+ #include <machine/cpu.h>
+ #endif
+ int main() {
+ #if defined(__FreeBSD__) || defined(__OpenBSD__)
+ unsigned long hwcap;
+ elf_aux_info(AT_HWCAP2, &hwcap, sizeof(hwcap));
+ return (hwcap & PPC_FEATURE2_ARCH_2_07);
+ #else
+ return (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07);
+ #endif
+ }"
+ HAVE_POWER8_INTRIN
+ )
+ if(NOT HAVE_POWER8_INTRIN AND HAVE_LINUX_AUXVEC_H)
+ check_c_source_compiles(
+ "#include <sys/auxv.h>
+ #include <linux/auxvec.h>
+ int main() {
+ return (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07);
+ }"
+ HAVE_POWER8_INTRIN2
+ )
+ if(HAVE_POWER8_INTRIN2)
+ set(POWER8_NEED_AUXVEC_H 1)
+ set(HAVE_POWER8_INTRIN ${HAVE_POWER8_INTRIN2} CACHE INTERNAL "Have POWER8 intrinsics" FORCE)
+ unset(HAVE_POWER8_INTRIN2 CACHE)
+ endif()
+ endif()
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_rvv_intrinsics)
+ if(NOT NATIVEFLAG)
+ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+ set(RISCVFLAG "-march=rv64gcv")
+ endif()
+ endif()
+ # Check whether compiler supports RVV
+ set(CMAKE_REQUIRED_FLAGS "${RISCVFLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <riscv_vector.h>
+ int main() {
+ return 0;
+ }"
+ HAVE_RVV_INTRIN
+ )
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_riscv_zbc_ext)
+ if(NOT NATIVEFLAG)
+ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+ set(RISCVZBCFLAG "-march=rv64gc_zbc")
+ endif()
+ endif()
+ # Check whether compiler supports RISC-V Zbc inline asm
+ # gcc-11 / clang-14 at least
+ set(CMAKE_REQUIRED_FLAGS "${RISCVZBCFLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <stdint.h>
+ uint64_t f(uint64_t a, uint64_t b) {
+ uint64_t c;
+ __asm__ __volatile__ (\"clmul %[result], %[input_a], %[input_b]\" : [result] \"=r\" (c) : [input_a] \"r\" (a), [input_b] \"r\" (b));
+ return c;
+ }
+ int main(void) { return f(1, 2); }"
+ HAVE_RISCV_ZBC
+ )
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_s390_intrinsics)
+ check_c_source_compiles(
+ "#include <sys/auxv.h>
+ #ifndef HWCAP_S390_VXRS
+ #define HWCAP_S390_VXRS (1 << 11)
+ #endif
+ int main() {
+ return (getauxval(AT_HWCAP) & HWCAP_S390_VXRS);
+ }"
+ HAVE_S390_INTRIN
+ )
+endmacro()
+
+macro(check_power9_intrinsics)
+ if(NOT NATIVEFLAG)
+ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+ set(POWER9FLAG "-mcpu=power9")
+ endif()
+ endif()
+ # Check if we have what we need for POWER9 optimizations
+ set(CMAKE_REQUIRED_FLAGS "${POWER9FLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <sys/auxv.h>
+ #ifdef __FreeBSD__
+ #include <machine/cpu.h>
+ #endif
+ int main() {
+ #if defined(__FreeBSD__) || defined(__OpenBSD__)
+ unsigned long hwcap;
+ elf_aux_info(AT_HWCAP2, &hwcap, sizeof(hwcap));
+ return (hwcap & PPC_FEATURE2_ARCH_3_00);
+ #else
+ return (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_00);
+ #endif
+ }"
+ HAVE_POWER9_INTRIN
+ )
+ if(NOT HAVE_POWER9_INTRIN AND HAVE_LINUX_AUXVEC_H)
+ check_c_source_compiles(
+ "#include <sys/auxv.h>
+ #include <linux/auxvec.h>
+ int main() {
+ return (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_00);
+ }"
+ HAVE_POWER9_INTRIN2
+ )
+ if(HAVE_POWER9_INTRIN2)
+ set(POWER9_NEED_AUXVEC_H 1)
+ set(HAVE_POWER9_INTRIN ${HAVE_POWER9_INTRIN2} CACHE INTERNAL "Have POWER9 intrinsics" FORCE)
+ unset(HAVE_POWER9_INTRIN2 CACHE)
+ endif()
+ endif()
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_sse2_intrinsics)
+ if(NOT NATIVEFLAG)
+ if(CMAKE_C_COMPILER_ID MATCHES "Intel")
+ if(CMAKE_HOST_UNIX OR APPLE)
+ set(SSE2FLAG "-msse2")
+ else()
+ set(SSE2FLAG "/arch:SSE2")
+ endif()
+ elseif(MSVC)
+ if(ARCH_32BIT)
+ set(SSE2FLAG "/arch:SSE2")
+ endif()
+ elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "NVHPC")
+ set(SSE2FLAG "-msse2")
+ endif()
+ endif()
+ # Check whether compiler supports SSE2 intrinsics
+ set(CMAKE_REQUIRED_FLAGS "${SSE2FLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <immintrin.h>
+ __m128i f(__m128i x, __m128i y) { return _mm_sad_epu8(x, y); }
+ int main(void) { return 0; }"
+ HAVE_SSE2_INTRIN
+ )
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_ssse3_intrinsics)
+ if(NOT NATIVEFLAG)
+ if(CMAKE_C_COMPILER_ID MATCHES "Intel")
+ if(CMAKE_HOST_UNIX OR APPLE)
+ set(SSSE3FLAG "-mssse3")
+ else()
+ set(SSSE3FLAG "/arch:SSSE3")
+ endif()
+ elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "NVHPC")
+ set(SSSE3FLAG "-mssse3")
+ endif()
+ endif()
+ # Check whether compiler supports SSSE3 intrinsics
+ set(CMAKE_REQUIRED_FLAGS "${SSSE3FLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <immintrin.h>
+ __m128i f(__m128i u) {
+ __m128i v = _mm_set1_epi32(1);
+ return _mm_hadd_epi32(u, v);
+ }
+ int main(void) { return 0; }"
+ HAVE_SSSE3_INTRIN
+ )
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_sse41_intrinsics)
+ if(NOT NATIVEFLAG)
+ if(CMAKE_C_COMPILER_ID MATCHES "Intel")
+ if(CMAKE_HOST_UNIX OR APPLE)
+ set(SSE41FLAG "-msse4.1")
+ else()
+ set(SSE41FLAG "/arch:SSE4.1")
+ endif()
+ elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "NVHPC")
+ set(SSE41FLAG "-msse4.1")
+ endif()
+ endif()
+ # Check whether compiler supports SSE4.1 intrinsics
+ set(CMAKE_REQUIRED_FLAGS "${SSE41FLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <smmintrin.h>
+ __m128i f(__m128i a, __m128i b) { return _mm_min_epi32(a, b); }
+ int main(void) { return 0; }"
+ HAVE_SSE41_INTRIN
+ )
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_sse42_intrinsics)
+ if(NOT NATIVEFLAG)
+ if(CMAKE_C_COMPILER_ID MATCHES "Intel")
+ if(CMAKE_HOST_UNIX OR APPLE)
+ set(SSE42FLAG "-msse4.2")
+ else()
+ set(SSE42FLAG "/arch:SSE4.2")
+ endif()
+ elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "NVHPC")
+ set(SSE42FLAG "-msse4.2")
+ endif()
+ endif()
+ # Check whether compiler supports SSE4.2 intrinsics
+ set(CMAKE_REQUIRED_FLAGS "${SSE42FLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <nmmintrin.h>
+ unsigned int f(unsigned int a, unsigned int b) { return _mm_crc32_u32(a, b); }
+ int main(void) { return 0; }"
+ HAVE_SSE42_INTRIN
+ )
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_vgfma_intrinsics)
+ if(NOT NATIVEFLAG)
+ set(VGFMAFLAG "-march=z13")
+ if(CMAKE_C_COMPILER_ID MATCHES "GNU")
+ set(VGFMAFLAG "${VGFMAFLAG} -mzarch")
+ endif()
+ if(CMAKE_C_COMPILER_ID MATCHES "Clang")
+ set(VGFMAFLAG "${VGFMAFLAG} -fzvector")
+ endif()
+ endif()
+ # Check whether compiler supports "VECTOR GALOIS FIELD MULTIPLY SUM AND ACCUMULATE" intrinsic
+ set(CMAKE_REQUIRED_FLAGS "${VGFMAFLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <vecintrin.h>
+ int main(void) {
+ unsigned long long a __attribute__((vector_size(16))) = { 0 };
+ unsigned long long b __attribute__((vector_size(16))) = { 0 };
+ unsigned char c __attribute__((vector_size(16))) = { 0 };
+ c = vec_gfmsum_accum_128(a, b, c);
+ return c[0];
+ }"
+ HAVE_VGFMA_INTRIN FAIL_REGEX "not supported")
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_xsave_intrinsics)
+ if(NOT NATIVEFLAG AND NOT MSVC AND NOT CMAKE_C_COMPILER_ID MATCHES "Intel")
+ set(XSAVEFLAG "-mxsave")
+ endif()
+ set(CMAKE_REQUIRED_FLAGS "${XSAVEFLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#ifdef _MSC_VER
+ # include <intrin.h>
+ #elif __GNUC__ == 8 && __GNUC_MINOR__ > 1
+ # include <xsaveintrin.h>
+ #else
+ # include <immintrin.h>
+ #endif
+ unsigned int f(unsigned int a) { return (int) _xgetbv(a); }
+ int main(void) { return 0; }"
+ HAVE_XSAVE_INTRIN FAIL_REGEX "not supported")
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_la64_crc_intrinsics)
+ # Check whether compiler supports "crc" intrinsic
+ set(CMAKE_REQUIRED_FLAGS "${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <larchintrin.h>
+ int main(void) {
+ char ch = 'a';
+ int crc = __crc_w_b_w(ch, 0);
+ return crc;
+ }"
+ HAVE_LA64_CRC_INTRIN)
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_lsx_intrinsics)
+ if(NOT NATIVEFLAG)
+ set(LSXFLAG "-mlsx")
+ endif()
+ # Check whether compiler supports LSX intrinsics
+ set(CMAKE_REQUIRED_FLAGS "${LSXFLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <lsxintrin.h>
+ __m128i f(__m128i a, __m128i b) {
+ return __lsx_vabsd_b(a, b);
+ }
+ int main(void) { return 0; }"
+ HAVE_LSX_INTRIN
+ )
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
+
+macro(check_lasx_intrinsics)
+ if(NOT NATIVEFLAG)
+ set(LASXFLAG "-mlasx")
+ endif()
+ # Check whether compiler supports LASX intrinsics
+ set(CMAKE_REQUIRED_FLAGS "${LASXFLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}")
+ check_c_source_compiles(
+ "#include <lasxintrin.h>
+ __m256i f(__m256i a, __m256i b) {
+ return __lasx_xvabsd_b(a, b);
+ }
+ int main(void) { return 0; }"
+ HAVE_LASX_INTRIN
+ )
+ set(CMAKE_REQUIRED_FLAGS)
+endmacro()
diff --git a/neozip/cmake/detect-sanitizer.cmake b/neozip/cmake/detect-sanitizer.cmake
new file mode 100644
index 0000000000..c7c33ff38d
--- /dev/null
+++ b/neozip/cmake/detect-sanitizer.cmake
@@ -0,0 +1,164 @@
+# detect-sanitizer.cmake -- Detect supported compiler sanitizer flags
+# Licensed under the Zlib license, see LICENSE.md for details
+
+macro(add_common_sanitizer_flags)
+ if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+ add_compile_options(-g3)
+ endif()
+ check_c_compiler_flag(-fno-omit-frame-pointer HAVE_NO_OMIT_FRAME_POINTER)
+ if(HAVE_NO_OMIT_FRAME_POINTER)
+ add_compile_options(-fno-omit-frame-pointer)
+ add_link_options(-fno-omit-frame-pointer)
+ endif()
+ check_c_compiler_flag(-fno-optimize-sibling-calls HAVE_NO_OPTIMIZE_SIBLING_CALLS)
+ if(HAVE_NO_OPTIMIZE_SIBLING_CALLS)
+ add_compile_options(-fno-optimize-sibling-calls)
+ add_link_options(-fno-optimize-sibling-calls)
+ endif()
+endmacro()
+
+macro(check_sanitizer_support known_checks supported_checks)
+ set(available_checks "")
+
+ # Build list of supported sanitizer flags by incrementally trying compilation with
+ # known sanitizer checks
+
+ foreach(check ${known_checks})
+ if(available_checks STREQUAL "")
+ set(compile_checks "${check}")
+ else()
+ set(compile_checks "${available_checks},${check}")
+ endif()
+
+ set(CMAKE_REQUIRED_FLAGS -fsanitize=${compile_checks})
+
+ check_c_source_compiles("int main() { return 0; }" HAVE_SANITIZER_${check}
+ FAIL_REGEX "not supported|unrecognized command|unknown option")
+
+ set(CMAKE_REQUIRED_FLAGS)
+
+ if(HAVE_SANITIZER_${check})
+ set(available_checks ${compile_checks})
+ endif()
+ endforeach()
+
+ set(${supported_checks} ${available_checks})
+endmacro()
+
+macro(add_address_sanitizer)
+ set(known_checks
+ address
+ pointer-compare
+ pointer-subtract
+ )
+
+ check_sanitizer_support("${known_checks}" supported_checks)
+ if(NOT ${supported_checks} STREQUAL "")
+ message(STATUS "Address sanitizer is enabled: ${supported_checks}")
+ if(NOT MSVC)
+ add_compile_options("-fsanitize=${supported_checks}")
+ add_link_options("-fsanitize=${supported_checks}")
+ else()
+ add_compile_options("/fsanitize=${supported_checks}" "/Zi")
+ # Note that the MSVC linker doesn't use /fsanitizer
+ endif()
+ add_common_sanitizer_flags()
+ else()
+ message(FATAL_ERROR "Address sanitizer is not supported")
+ endif()
+
+ if(CMAKE_CROSSCOMPILING_EMULATOR)
+ # Only check for leak sanitizer if not cross-compiling due to qemu crash
+ message(WARNING "Leak sanitizer is not supported when cross compiling")
+ else()
+ # Leak sanitizer requires address sanitizer
+ check_sanitizer_support("leak" supported_checks)
+ if(NOT ${supported_checks} STREQUAL "")
+ message(STATUS "Leak sanitizer is enabled: ${supported_checks}")
+ add_compile_options(-fsanitize=${supported_checks})
+ add_link_options(-fsanitize=${supported_checks})
+ add_common_sanitizer_flags()
+ else()
+ # The Microsoft C compiler doesn't support Leak detector,
+ # so don't make this an error that disables ASAN completely
+ message(STATUS "Leak sanitizer is not supported")
+ endif()
+ endif()
+endmacro()
+
+macro(add_memory_sanitizer)
+ check_sanitizer_support("memory" supported_checks)
+ if(NOT ${supported_checks} STREQUAL "")
+ message(STATUS "Memory sanitizer is enabled: ${supported_checks}")
+ add_compile_options(-fsanitize=${supported_checks})
+ add_link_options(-fsanitize=${supported_checks})
+ add_common_sanitizer_flags()
+
+ check_c_compiler_flag(-fsanitize-memory-track-origins HAVE_MEMORY_TRACK_ORIGINS)
+ if(HAVE_MEMORY_TRACK_ORIGINS)
+ add_compile_options(-fsanitize-memory-track-origins)
+ add_link_options(-fsanitize-memory-track-origins)
+ endif()
+ else()
+ message(FATAL_ERROR "Memory sanitizer is not supported")
+ endif()
+endmacro()
+
+macro(add_thread_sanitizer)
+ check_sanitizer_support("thread" supported_checks)
+ if(NOT ${supported_checks} STREQUAL "")
+ message(STATUS "Thread sanitizer is enabled: ${supported_checks}")
+ add_compile_options(-fsanitize=${supported_checks})
+ add_link_options(-fsanitize=${supported_checks})
+ add_common_sanitizer_flags()
+ else()
+ message(FATAL_ERROR "Thread sanitizer is not supported")
+ endif()
+endmacro()
+
+macro(add_undefined_sanitizer)
+ set(known_checks
+ alignment
+ array-bounds
+ bool
+ bounds
+ builtin
+ enum
+ float-cast-overflow
+ float-divide-by-zero
+ function
+ integer-divide-by-zero
+ local-bounds
+ null
+ nonnull-attribute
+ pointer-overflow
+ return
+ returns-nonnull-attribute
+ shift
+ shift-base
+ shift-exponent
+ signed-integer-overflow
+ undefined
+ vla-bound
+ vptr
+ )
+
+ # unsigned-integer-overflow and unsigned-shift-base are not enabled, as they are not undefined in C/C++
+
+ # Object size sanitizer has no effect at -O0 and produces compiler warning if enabled
+ if(NOT CMAKE_C_FLAGS MATCHES "-O0")
+ list(APPEND known_checks object-size)
+ endif()
+
+ check_sanitizer_support("${known_checks}" supported_checks)
+
+ if(NOT ${supported_checks} STREQUAL "")
+ message(STATUS "Undefined behavior sanitizer is enabled: ${supported_checks}")
+ add_compile_options(-fsanitize=${supported_checks})
+ add_link_options(-fsanitize=${supported_checks})
+
+ add_common_sanitizer_flags()
+ else()
+ message(FATAL_ERROR "Undefined behavior sanitizer is not supported")
+ endif()
+endmacro() \ No newline at end of file
diff --git a/neozip/cmake/fallback-macros.cmake b/neozip/cmake/fallback-macros.cmake
new file mode 100644
index 0000000000..d2375cdcc7
--- /dev/null
+++ b/neozip/cmake/fallback-macros.cmake
@@ -0,0 +1,29 @@
+# fallback-macros.cmake -- CMake fallback macros
+# Copyright (C) 2026 Vladislav Shchapov
+# Licensed under the Zlib license, see LICENSE.md for details
+
+# Workaround for FetchContent EXCLUDE_FROM_ALL implementation for CMake before 3.28.
+# The EXCLUDE_FROM_ALL argument for FetchContent_Declare added in version 3.28.
+# Before CMake 3.28, FetchContent_MakeAvailable would add dependencies to the ALL target.
+macro(ZNG_FetchContent_MakeAvailable)
+ if(CMAKE_VERSION VERSION_LESS 3.28)
+ foreach(__zng_contentName IN ITEMS ${ARGV})
+ string(TOLOWER ${__zng_contentName} __zng_contentNameLower)
+ FetchContent_GetProperties(${__zng_contentName})
+ if(NOT ${__zng_contentNameLower}_POPULATED)
+ FetchContent_Populate(${__zng_contentName})
+ add_subdirectory(${${__zng_contentNameLower}_SOURCE_DIR} ${${__zng_contentNameLower}_BINARY_DIR} EXCLUDE_FROM_ALL)
+ endif()
+ endforeach()
+ unset(__zng_contentName)
+ unset(__zng_contentNameLower)
+ else()
+ FetchContent_MakeAvailable(${ARGV})
+ endif()
+endmacro()
+
+if(CMAKE_VERSION VERSION_LESS 3.28)
+ set(ZNG_FetchContent_Declare_EXCLUDE_FROM_ALL)
+else()
+ set(ZNG_FetchContent_Declare_EXCLUDE_FROM_ALL EXCLUDE_FROM_ALL)
+endif()
diff --git a/neozip/cmake/toolchain-aarch64.cmake b/neozip/cmake/toolchain-aarch64.cmake
new file mode 100644
index 0000000000..1e24731077
--- /dev/null
+++ b/neozip/cmake/toolchain-aarch64.cmake
@@ -0,0 +1,24 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR aarch64)
+set(CMAKE_SYSTEM_VERSION 1)
+
+set(CMAKE_C_COMPILER_TARGET "aarch64-linux-gnu")
+set(CMAKE_CXX_COMPILER_TARGET "aarch64-linux-gnu")
+
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR qemu-aarch64 -L /usr/${CMAKE_C_COMPILER_TARGET}/)
+
+SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc)
+if(NOT C_COMPILER_FULL_PATH)
+ message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++)
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()
diff --git a/neozip/cmake/toolchain-arm.cmake b/neozip/cmake/toolchain-arm.cmake
new file mode 100644
index 0000000000..1bdd8d2cc1
--- /dev/null
+++ b/neozip/cmake/toolchain-arm.cmake
@@ -0,0 +1,29 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR arm)
+set(CMAKE_SYSTEM_VERSION 1)
+
+if(NOT DEFINED CMAKE_C_COMPILER_TARGET)
+ set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabi)
+endif()
+if(NOT DEFINED CMAKE_CXX_COMPILER_TARGET)
+ set(CMAKE_CXX_COMPILER_TARGET arm-linux-gnueabi)
+endif()
+
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR qemu-arm -L /usr/${CMAKE_C_COMPILER_TARGET}/)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc)
+if(NOT C_COMPILER_FULL_PATH)
+ message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++)
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()
diff --git a/neozip/cmake/toolchain-armhf.cmake b/neozip/cmake/toolchain-armhf.cmake
new file mode 100644
index 0000000000..007859caf6
--- /dev/null
+++ b/neozip/cmake/toolchain-armhf.cmake
@@ -0,0 +1,25 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR arm)
+set(CMAKE_SYSTEM_VERSION 1)
+
+set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabihf)
+set(CMAKE_CXX_COMPILER_TARGET arm-linux-gnueabihf)
+
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR qemu-arm -L /usr/${CMAKE_C_COMPILER_TARGET}/)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc)
+if(NOT C_COMPILER_FULL_PATH)
+ message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++)
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()
diff --git a/neozip/cmake/toolchain-e2k-lcc.cmake b/neozip/cmake/toolchain-e2k-lcc.cmake
new file mode 100644
index 0000000000..ead39b88af
--- /dev/null
+++ b/neozip/cmake/toolchain-e2k-lcc.cmake
@@ -0,0 +1,44 @@
+# Export configurable variables for the try_compile() command.
+set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES MCST_LCC_PREFIX QEMU_CPU)
+
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR e2k)
+set(CMAKE_SYSTEM_VERSION 1)
+
+set(CMAKE_C_COMPILER_TARGET e2k-linux-gnu)
+set(CMAKE_CXX_COMPILER_TARGET e2k-linux-gnu)
+
+set(CMAKE_CROSSCOMPILING TRUE)
+
+# Require explicit toolchain prefix
+if(NOT MCST_LCC_PREFIX)
+ message(FATAL_ERROR "MCST_LCC_PREFIX must be set to the LCC install prefix (e.g. /opt/mcst/lcc-<ver>)")
+endif()
+if(NOT EXISTS "${MCST_LCC_PREFIX}/bin")
+ message(FATAL_ERROR "MCST_LCC_PREFIX does not contain a bin directory: ${MCST_LCC_PREFIX}")
+endif()
+if(NOT EXISTS "${MCST_LCC_PREFIX}/fs")
+ message(FATAL_ERROR "MCST_LCC_PREFIX does not contain a fs directory: ${MCST_LCC_PREFIX}")
+endif()
+
+unset(QEMU_CPU_ARG)
+if(QEMU_CPU)
+ set(QEMU_CPU_ARG -cpu "${QEMU_CPU}")
+endif()
+set(CMAKE_CROSSCOMPILING_EMULATOR qemu-e2k-static ${QEMU_CPU_ARG} -L "${MCST_LCC_PREFIX}/fs/")
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+find_program(C_COMPILER_FULL_PATH NAMES lcc PATHS "${MCST_LCC_PREFIX}/bin" NO_DEFAULT_PATH)
+if(NOT C_COMPILER_FULL_PATH)
+ message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH NAMES l++ PATHS "${MCST_LCC_PREFIX}/bin" NO_DEFAULT_PATH)
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()
diff --git a/neozip/cmake/toolchain-llvm-mingw-aarch64.cmake b/neozip/cmake/toolchain-llvm-mingw-aarch64.cmake
new file mode 100644
index 0000000000..4da1e2c796
--- /dev/null
+++ b/neozip/cmake/toolchain-llvm-mingw-aarch64.cmake
@@ -0,0 +1,41 @@
+set(CMAKE_SYSTEM_NAME Windows)
+set(CMAKE_C_COMPILER_FRONTEND_VARIANT GNU)
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR wine)
+
+set(CMAKE_C_COMPILER_TARGET aarch64-w64-mingw32)
+set(CMAKE_CXX_COMPILER_TARGET aarch64-w64-mingw32)
+set(CMAKE_RC_COMPILER_TARGET aarch64-w64-mingw32)
+set(CMAKE_SYSTEM_PROCESSOR aarch64)
+
+# Required to propagate 'LLVM_MINGW_ROOT' variables to C compiler feature test.
+set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES LLVM_MINGW_ROOT)
+
+if(NOT LLVM_MINGW_ROOT)
+ set(LLVM_MINGW_ROOT $ENV{LLVM_MINGW_ROOT})
+endif()
+cmake_path(CONVERT "${LLVM_MINGW_ROOT}" TO_CMAKE_PATH_LIST LLVM_MINGW_ROOT)
+
+set(CMAKE_FIND_ROOT_PATH ${LLVM_MINGW_ROOT} ${LLVM_MINGW_ROOT}/aarch64-w64-mingw32)
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ALWAYS)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+find_program(C_COMPILER_FULL_PATH ${CMAKE_C_COMPILER_TARGET}-clang HINTS ${LLVM_MINGW_ROOT}/bin)
+if(NOT C_COMPILER_FULL_PATH)
+message(FATAL_ERROR "Compiler for ${CMAKE_C_COMPILER_TARGET} not found. Try setting llvm-mingw root path to LLVM_MINGW_ROOT variable!")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH ${CMAKE_CXX_COMPILER_TARGET}-clang++ HINTS ${LLVM_MINGW_ROOT}/bin)
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()
+
+find_program(RC_COMPILER_FULL_PATH ${CMAKE_RC_COMPILER_TARGET}-windres HINTS ${LLVM_MINGW_ROOT}/bin)
+if(RC_COMPILER_FULL_PATH)
+ set(CMAKE_RC_COMPILER ${RC_COMPILER_FULL_PATH})
+endif()
+
+add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:-gcodeview>)
+add_link_options(-Wl,-pdb=)
diff --git a/neozip/cmake/toolchain-llvm-mingw-armv7.cmake b/neozip/cmake/toolchain-llvm-mingw-armv7.cmake
new file mode 100644
index 0000000000..d077309b86
--- /dev/null
+++ b/neozip/cmake/toolchain-llvm-mingw-armv7.cmake
@@ -0,0 +1,41 @@
+set(CMAKE_SYSTEM_NAME Windows)
+set(CMAKE_C_COMPILER_FRONTEND_VARIANT GNU)
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR wine)
+
+set(CMAKE_C_COMPILER_TARGET armv7-w64-mingw32)
+set(CMAKE_CXX_COMPILER_TARGET armv7-w64-mingw32)
+set(CMAKE_RC_COMPILER_TARGET armv7-w64-mingw32)
+set(CMAKE_SYSTEM_PROCESSOR armv7)
+
+# Required to propagate 'LLVM_MINGW_ROOT' variables to C compiler feature test.
+set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES LLVM_MINGW_ROOT)
+
+if(NOT LLVM_MINGW_ROOT)
+ set(LLVM_MINGW_ROOT $ENV{LLVM_MINGW_ROOT})
+endif()
+cmake_path(CONVERT "${LLVM_MINGW_ROOT}" TO_CMAKE_PATH_LIST LLVM_MINGW_ROOT)
+
+set(CMAKE_FIND_ROOT_PATH ${LLVM_MINGW_ROOT} ${LLVM_MINGW_ROOT}/armv7-w64-mingw32)
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ALWAYS)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+find_program(C_COMPILER_FULL_PATH ${CMAKE_C_COMPILER_TARGET}-clang HINTS ${LLVM_MINGW_ROOT}/bin)
+if(NOT C_COMPILER_FULL_PATH)
+message(FATAL_ERROR "Compiler for ${CMAKE_C_COMPILER_TARGET} not found. Try setting llvm-mingw root path to LLVM_MINGW_ROOT variable!")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH ${CMAKE_CXX_COMPILER_TARGET}-clang++ HINTS ${LLVM_MINGW_ROOT}/bin)
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()
+
+find_program(RC_COMPILER_FULL_PATH ${CMAKE_RC_COMPILER_TARGET}-windres HINTS ${LLVM_MINGW_ROOT}/bin)
+if(RC_COMPILER_FULL_PATH)
+ set(CMAKE_RC_COMPILER ${RC_COMPILER_FULL_PATH})
+endif()
+
+add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:-gcodeview>)
+add_link_options(-Wl,-pdb=)
diff --git a/neozip/cmake/toolchain-llvm-mingw-i686.cmake b/neozip/cmake/toolchain-llvm-mingw-i686.cmake
new file mode 100644
index 0000000000..17a0aa7909
--- /dev/null
+++ b/neozip/cmake/toolchain-llvm-mingw-i686.cmake
@@ -0,0 +1,41 @@
+set(CMAKE_SYSTEM_NAME Windows)
+set(CMAKE_C_COMPILER_FRONTEND_VARIANT GNU)
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR wine)
+
+set(CMAKE_C_COMPILER_TARGET i686-w64-mingw32)
+set(CMAKE_CXX_COMPILER_TARGET i686-w64-mingw32)
+set(CMAKE_RC_COMPILER_TARGET i686-w64-mingw32)
+set(CMAKE_SYSTEM_PROCESSOR i686)
+
+# Required to propagate 'LLVM_MINGW_ROOT' variables to C compiler feature test.
+set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES LLVM_MINGW_ROOT)
+
+if(NOT LLVM_MINGW_ROOT)
+ set(LLVM_MINGW_ROOT $ENV{LLVM_MINGW_ROOT})
+endif()
+cmake_path(CONVERT "${LLVM_MINGW_ROOT}" TO_CMAKE_PATH_LIST LLVM_MINGW_ROOT)
+
+set(CMAKE_FIND_ROOT_PATH ${LLVM_MINGW_ROOT} ${LLVM_MINGW_ROOT}/i686-w64-mingw32)
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ALWAYS)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+find_program(C_COMPILER_FULL_PATH ${CMAKE_C_COMPILER_TARGET}-clang HINTS ${LLVM_MINGW_ROOT}/bin)
+if(NOT C_COMPILER_FULL_PATH)
+ message(FATAL_ERROR "Compiler for ${CMAKE_C_COMPILER_TARGET} not found. Try setting llvm-mingw root path to LLVM_MINGW_ROOT variable!")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH ${CMAKE_CXX_COMPILER_TARGET}-clang++ HINTS ${LLVM_MINGW_ROOT}/bin)
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()
+
+find_program(RC_COMPILER_FULL_PATH ${CMAKE_RC_COMPILER_TARGET}-windres HINTS ${LLVM_MINGW_ROOT}/bin)
+if(RC_COMPILER_FULL_PATH)
+ set(CMAKE_RC_COMPILER ${RC_COMPILER_FULL_PATH})
+endif()
+
+add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:-gcodeview>)
+add_link_options(-Wl,-pdb=)
diff --git a/neozip/cmake/toolchain-llvm-mingw-x86_64.cmake b/neozip/cmake/toolchain-llvm-mingw-x86_64.cmake
new file mode 100644
index 0000000000..e519562418
--- /dev/null
+++ b/neozip/cmake/toolchain-llvm-mingw-x86_64.cmake
@@ -0,0 +1,41 @@
+set(CMAKE_SYSTEM_NAME Windows)
+set(CMAKE_C_COMPILER_FRONTEND_VARIANT GNU)
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR wine)
+
+set(CMAKE_C_COMPILER_TARGET x86_64-w64-mingw32)
+set(CMAKE_CXX_COMPILER_TARGET x86_64-w64-mingw32)
+set(CMAKE_RC_COMPILER_TARGET x86_64-w64-mingw32)
+set(CMAKE_SYSTEM_PROCESSOR x86_64)
+
+# Required to propagate 'LLVM_MINGW_ROOT' variables to C compiler feature test.
+set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES LLVM_MINGW_ROOT)
+
+if(NOT LLVM_MINGW_ROOT)
+ set(LLVM_MINGW_ROOT $ENV{LLVM_MINGW_ROOT})
+endif()
+cmake_path(CONVERT "${LLVM_MINGW_ROOT}" TO_CMAKE_PATH_LIST LLVM_MINGW_ROOT)
+
+set(CMAKE_FIND_ROOT_PATH ${LLVM_MINGW_ROOT} ${LLVM_MINGW_ROOT}/x86_64-w64-mingw32)
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ALWAYS)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+find_program(C_COMPILER_FULL_PATH ${CMAKE_C_COMPILER_TARGET}-clang HINTS ${LLVM_MINGW_ROOT}/bin)
+if(NOT C_COMPILER_FULL_PATH)
+ message(FATAL_ERROR "Compiler for ${CMAKE_C_COMPILER_TARGET} not found. Try setting llvm-mingw root path to LLVM_MINGW_ROOT variable!")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH ${CMAKE_CXX_COMPILER_TARGET}-clang++ HINTS ${LLVM_MINGW_ROOT}/bin)
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()
+
+find_program(RC_COMPILER_FULL_PATH ${CMAKE_RC_COMPILER_TARGET}-windres HINTS ${LLVM_MINGW_ROOT}/bin)
+if(RC_COMPILER_FULL_PATH)
+ set(CMAKE_RC_COMPILER ${RC_COMPILER_FULL_PATH})
+endif()
+
+add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:-gcodeview>)
+add_link_options(-Wl,-pdb=)
diff --git a/neozip/cmake/toolchain-loongarch64-gcc.cmake b/neozip/cmake/toolchain-loongarch64-gcc.cmake
new file mode 100644
index 0000000000..7e10c701b7
--- /dev/null
+++ b/neozip/cmake/toolchain-loongarch64-gcc.cmake
@@ -0,0 +1,28 @@
+# Export configurable variables for the try_compile() command.
+set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES COMPILER_SUFFIX)
+
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR loongarch64)
+set(CMAKE_SYSTEM_VERSION 1)
+
+set(CMAKE_C_COMPILER_TARGET loongarch64-linux-gnu)
+set(CMAKE_CXX_COMPILER_TARGET loongarch64-linux-gnu)
+
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR qemu-loongarch64 -cpu la464-loongarch-cpu -L /usr/${CMAKE_C_COMPILER_TARGET}/)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc${COMPILER_SUFFIX})
+if(NOT C_COMPILER_FULL_PATH)
+ message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH NAMES g++${COMPILER_SUFFIX}-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++${COMPILER_SUFFIX})
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()
diff --git a/neozip/cmake/toolchain-mingw-i686.cmake b/neozip/cmake/toolchain-mingw-i686.cmake
new file mode 100644
index 0000000000..b95e63f50c
--- /dev/null
+++ b/neozip/cmake/toolchain-mingw-i686.cmake
@@ -0,0 +1,35 @@
+set(CMAKE_SYSTEM_NAME Windows)
+
+set(CMAKE_C_COMPILER_TARGET i686-w64-mingw32)
+set(CMAKE_CXX_COMPILER_TARGET i686-w64-mingw32)
+set(CMAKE_RC_COMPILER_TARGET i686-w64-mingw32)
+
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR wine)
+
+set(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32)
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+# Prefer posix gcc variant for gtest pthread support
+find_program(C_COMPILER_FULL_PATH NAMES
+ ${CMAKE_C_COMPILER_TARGET}-gcc-posix
+ ${CMAKE_C_COMPILER_TARGET}-gcc)
+if(NOT C_COMPILER_FULL_PATH)
+ message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH NAMES
+ ${CMAKE_CXX_COMPILER_TARGET}-g++-posix
+ ${CMAKE_CXX_COMPILER_TARGET}-g++)
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()
+
+find_program(RC_COMPILER_FULL_PATH NAMES
+ ${CMAKE_RC_COMPILER_TARGET}-windres)
+if(RC_COMPILER_FULL_PATH)
+ set(CMAKE_RC_COMPILER ${RC_COMPILER_FULL_PATH})
+endif()
diff --git a/neozip/cmake/toolchain-mingw-x86_64.cmake b/neozip/cmake/toolchain-mingw-x86_64.cmake
new file mode 100644
index 0000000000..8c660b0b1e
--- /dev/null
+++ b/neozip/cmake/toolchain-mingw-x86_64.cmake
@@ -0,0 +1,34 @@
+set(CMAKE_SYSTEM_NAME Windows)
+
+set(CMAKE_C_COMPILER_TARGET x86_64-w64-mingw32)
+set(CMAKE_CXX_COMPILER_TARGET x86_64-w64-mingw32)
+set(CMAKE_RC_COMPILER_TARGET x86_64-w64-mingw32)
+
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR wine)
+
+set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32)
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+# Prefer posix gcc variant for gtest pthread support
+find_program(C_COMPILER_FULL_PATH NAMES
+ ${CMAKE_C_COMPILER_TARGET}-gcc-posix
+ ${CMAKE_C_COMPILER_TARGET}-gcc)
+if(NOT C_COMPILER_FULL_PATH)
+ message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH NAMES
+ ${CMAKE_CXX_COMPILER_TARGET}-g++-posix
+ ${CMAKE_CXX_COMPILER_TARGET}-g++)
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()
+
+find_program(RC_COMPILER_FULL_PATH NAMES ${CMAKE_RC_COMPILER_TARGET}-windres)
+if(RC_COMPILER_FULL_PATH)
+ set(CMAKE_RC_COMPILER ${RC_COMPILER_FULL_PATH})
+endif()
diff --git a/neozip/cmake/toolchain-mips.cmake b/neozip/cmake/toolchain-mips.cmake
new file mode 100644
index 0000000000..69a1025e34
--- /dev/null
+++ b/neozip/cmake/toolchain-mips.cmake
@@ -0,0 +1,29 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR mips)
+set(CMAKE_SYSTEM_VERSION 1)
+
+if(NOT DEFINED CMAKE_C_COMPILER_TARGET)
+ set(CMAKE_C_COMPILER_TARGET mips-linux-gnu)
+endif()
+if(NOT DEFINED CMAKE_CXX_COMPILER_TARGET)
+ set(CMAKE_CXX_COMPILER_TARGET mips-linux-gnu)
+endif()
+
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR qemu-mips -L /usr/${CMAKE_C_COMPILER_TARGET}/)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc)
+if(NOT C_COMPILER_FULL_PATH)
+ message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++)
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()
diff --git a/neozip/cmake/toolchain-mips64.cmake b/neozip/cmake/toolchain-mips64.cmake
new file mode 100644
index 0000000000..8ef3b6b009
--- /dev/null
+++ b/neozip/cmake/toolchain-mips64.cmake
@@ -0,0 +1,29 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR mips64)
+set(CMAKE_SYSTEM_VERSION 1)
+
+if(NOT DEFINED CMAKE_C_COMPILER_TARGET)
+ set(CMAKE_C_COMPILER_TARGET mips64-linux-gnuabi64)
+endif()
+if(NOT DEFINED CMAKE_CXX_COMPILER_TARGET)
+ set(CMAKE_CXX_COMPILER_TARGET mips64-linux-gnuabi64)
+endif()
+
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR qemu-mips64 -L /usr/${CMAKE_C_COMPILER_TARGET}/)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc)
+if(NOT C_COMPILER_FULL_PATH)
+ message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++)
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()
diff --git a/neozip/cmake/toolchain-powerpc.cmake b/neozip/cmake/toolchain-powerpc.cmake
new file mode 100644
index 0000000000..f09713370d
--- /dev/null
+++ b/neozip/cmake/toolchain-powerpc.cmake
@@ -0,0 +1,25 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR powerpc)
+set(CMAKE_SYSTEM_VERSION 1)
+
+set(CMAKE_C_COMPILER_TARGET powerpc-linux-gnu)
+set(CMAKE_CXX_COMPILER_TARGET powerpc-linux-gnu)
+
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR qemu-ppc -cpu 7400 -L /usr/${CMAKE_C_COMPILER_TARGET}/)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc)
+if(NOT C_COMPILER_FULL_PATH)
+ message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++)
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()
diff --git a/neozip/cmake/toolchain-powerpc64-clang.cmake b/neozip/cmake/toolchain-powerpc64-clang.cmake
new file mode 100644
index 0000000000..f986796f6b
--- /dev/null
+++ b/neozip/cmake/toolchain-powerpc64-clang.cmake
@@ -0,0 +1,16 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR ppc64)
+set(CMAKE_SYSTEM_VERSION 1)
+
+set(CMAKE_C_COMPILER clang)
+set(CMAKE_C_COMPILER_TARGET powerpc64-linux-gnu)
+set(CMAKE_CXX_COMPILER clang++)
+set(CMAKE_CXX_COMPILER_TARGET powerpc64-linux-gnu)
+
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR qemu-ppc64 -cpu power9 -L /usr/${CMAKE_C_COMPILER_TARGET}/)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
diff --git a/neozip/cmake/toolchain-powerpc64-power9.cmake b/neozip/cmake/toolchain-powerpc64-power9.cmake
new file mode 100644
index 0000000000..2ea190a4d1
--- /dev/null
+++ b/neozip/cmake/toolchain-powerpc64-power9.cmake
@@ -0,0 +1,25 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR ppc64)
+set(CMAKE_SYSTEM_VERSION 1)
+
+set(CMAKE_C_COMPILER_TARGET powerpc64-linux-gnu)
+set(CMAKE_CXX_COMPILER_TARGET powerpc64-linux-gnu)
+
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR qemu-ppc64 -cpu power9 -L /usr/${CMAKE_C_COMPILER_TARGET}/)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc)
+if(NOT C_COMPILER_FULL_PATH)
+ message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++)
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()
diff --git a/neozip/cmake/toolchain-powerpc64.cmake b/neozip/cmake/toolchain-powerpc64.cmake
new file mode 100644
index 0000000000..80d8b904e7
--- /dev/null
+++ b/neozip/cmake/toolchain-powerpc64.cmake
@@ -0,0 +1,25 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR ppc64)
+set(CMAKE_SYSTEM_VERSION 1)
+
+set(CMAKE_C_COMPILER_TARGET powerpc64-linux-gnu)
+set(CMAKE_CXX_COMPILER_TARGET powerpc64-linux-gnu)
+
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR qemu-ppc64 -cpu power8 -L /usr/${CMAKE_C_COMPILER_TARGET}/)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc)
+if(NOT C_COMPILER_FULL_PATH)
+ message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++)
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()
diff --git a/neozip/cmake/toolchain-powerpc64le-clang.cmake b/neozip/cmake/toolchain-powerpc64le-clang.cmake
new file mode 100644
index 0000000000..b3423c590d
--- /dev/null
+++ b/neozip/cmake/toolchain-powerpc64le-clang.cmake
@@ -0,0 +1,16 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR ppc64le)
+set(CMAKE_SYSTEM_VERSION 1)
+
+set(CMAKE_C_COMPILER clang)
+set(CMAKE_C_COMPILER_TARGET powerpc64le-linux-gnu)
+set(CMAKE_CXX_COMPILER clang++)
+set(CMAKE_CXX_COMPILER_TARGET powerpc64le-linux-gnu)
+
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR qemu-ppc64le -cpu power9 -L /usr/${CMAKE_C_COMPILER_TARGET}/)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
diff --git a/neozip/cmake/toolchain-powerpc64le-power9.cmake b/neozip/cmake/toolchain-powerpc64le-power9.cmake
new file mode 100644
index 0000000000..5ac8c7a9c1
--- /dev/null
+++ b/neozip/cmake/toolchain-powerpc64le-power9.cmake
@@ -0,0 +1,25 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR ppc64le)
+set(CMAKE_SYSTEM_VERSION 1)
+
+set(CMAKE_C_COMPILER_TARGET powerpc64le-linux-gnu)
+set(CMAKE_CXX_COMPILER_TARGET powerpc64le-linux-gnu)
+
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR qemu-ppc64le -cpu power9 -L /usr/${CMAKE_C_COMPILER_TARGET}/)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc)
+if(NOT C_COMPILER_FULL_PATH)
+ message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++)
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()
diff --git a/neozip/cmake/toolchain-powerpc64le.cmake b/neozip/cmake/toolchain-powerpc64le.cmake
new file mode 100644
index 0000000000..68381de120
--- /dev/null
+++ b/neozip/cmake/toolchain-powerpc64le.cmake
@@ -0,0 +1,25 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR ppc64le)
+set(CMAKE_SYSTEM_VERSION 1)
+
+set(CMAKE_C_COMPILER_TARGET powerpc64le-linux-gnu)
+set(CMAKE_CXX_COMPILER_TARGET powerpc64le-linux-gnu)
+
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR qemu-ppc64le -cpu power8 -L /usr/${CMAKE_C_COMPILER_TARGET}/)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc)
+if(NOT C_COMPILER_FULL_PATH)
+ message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++)
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()
diff --git a/neozip/cmake/toolchain-riscv-clang.cmake b/neozip/cmake/toolchain-riscv-clang.cmake
new file mode 100644
index 0000000000..71fa7f4cf3
--- /dev/null
+++ b/neozip/cmake/toolchain-riscv-clang.cmake
@@ -0,0 +1,16 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR riscv64)
+set(CMAKE_SYSTEM_VERSION 1)
+
+set(CMAKE_C_COMPILER clang)
+set(CMAKE_C_COMPILER_TARGET riscv64-linux-gnu)
+set(CMAKE_CXX_COMPILER clang++)
+set(CMAKE_CXX_COMPILER_TARGET riscv64-linux-gnu)
+
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR qemu-riscv64 -cpu rv64,zba=true,zbb=true,zbc=true,zbs=true,v=true,vlen=512,elen=64,vext_spec=v1.0 -L /usr/${CMAKE_C_COMPILER_TARGET}/)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
diff --git a/neozip/cmake/toolchain-riscv.cmake b/neozip/cmake/toolchain-riscv.cmake
new file mode 100644
index 0000000000..241f2a7d71
--- /dev/null
+++ b/neozip/cmake/toolchain-riscv.cmake
@@ -0,0 +1,25 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR riscv64)
+set(CMAKE_SYSTEM_VERSION 1)
+
+set(CMAKE_C_COMPILER_TARGET riscv64-linux-gnu)
+set(CMAKE_CXX_COMPILER_TARGET riscv64-linux-gnu)
+
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR qemu-riscv64 -cpu rv64,zba=true,zbb=true,zbc=true,zbs=true,v=true,vlen=512,elen=64,vext_spec=v1.0 -L /usr/${CMAKE_C_COMPILER_TARGET}/)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc)
+if(NOT C_COMPILER_FULL_PATH)
+ message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++)
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()
diff --git a/neozip/cmake/toolchain-s390x.cmake b/neozip/cmake/toolchain-s390x.cmake
new file mode 100644
index 0000000000..9455a2bedb
--- /dev/null
+++ b/neozip/cmake/toolchain-s390x.cmake
@@ -0,0 +1,25 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR s390x)
+set(CMAKE_SYSTEM_VERSION 1)
+
+set(CMAKE_C_COMPILER_TARGET s390x-linux-gnu)
+set(CMAKE_CXX_COMPILER_TARGET s390x-linux-gnu)
+
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR qemu-s390x -L /usr/${CMAKE_C_COMPILER_TARGET}/)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc)
+if(NOT C_COMPILER_FULL_PATH)
+ message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++)
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()
diff --git a/neozip/cmake/toolchain-sparc64.cmake b/neozip/cmake/toolchain-sparc64.cmake
new file mode 100644
index 0000000000..16161a78c0
--- /dev/null
+++ b/neozip/cmake/toolchain-sparc64.cmake
@@ -0,0 +1,25 @@
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR sparc64)
+set(CMAKE_SYSTEM_VERSION 1)
+
+set(CMAKE_C_COMPILER_TARGET sparc64-linux-gnu)
+set(CMAKE_CXX_COMPILER_TARGET sparc64-linux-gnu)
+
+set(CMAKE_CROSSCOMPILING TRUE)
+set(CMAKE_CROSSCOMPILING_EMULATOR qemu-sparc64 -L /usr/${CMAKE_C_COMPILER_TARGET}/)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc)
+if(NOT C_COMPILER_FULL_PATH)
+ message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found")
+endif()
+set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH})
+
+find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++)
+if(CXX_COMPILER_FULL_PATH)
+ set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH})
+endif()