Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
5a5ad23
first successful build and run in simulator using in-repo test app
matthargett Oct 17, 2025
ea40648
adjust optimization and C++ flags. -Oz produces a 2MB smaller intl bi…
matthargett Oct 18, 2025
4b4310f
Update scripts/start.sh
matthargett Oct 19, 2025
bf0a760
clang bug in NDK 27 makes loop vectorization pass error. disable the …
matthargett Oct 19, 2025
daf4c7e
[ci] cleanup ubuntu runner disk (#188)
Kudo Oct 19, 2025
055fcd8
patches on top of bun, scripts to make things more dynamically discov…
matthargett Nov 2, 2025
b2e4240
lto=thin is clang-only, even in Ubuntu 24.x, and we only really care …
matthargett Nov 3, 2025
79cf238
be more flexible with suboptimal ABI requests, but still favor armv8a…
matthargett Nov 3, 2025
509e65b
filter 32bit platforms out
matthargett Nov 4, 2025
abbf732
upstream update fixes a problem where Promise reactions weren't first…
matthargett Nov 5, 2025
d7dbeb7
build and publish separate artifacts for NDK 27, 28, and 29 so decoup…
matthargett Nov 5, 2025
940c071
cache the NDKs instead of re-downloading and re-unpacking each time. …
matthargett Nov 5, 2025
3951b75
nointl build was broken due to incorrect codepoint comparison that wa…
matthargett Nov 7, 2025
aa5d326
ignore NDK-specific dist directories
matthargett Nov 7, 2025
74de2cf
fix overly specific shell usage
matthargett Nov 11, 2025
dbab32c
don't add clang flags to gcc. I thought for sure this would be fine, …
matthargett Nov 11, 2025
5ba223a
fix corrupt patch
matthargett Nov 12, 2025
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
build and publish separate artifacts for NDK 27, 28, and 29 so decoup…
…le React Native's lagging toolchain from other downstream users like BabylonNative
  • Loading branch information
matthargett committed Nov 5, 2025
commit d7dbeb7d8191424e7736de6000f0ae2b751796c0
33 changes: 32 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,38 @@
"bunWebKitRepo": "https://github.com/oven-sh/WebKit.git",
"bunWebKitCommit": "26e6460697dab3e8681489ce67857434b2180e6f",
"icuRelease": "release-74-2",
"icuArchive": "icu4c-74_2-src.tgz"
"icuArchive": "icu4c-74_2-src.tgz",
"ndkVariants": [
{
"id": "ndk27",
"label": "Android NDK r27",
"npmPackage": "jsc-android-ndk27",
"pkgRevisionPrefixes": ["27."],
"buildSuffix": "ndk27",
"distDir": "dist-ndk27",
"distUnstrippedDir": "dist-ndk27.unstripped",
"disableLoopVectorization": true
},
{
"id": "ndk28c",
"label": "Android NDK r28c",
"npmPackage": "jsc-android",
"pkgRevisionPrefixes": ["28.2."],
"buildSuffix": "ndk28",
"distDir": "dist-ndk28",
"distUnstrippedDir": "dist-ndk28.unstripped",
"default": true
},
{
"id": "ndk29",
"label": "Android NDK r29",
"npmPackage": "jsc-android-ndk29",
"pkgRevisionPrefixes": ["29."],
"buildSuffix": "ndk29",
"distDir": "dist-ndk29",
"distUnstrippedDir": "dist-ndk29.unstripped"
}
]
},
"devDependencies": {
"commander": "^12.1.0",
Expand Down
19 changes: 15 additions & 4 deletions scripts/compile/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ process_switch_options() {
}

if ! [[ $ROOTDIR ]]; then ROOTDIR=`pwd`; fi
source $ROOTDIR/scripts/toolchain.sh
ARCH=$JSC_ARCH

TARGETDIR=$ROOTDIR/build/target
Expand Down Expand Up @@ -101,8 +102,16 @@ DEBUG_SYMBOL_LEVEL="-g2"
if [[ "$BUILD_TYPE" = "Release" ]]
then
FRAME_POINTER_FLAG="-fomit-frame-pointer"
CFLAGS_BUILD_TYPE="-DNDEBUG -g0 -O2 -flto=thin"
ICU_CFLAGS_BUILD_TYPE="-O2 -flto=thin"
CFLAGS_BUILD_TYPE="-DNDEBUG -g0 -O2"
ICU_CFLAGS_BUILD_TYPE="-O2"
if [[ -n "$JSC_TOOLCHAIN_LTO_FLAG" ]]; then
CFLAGS_BUILD_TYPE="$CFLAGS_BUILD_TYPE $JSC_TOOLCHAIN_LTO_FLAG"
ICU_CFLAGS_BUILD_TYPE="$ICU_CFLAGS_BUILD_TYPE $JSC_TOOLCHAIN_LTO_FLAG"
fi
if [[ -n "$JSC_TOOLCHAIN_RELEASE_CFLAGS" ]]; then
CFLAGS_BUILD_TYPE="$CFLAGS_BUILD_TYPE $JSC_TOOLCHAIN_RELEASE_CFLAGS"
ICU_CFLAGS_BUILD_TYPE="$ICU_CFLAGS_BUILD_TYPE $JSC_TOOLCHAIN_RELEASE_CFLAGS"
fi
else
FRAME_POINTER_FLAG="-fno-omit-frame-pointer"
CFLAGS_BUILD_TYPE=""
Expand All @@ -117,9 +126,12 @@ COMMON_LDFLAGS=" \
-Wl,--exclude-libs,libgcc.a \
-Wl,--no-undefined \
-Wl,-z,max-page-size=16384 \
-flto=thin \
"

if [[ "$BUILD_TYPE" = "Release" && -n "$JSC_TOOLCHAIN_RELEASE_LDFLAGS" ]]; then
COMMON_LDFLAGS="$COMMON_LDFLAGS $JSC_TOOLCHAIN_RELEASE_LDFLAGS"
fi

COMMON_CFLAGS=" \
-fstack-protector \
-ffunction-sections \
Expand All @@ -132,7 +144,6 @@ $FRAME_POINTER_FLAG \
-DCUSTOMIZE_REACT_NATIVE \
$SWITCH_COMMON_CFLAGS_INTL \
$CFLAGS_BUILD_TYPE \
-Wno-pass-failed=loop-vectorize \
-D__ANDROID_MIN_SDK_VERSION__=${ANDROID_API} \
"

Expand Down
13 changes: 9 additions & 4 deletions scripts/env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@

export ROOTDIR=$PWD

BUILD_VARIANT_SUFFIX=""
if [[ -n "$JSC_BUILD_VARIANT" ]]; then
BUILD_VARIANT_SUFFIX="-$JSC_BUILD_VARIANT"
fi

# Intermediated build target dir
export TARGETDIR=$ROOTDIR/build/target
export TARGETDIR=${TARGETDIR:-$ROOTDIR/build/target${BUILD_VARIANT_SUFFIX}}

# JSC shared library install dir
export INSTALL_DIR=$ROOTDIR/build/compiled
export INSTALL_DIR=${INSTALL_DIR:-$ROOTDIR/build/compiled${BUILD_VARIANT_SUFFIX}}

# JSC unstripped shared library install dir
export INSTALL_UNSTRIPPED_DIR=$ROOTDIR/build/compiled.unstripped
export INSTALL_UNSTRIPPED_DIR=${INSTALL_UNSTRIPPED_DIR:-$ROOTDIR/build/compiled.unstripped${BUILD_VARIANT_SUFFIX}}

# CPP runtime shared library install dir
export INSTALL_CPPRUNTIME_DIR=$ROOTDIR/build/cppruntime
export INSTALL_CPPRUNTIME_DIR=${INSTALL_CPPRUNTIME_DIR:-$ROOTDIR/build/cppruntime${BUILD_VARIANT_SUFFIX}}

# Install dir for i18n build variants
export INSTALL_DIR_I18N_true=$INSTALL_DIR/intl
Expand Down
10 changes: 10 additions & 0 deletions scripts/info.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ ROOTDIR=$PWD
WEBKIT_REPO="${npm_package_config_bunWebKitRepo:-https://github.com/oven-sh/WebKit.git}"
WEBKIT_COMMIT="${npm_package_config_bunWebKitCommit}"

export JSC_TOOLCHAIN_SUPPRESS_LOG=1
source $ROOTDIR/scripts/toolchain.sh
unset JSC_TOOLCHAIN_SUPPRESS_LOG

export REVISION=$(node -e "console.log(require('./package.json').version.split('.')[0])")
CONFIG=$(node -e "console.log(JSON.stringify(require('$ROOTDIR/package.json').config, null, 2))")

Expand All @@ -27,5 +31,11 @@ printf "\n\n\n\n\n\t\t\tRevision: \x1B[32m$REVISION\x1B[0m\n\n\n"
printf "WebKit repository:\n%s @ %s\n\n" "$WEBKIT_REPO" "${WEBKIT_COMMIT:-unknown}"
printf "Upstream URL:\n%s\n\n" "$WEBKIT_URL"
printf "Config:\n%s\n\n" "$CONFIG"
printf "NDK variant: %s\n" "${JSC_TOOLCHAIN_VARIANT:-unknown}"
if [[ -n "$JSC_TOOLCHAIN_NDK_REVISION" ]]; then
printf "NDK revision: %s\n\n" "$JSC_TOOLCHAIN_NDK_REVISION"
else
printf "\n"
fi
printf "AppleWebKit version components:\n%s\n\n" "$APPLE_VERSION"
printf "Size:\n$SIZE\n\n"
120 changes: 89 additions & 31 deletions scripts/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ const path = require('path');
const rimraf = require('rimraf');
const semver = require('semver');

if (!semver.satisfies(process.versions.node, '>= 10.12.0')) {
console.log('Please execute this script with node version >= 10.12.0');
if (!semver.satisfies(process.versions.node, '>= 16.7.0')) {
console.log('Please execute this script with node version >= 16.7.0');
process.exit(1);
}

Expand All @@ -23,49 +23,94 @@ commander

const artifactZipFile = verifyFile(commander.args[0], '<artifact_zip_file>');
const rootDir = path.dirname(__dirname);
const pkgJsonPath = path.join(rootDir, 'package.json');
const packageTemplate = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'));
const workDir = path.join(rootDir, 'build', 'publish');
const distDir = path.join(rootDir, 'dist');

if (fs.existsSync(workDir)) {
rimraf.sync(workDir);
}
fs.mkdirSync(workDir, {recursive: true});

child_process.execFileSync('unzip', [artifactZipFile, '-d', workDir]);

// Publish standard package
console.log('\n\n========== Publish standard package ==========');
createPatchedContext(rootDir, '', () => {
if (fs.existsSync(distDir)) {
rimraf.sync(distDir);
}
fs.renameSync(path.join(workDir, 'dist'), distDir);
const publishArgs = ['publish', '--tag', commander.tag];
if (commander.dryRun) {
publishArgs.push('--dry-run');
}
child_process.execFileSync('npm', publishArgs);
});
const variantList = Array.isArray(packageTemplate.config?.ndkVariants)
? packageTemplate.config.ndkVariants
: [];

// Publish unstripped package
// 1. Add suffix in version, e.g. 245459.0.0-unstripped
// 2. Add suffix in tag, e.g. latest-unstripped
// 3. Get unstripped distribution from dist.unstripped/ in CI archive.zip
console.log('\n\n========== Publish unstripped package ==========');
createPatchedContext(rootDir, 'unstripped', () => {
if (fs.existsSync(distDir)) {
rimraf.sync(distDir);
}
fs.renameSync(path.join(workDir, 'dist.unstripped'), distDir);
const publishArgs = ['publish', '--tag', `${commander.tag}-unstripped`];
if (commander.dryRun) {
publishArgs.push('--dry-run');
}
child_process.execFileSync('npm', publishArgs);
const variants =
variantList.length > 0
? [...variantList].sort((a, b) => {
const aDefault = a && a.default ? 1 : 0;
const bDefault = b && b.default ? 1 : 0;
return bDefault - aDefault;
})
: [
{
id: 'default',
npmPackage: packageTemplate.name,
distDir: 'dist',
distUnstrippedDir: 'dist.unstripped',
},
];

variants.forEach((variant) => {
publishVariant(variant);
});

// ---------------------------------------------------------------------------
// Helper functions
// ---------------------------------------------------------------------------
function publishVariant(variant) {
const displayName = variant?.id || 'default';
console.log(`\n\n========== Publish ${displayName} package ==========`); // eslint-disable-line no-console

publishVariantFlavor(variant, {
sourceDirName: variant.distDir || 'dist',
versionSuffix: '',
tagSuffix: '',
});

publishVariantFlavor(variant, {
sourceDirName: variant.distUnstrippedDir || 'dist.unstripped',
versionSuffix: 'unstripped',
tagSuffix: '-unstripped',
});
}

function publishVariantFlavor(variant, {sourceDirName, versionSuffix, tagSuffix}) {
if (!sourceDirName) {
return;
}

const sourceDir = path.join(workDir, sourceDirName);
if (!fs.existsSync(sourceDir)) {
console.warn(
`Skipping ${variant?.id || 'default'}${tagSuffix ? ` (${tagSuffix.replace('-', '')})` : ''} - missing directory ${sourceDirName}`,
);
return;
}

createPatchedContext(rootDir, {variant, versionSuffix}, () => {
if (fs.existsSync(distDir)) {
rimraf.sync(distDir);
}
copyDir(sourceDir, distDir);
const publishTag = tagSuffix ? `${commander.tag}${tagSuffix}` : commander.tag;
const publishArgs = ['publish', '--tag', publishTag];
if (commander.dryRun) {
publishArgs.push('--dry-run');
}
child_process.execFileSync('npm', publishArgs, {stdio: 'inherit'});
});
}

function copyDir(source, destination) {
fs.mkdirSync(path.dirname(destination), {recursive: true});
fs.cpSync(source, destination, {recursive: true, force: true});
}

function verifyFile(filePath, argName) {
if (filePath == null) {
console.error(`Error: ${argName} is required`);
Expand All @@ -88,12 +133,25 @@ function verifyFile(filePath, argName) {
return filePath;
}

function createPatchedContext(rootDir, versionSuffix, wrappedRunner) {
function createPatchedContext(rootDir, options, wrappedRunner) {
const {versionSuffix, variant} = options || {};
const configPath = path.join(rootDir, 'package.json');
const origConfig = fs.readFileSync(configPath);

function enter() {
const patchedConfig = JSON.parse(origConfig);
if (variant) {
if (variant.npmPackage) {
patchedConfig.name = variant.npmPackage;
}
patchedConfig.config = patchedConfig.config || {};
if (variant.id) {
patchedConfig.config.selectedNdkVariant = variant.id;
}
if (variant.npmPackage) {
patchedConfig.config.selectedNdkPackage = variant.npmPackage;
}
}
if (versionSuffix) {
patchedConfig.version += '-' + versionSuffix;
}
Expand Down
50 changes: 35 additions & 15 deletions scripts/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ if [[ -z "$ANDROID_NDK" || ! -d "$ANDROID_NDK" ]]; then
export ANDROID_NDK="$DEFAULT_ANDROID_NDK"
fi

export JSC_TOOLCHAIN_SUPPRESS_LOG=1
source $ROOTDIR/scripts/toolchain.sh
unset JSC_TOOLCHAIN_SUPPRESS_LOG

if [[ -z "$JAVA_HOME" || ! -x "$JAVA_HOME/bin/java" ]]; then
if [[ "$(uname -s)" == "Darwin" ]]; then
if command -v brew >/dev/null 2>&1; then
Expand All @@ -37,6 +41,17 @@ export JSC_VERSION=${npm_package_version}
export BUILD_TYPE=Release
# export BUILD_TYPE=Debug

STRIPPED_DIST_DIR=${JSC_DIST_DIR:-${ROOTDIR}/dist-ndk28}
UNSTRIPPED_DIST_DIR=${JSC_DIST_UNSTRIPPED_DIR:-${ROOTDIR}/dist-ndk28.unstripped}

printf "Building with Android NDK variant: %s\n" "${JSC_TOOLCHAIN_VARIANT}"
if [[ -n "$JSC_TOOLCHAIN_NDK_REVISION" ]]; then
printf "Detected Android NDK revision: %s\n" "${JSC_TOOLCHAIN_NDK_REVISION}"
fi
printf "Using distribution directories:\n"
printf " stripped : %s\n" "$STRIPPED_DIST_DIR"
printf " unstripped : %s\n" "$UNSTRIPPED_DIST_DIR"

SCRIPT_DIR=$(cd `dirname $0`; pwd)

patchAndMakeICU() {
Expand All @@ -55,23 +70,28 @@ patchAndMakeICU() {

if [[ "$BUILD_TYPE" = "Release" ]]
then
local LTO_FLAG
local EXTRA_FLAGS=""
local opt_flags="-O2"
local lto_flag=""
if [[ $HAS_CLANG -eq 1 ]]; then
LTO_FLAG="-flto=thin"
EXTRA_FLAGS="-Wno-pass-failed=loop-vectorize"
else
LTO_FLAG="-flto"
lto_flag="$JSC_TOOLCHAIN_LTO_FLAG"
elif [[ -n "$JSC_TOOLCHAIN_LTO_FLAG" ]]; then
lto_flag="-flto"
fi

local OPT_FLAGS="-O2 $LTO_FLAG"
if [[ -n "$EXTRA_FLAGS" ]]; then
OPT_FLAGS="$OPT_FLAGS $EXTRA_FLAGS"
if [[ -n "$lto_flag" ]]; then
opt_flags="$opt_flags $lto_flag"
fi
if [[ -n "$JSC_TOOLCHAIN_RELEASE_CFLAGS" ]]; then
opt_flags="$opt_flags $JSC_TOOLCHAIN_RELEASE_CFLAGS"
fi

CFLAGS="$OPT_FLAGS"
CXXFLAGS="-std=c++20 $OPT_FLAGS"
LDFLAGS="$LTO_FLAG"
CFLAGS="$opt_flags"
CXXFLAGS="-std=c++20 $opt_flags"

local ldflags="$JSC_TOOLCHAIN_RELEASE_LDFLAGS"
if [[ $HAS_CLANG -eq 0 && "$ldflags" == "-flto=thin" ]]; then
ldflags="-flto"
fi
LDFLAGS="$ldflags"
else
CFLAGS="-g2"
CXXFLAGS="-std=c++20"
Expand Down Expand Up @@ -180,14 +200,14 @@ if [[ "${SKIP_INTL}" != "1" ]]; then
fi

printf "\n\n\t\t===================== create stripped distributions =====================\n\n"
export DISTDIR=${ROOTDIR}/dist
export DISTDIR=${STRIPPED_DIST_DIR}
copyHeaders ${DISTDIR}
createAAR "jsc-android" ${DISTDIR} ${INSTALL_DIR_I18N_false} "false"
createAAR "jsc-android" ${DISTDIR} ${INSTALL_DIR_I18N_true} "true"
createAAR "cppruntime" ${DISTDIR} ${INSTALL_CPPRUNTIME_DIR} "false"

printf "\n\n\t\t===================== create unstripped distributions =====================\n\n"
export DISTDIR=${ROOTDIR}/dist.unstripped
export DISTDIR=${UNSTRIPPED_DIST_DIR}
copyHeaders ${DISTDIR}
createAAR "jsc-android" ${DISTDIR} ${INSTALL_UNSTRIPPED_DIR_I18N_false} "false"
createAAR "jsc-android" ${DISTDIR} ${INSTALL_UNSTRIPPED_DIR_I18N_true} "true"
Expand Down
Loading