Skip to content

Fix arm64 macOS build with Homebrew#1678

Open
audriusbuika wants to merge 2 commits intoveracrypt:masterfrom
audriusbuika:fix-arm64-build-with-homebrew
Open

Fix arm64 macOS build with Homebrew#1678
audriusbuika wants to merge 2 commits intoveracrypt:masterfrom
audriusbuika:fix-arm64-build-with-homebrew

Conversation

@audriusbuika
Copy link
Copy Markdown
Contributor

Problem

On Apple Silicon, ./src/Build/build_veracrypt_macosx.sh -b fails to build:

clang: error: unsupported option '-mssse3' for target 'arm64-apple-darwin24.6.0'
clang: error: unsupported option '-msse4.1' for target 'arm64-apple-darwin24.6.0'
clang: error: unsupported option '-msha'   for target 'arm64-apple-darwin24.6.0'
make[1]: *** [../Crypto/Sha2Intel.oshani] Error 1

Once the flag issue is worked around, the link step then fails with missing
arm64 symbols: _aes_encrypt, _aes_hw_cpu_*, and
_sha256_compress_digest_armv8.

Root Cause

Two separate issues surface together on arm64:

  1. The pattern rules in src/Build/Include/Makefile.inc (%.oshani,
    %.osse41, %.ossse3, %.oaesni, %.oavx2) always append x86-only
    flags such as -mssse3 -msse4.1 -msha. clang rejects those flags when
    targeting arm64, even though the source bodies are already guarded by
    CRYPTOPP_BOOL_X86/X64 and would compile to empty objects.

  2. src/Volume/Volume.make has no arm64 object list for local MacOSX
    builds. The build script sets COMPILE_ASM=false on arm64 hosts (yasm
    can't assemble x86 asm for an arm64-only build), which leaves the
    MacOSX branch empty, and the generic arm64 branch below it is never
    reached. As a result, no AES or SHA-256 backend ends up in the link.

Fix

src/Build/Include/Makefile.inc — move the x86 feature flags into
variables that are empty when CPU_ARCH=arm64. x86/x64 builds keep the
same flags they had before; arm64 compiles the same sources without
them, and the existing #ifdef guards take care of the rest.

src/Volume/Volume.make

  1. Add an else ifeq "$(CPU_ARCH)" "arm64" branch inside the MacOSX
    block that pulls in Aes_hw_armv8.oarmv8crypto, Aescrypt.o, and
    sha256_armv8.oarmv8crypto — the symbols the linker was missing.
  2. On arm64, compile Sha2Intel, blake2s_SSE41, blake2s_SSSE3, and
    opt_avx2 as plain .o files so they skip the x86-flag pattern rules.

Verification

The build now completes on arm64 (macOS 24.6, SDK 26.2) and produces a
working src/Main/VeraCrypt binary. x86_64 and universal-binary release
builds are untouched — the new paths only activate when CPU_ARCH=arm64.

@idrassi
Copy link
Copy Markdown
Member

idrassi commented Apr 16, 2026

Thanks for investigating the Apple Silicon/Homebrew build failure.

The local arm64 build issue is real, but I do not think this PR cannot be merged as-is because the CPU_ARCH=arm64 conditions also affect the normal non-local macOS release build on Apple Silicon.

On Apple Silicon, CPU_ARCH is derived from uname -m, so it is arm64 even when the build is not local-only. In that non-local path, src/Makefile still builds a universal x86_64 + arm64 binary. With this PR, src/Volume/Volume.make therefore compiles blake2s_SSE41, blake2s_SSSE3, Sha2Intel and Argon2/src/opt_avx2 as plain .o files for the universal build instead of using the feature-specific .osse41, .ossse3, .oshani, and .oavx2 rules.

The opt_avx2 case is a functional regression: without -mavx2, __AVX2__ is not defined, so fill_segment_avx2 compiles to the stub returning ARGON2_INCORRECT_PARAMETER. The x86 runtime dispatch calls this function when HasSAVX2 is true, so the x86_64 slice of a universal macOS build produced on Apple Silicon can fail on AVX2-capable Intel machines.

Please scope the plain-object fallback to the local arm64 build only, for example by keying it on LOCAL_DEVELOPMENT_BUILD=true and CPU_ARCH=arm64 rather than on CPU_ARCH=arm64 alone. The global Makefile.inc flag stripping should either be avoided or constrained by the same condition.

Comment thread src/Volume/Volume.make
Comment on lines +101 to +108
ifeq "$(CPU_ARCH)" "arm64"
# x86-only intrinsics sources are compiled as plain objects on arm64
# (their bodies are #ifdef-gated to x86/x64 and become empty translation units)
OBJS += ../Crypto/blake2s_SSE41.o
OBJS += ../Crypto/blake2s_SSSE3.o
OBJS += ../Crypto/Sha2Intel.o
OBJS += ../Crypto/Argon2/src/opt_avx2.o
else
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition is too broad. CPU_ARCH=arm64 is also true for the normal non-local macOS build on Apple Silicon, which still produces a universal x86_64 + arm64 binary. In that path this block makes the x86_64 slice compile Argon2/src/opt_avx2.c as plain .o instead of .oavx2, so __AVX2__ is not defined and fill_segment_avx2() becomes the stub that returns ARGON2_INCORRECT_PARAMETER. Please scope this fallback to the local arm64-only case, e.g. LOCAL_DEVELOPMENT_BUILD=true plus CPU_ARCH=arm64, not CPU_ARCH=arm64 alone.


# On arm64 hosts, x86 feature flags are rejected by clang.
# Source files are guarded by CRYPTOPP_BOOL_X86/X64 so they produce empty objects on arm64.
ifeq "$(CPU_ARCH)" "arm64"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has the same scoping issue as the Volume.make change: CPU_ARCH=arm64 is true on Apple Silicon even for the normal non-local macOS build, which still targets a universal x86_64 + arm64 binary.
For that universal path, the x86_64 slice still needs these feature flags. In particular, clearing X86_SHANI_FLAGS makes Sha2Intel.oshani compile without -msha: with Apple clang this fails because _mm_sha256msg1_epu32 requires the sha target feature.
Please either leave these pattern rules unchanged and avoid selecting the x86-specific suffix objects for local arm64-only builds, or gate this flag clearing on the local arm64-only case, e.g. LOCAL_DEVELOPMENT_BUILD=true plus CPU_ARCH=arm64, not CPU_ARCH=arm64 alone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants