@@ -47,12 +47,86 @@ if [[ -z "${!nss_dir_var}" ]]; then
4747fi
4848
4949# Use toolchain configuration from environment
50- eval " CC =\$ ${RUST_ANDROID_PREFIX} _CC"
50+ eval " BASE_CC =\$ ${RUST_ANDROID_PREFIX} _CC"
5151eval " AR=\$ ${RUST_ANDROID_PREFIX} _AR"
52+ eval " AS=\$ ${RUST_ANDROID_PREFIX} _AS"
5253eval " RANLIB=\$ ${RUST_ANDROID_PREFIX} _RANLIB"
54+ eval " LD=\$ ${RUST_ANDROID_PREFIX} _LD"
5355eval " STRIP=\$ ${RUST_ANDROID_PREFIX} _TOOLCHAIN_PREFIX/${NSS_TARGET} -strip"
56+ eval " TOOLCHAIN_BIN=\$ ${RUST_ANDROID_PREFIX} _TOOLCHAIN_PREFIX"
5457eval " CFLAGS=\$ ${RUST_ANDROID_PREFIX} _CFLAGS_${NSS_TARGET// -/ _} "
55- eval " LDFLAGS=\$ ${RUST_ANDROID_PREFIX} _LDFLAGS_${NSS_TARGET// -/ _} "
58+
59+ # Create a wrapper directory for fake tools and compiler wrappers
60+ WRAPPER_DIR=$( mktemp -d)
61+
62+ # Create compiler wrapper scripts that filter out incompatible Apple-specific flags
63+ # and add C++ standard library include paths for cross-compilation
64+ cat > " ${WRAPPER_DIR} /cc-wrapper" << 'EOF '
65+ #!/usr/bin/env bash
66+ # Filter out -fasm-blocks and -mpascal-strings which clang-20 doesn't support for cross-compilation
67+ args=()
68+ for arg in "$@"; do
69+ if [[ "$arg" != "-fasm-blocks" && "$arg" != "-mpascal-strings" ]]; then
70+ args+=("$arg")
71+ fi
72+ done
73+ # Add clang's C++ standard library include path
74+ args+=("-I/builds/worker/clang/include/c++/v1")
75+ # REAL_CC may contain spaces (e.g., "clang-20 -target ..."), so we need to use eval
76+ eval exec "${REAL_CC}" '"${args[@]}"'
77+ EOF
78+ chmod +x " ${WRAPPER_DIR} /cc-wrapper"
79+
80+ # Set CC and CXX to use the wrapper with all flags baked in
81+ export REAL_CC=" ${BASE_CC} ${CFLAGS} "
82+ CC=" ${WRAPPER_DIR} /cc-wrapper"
83+ CXX=" ${WRAPPER_DIR} /cc-wrapper"
84+ export CC CXX
85+
86+ # Create a fake xcodebuild script and tool wrappers to allow gyp to use the mac flavor
87+ # This tricks gyp into thinking Xcode is installed so it generates macOS-style build rules
88+ cat > " ${WRAPPER_DIR} /xcodebuild" << 'EOF '
89+ #!/usr/bin/env bash
90+ # Fake xcodebuild that returns a version for gyp's mac flavor
91+ # Xcode 12.2 corresponds to macOS SDK 11.0 (Big Sur) and adds Apple Silicon support
92+ echo "Xcode 12.2"
93+ echo "Build version 12B45b"
94+ EOF
95+ chmod +x " ${WRAPPER_DIR} /xcodebuild"
96+
97+ # Create unprefixed symlinks to cctools binaries that gyp's mac flavor expects
98+ # The mac flavor expects tools like 'otool', 'libtool', 'lipo' without the target prefix
99+ ln -s " ${TOOLCHAIN_BIN} /${NSS_TARGET} -otool" " ${WRAPPER_DIR} /otool"
100+ ln -s " ${TOOLCHAIN_BIN} /${NSS_TARGET} -libtool" " ${WRAPPER_DIR} /libtool"
101+ ln -s " ${TOOLCHAIN_BIN} /${NSS_TARGET} -lipo" " ${WRAPPER_DIR} /lipo"
102+ ln -s " ${TOOLCHAIN_BIN} /${NSS_TARGET} -nm" " ${WRAPPER_DIR} /nm"
103+
104+ export PATH=" ${WRAPPER_DIR} :${PATH} "
105+
106+ # Work around Python 3 bug in Ubuntu 22.04 gyp package
107+ # Create a wrapper that monkey-patches GetStdoutQuiet to fix bytes/str handling
108+ GYP_WRAPPER=$( mktemp)
109+ cat > " ${GYP_WRAPPER} " << 'EOFGYP '
110+ #!/usr/bin/env python3
111+ import sys
112+ import gyp.xcode_emulation
113+
114+ # Monkey-patch GetStdoutQuiet to fix Python 3 bytes/str bug
115+ original_GetStdoutQuiet = gyp.xcode_emulation.GetStdoutQuiet
116+ def patched_GetStdoutQuiet(cmdlist):
117+ import subprocess
118+ job = subprocess.Popen(cmdlist, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
119+ out = job.communicate()[0]
120+ if job.returncode != 0:
121+ return None
122+ return out.rstrip(b'\n').decode('utf-8')
123+ gyp.xcode_emulation.GetStdoutQuiet = patched_GetStdoutQuiet
124+
125+ # Now run gyp normally
126+ import gyp
127+ sys.exit(gyp.script_main())
128+ EOFGYP
129+ chmod +x " ${GYP_WRAPPER} "
56130
57131# Build NSPR
58132NSPR_BUILD_DIR=$( mktemp -d)
@@ -61,12 +135,10 @@ pushd "${NSPR_BUILD_DIR}"
61135 STRIP=" ${STRIP} " \
62136 RANLIB=" ${RANLIB} " \
63137 AR=" ${AR} " \
64- AS=" ${AS:- ${AR} } " \
65- LD=" ${LD:- ${AR} } " \
138+ AS=" ${AS} " \
139+ LD=" ${LD} " \
66140 CC=" ${CC} " \
67141 CCC=" ${CC} " \
68- CFLAGS=" ${CFLAGS} " \
69- LDFLAGS=" ${LDFLAGS} " \
70142 --target=" ${NSS_TARGET} " \
71143 --enable-64bit \
72144 --disable-debug \
78150NSS_BUILD_DIR=$( mktemp -d)
79151rm -rf " ${NSS_SRC_DIR} /nss/out"
80152
81- gyp -f ninja " ${NSS_SRC_DIR} /nss/nss.gyp" \
153+ " ${GYP_WRAPPER} " -f ninja-mac " ${NSS_SRC_DIR} /nss/nss.gyp" \
82154 --depth " ${NSS_SRC_DIR} /nss/" \
83155 --generator-output=. \
84156 -DOS=mac \
@@ -97,6 +169,11 @@ gyp -f ninja "${NSS_SRC_DIR}/nss/nss.gyp" \
97169 -Dpython=python3
98170
99171GENERATED_DIR=" ${NSS_SRC_DIR} /nss/out/Release/"
172+ echo " === Dumping build.ninja for nss-macos-cross ==="
173+ cat " ${GENERATED_DIR} /build.ninja"
174+
175+ # With the mac flavor, we can build all targets including shared libraries
176+ # The generated ninja rules will use macOS-style linker flags (e.g., -install_name instead of -soname)
100177ninja -C " ${GENERATED_DIR} "
101178
102179# Assemble the DIST_DIR with relevant libraries and headers
@@ -112,3 +189,4 @@ ninja -C "${GENERATED_DIR}"
112189# Cleanup
113190rm -rf " ${NSS_BUILD_DIR} "
114191rm -rf " ${NSPR_BUILD_DIR} "
192+ rm -rf " ${WRAPPER_DIR} "
0 commit comments