Universal builds for Android armv8 and compatibility with older compilers

- We add a new path for supporting universal builds without #embed . `xxd` causes the compiler to run out of memory, so instead we embed it as a string literal created at compile time.
    - This file is created in `net.sh`, and only if `--embed-dir` isn't supported + we are doing a universal build.
    - This was necessary because Android NDK seems to not support embed, idk why
- A couple other Makefile tweaks were necessary for the Android path.
- While we're at it, remove the non-universal arm64 windows and android binaries.

closes https://github.com/official-stockfish/Stockfish/pull/6827

No functional change
This commit is contained in:
anematode
2026-05-19 18:39:06 +02:00
committed by Joost VandeVondele
parent 319d61effd
commit 24abab9f6c
11 changed files with 63 additions and 96 deletions
+25 -19
View File
@@ -372,6 +372,14 @@ ifeq ($(ARCH),armv8-dotprod)
arm_version = 8
endif
ifeq ($(ARCH),armv8-universal)
arch = armv8
prefetch = yes
popcnt = yes
neon = yes
arm_version = 8
endif
ifeq ($(ARCH),apple-silicon)
arch = arm64
prefetch = yes
@@ -589,6 +597,7 @@ ifeq ($(COMP),ndk)
STRIP=llvm-strip
endif
endif
OBJCOPY=llvm-objcopy
LDFLAGS += -static-libstdc++
endif
@@ -1126,6 +1135,7 @@ profileclean:
universalclean:
@rm -rf $(TEMP_DIR)
@rm -f universal/network_dump.inc
# evaluation network (nnue)
net:
@@ -1281,20 +1291,6 @@ UNIVERSAL_EXE := $(CURDIR)/$(EXE)
ifeq ($(UNIVERSAL_BUILD),true)
# GCC 15+ or Clang 19+ required for #embed
CXX_MAJOR := $(shell $(CXX) -dumpversion 2>/dev/null | cut -d. -f1)
CXX_IS_CLANG := $(shell $(CXX) --version 2>/dev/null | head -1 | grep -ic clang)
ifeq ($(CXX_IS_CLANG),0)
EMBED_MIN := 15
EMBED_NAME := GCC
else
EMBED_MIN := 19
EMBED_NAME := Clang
endif
ifneq ($(shell test "$(CXX_MAJOR)" -ge "$(EMBED_MIN)" 2>/dev/null && echo ok),ok)
$(error Universal build needs $(EMBED_NAME) $(EMBED_MIN)+ for \#embed support; CXX=$(CXX) reports version '$(CXX_MAJOR)')
endif
UNIVERSAL_SRC_DIR := $(CURDIR)/universal
NNUE_EMBED_OBJ := $(TEMP_DIR)/nnue_embed.o
NET_SENTINEL := $(TEMP_DIR)/.net-done
@@ -1324,7 +1320,12 @@ UNIVERSAL_FINAL_FLAGS := -fno-exceptions -Os \
-Wno-c++26-extensions -Wno-c23-extensions # suppress #embed warnings
ifeq ($(KERNEL),Linux)
UNIVERSAL_FINAL_FLAGS += -static-libstdc++ -static-libgcc -lrt -lpthread
UNIVERSAL_FINAL_FLAGS += -static-libstdc++ -static-libgcc
ifeq ($(COMP),ndk)
UNIVERSAL_FINAL_FLAGS += -static
else
UNIVERSAL_FINAL_FLAGS += -lrt -lpthread
endif
else # windows
UNIVERSAL_FINAL_FLAGS += -Wl,--allow-multiple-definition -static
ifeq ($(COMP),clang)
@@ -1346,7 +1347,12 @@ else
arch-defmain = -Wl,--defsym=main=$(call arch-mangled,$(1))
endif
arch-cxxflags = --embed-dir=$(CURDIR) -DStockfish=$(call arch-namespace,$(1)) -DUNIVERSAL_BINARY \
EMBED_DIR_SUPPORTED := $(shell echo 'int main(){}' | $(CXX) -x c++ --embed-dir=. -o /dev/null -c - 2>/dev/null && echo 1 || echo 0)
ifeq ($(EMBED_DIR_SUPPORTED),1)
EMBED_DIR = --embed-dir=$(CURDIR)
endif
arch-cxxflags = $(EMBED_DIR) -DStockfish=$(call arch-namespace,$(1)) -DUNIVERSAL_BINARY \
$(call arch-defmain,$(1)) -Wno-c++26-extensions -Wno-c23-extensions
UOBJ_TGT ?= universal-object-pgo
@@ -1363,11 +1369,11 @@ $(TEMP_DIR):
# Download nnue files once in src/ (reused by every sub-arch via --embed-dir).
$(NET_SENTINEL): | $(TEMP_DIR)
@cd $(CURDIR) && $(SHELL) ../scripts/net.sh
@cd $(CURDIR) && $(SHELL) ../scripts/net.sh $(EMBED_DIR_SUPPORTED)
@touch $@
$(NNUE_EMBED_OBJ): $(UNIVERSAL_SRC_DIR)/nnue_embed.cpp $(NET_SENTINEL) | $(TEMP_DIR)
$(CXX) -O2 -Wno-c++26-extensions --embed-dir=$(CURDIR) -c $< -o $@
$(CXX) -O2 -Wno-c++26-extensions $(EMBED_DIR) -c $< -o $@
$(UNIVERSAL_ENTRY_OBJ): $(UNIVERSAL_ENTRY_SRC) | $(TEMP_DIR)
$(CXX) -O2 -c $< -o $@
@@ -1385,7 +1391,7 @@ $(TEMP_DIR)/%/.setup: | $(TEMP_DIR)
$(TEMP_DIR)/%/stockfish.o: $(TEMP_DIR)/%/.setup $(NNUE_EMBED_OBJ) $(NET_SENTINEL)
+ENV_CXXFLAGS='$(ENV_CXXFLAGS) $(call arch-cxxflags,$*)' \
$(MAKE) -C $(TEMP_DIR)/$* $(UOBJ_TGT) \
ARCH=$* CXX=$(CXX) \
ARCH=$* CXX=$(CXX) COMP=$(COMP) \
NNUE_EMBED_OBJ=$(NNUE_EMBED_OBJ)
# Drop COMDAT groups; clang LTO leaves them around internalized LOCAL
# template instantiations which causes problems at the final link
+11 -3
View File
@@ -51,10 +51,18 @@ INCBIN(EmbeddedNNUE, EvalFileDefaultName);
// separate, non-LTO nnue_embed.o (with strong symbols) can override them during the LTO link,
// (INCBIN can't deduplicate.)
#define WEAK_SYM __attribute__((weak))
extern const unsigned char gEmbeddedNNUEData[] WEAK_SYM = {
#embed EvalFileDefaultName
extern const unsigned char gEmbeddedNNUEData[] WEAK_SYM =
#ifdef __has_embed
{
#embed EvalFileDefaultName
};
extern const unsigned int gEmbeddedNNUESize WEAK_SYM = sizeof(gEmbeddedNNUEData);
const int padding = 0;
#else
#include "../universal/network_dump.inc"
;
const int padding = 1; // trailing NUL byte
#endif
extern const unsigned int gEmbeddedNNUESize WEAK_SYM = sizeof(gEmbeddedNNUEData) - padding;
#else
const unsigned char gEmbeddedNNUEData[1] = {0x0};
const unsigned int gEmbeddedNNUESize = 1;
+11 -3
View File
@@ -2,7 +2,15 @@
#include "../evaluate.h"
extern const unsigned char gEmbeddedNNUEData[] = {
#embed EvalFileDefaultName
extern const unsigned char gEmbeddedNNUEData[] =
#ifdef __has_embed
{
#embed EvalFileDefaultName
};
extern const unsigned int gEmbeddedNNUESize = sizeof(gEmbeddedNNUEData);
const unsigned int padding = 0;
#else
#include "network_dump.inc"
;
const unsigned int padding = 1; // trailing NUL byte
#endif
extern const unsigned int gEmbeddedNNUESize = sizeof(gEmbeddedNNUEData) - padding;