Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,34 @@ jobs:
- name: Provision third-party headers
run: RNET_HEADERS_ONLY=1 node scripts/download-libs.js

# third-party/include and the ExecuTorch built below must come from the
# same release. When they drifted, `make_tensor_ptr` gaining a trailing
# `Device` parameter surfaced as an undefined reference nine minutes into
# the dependency build, blamed on whichever code happened to call it.
# Comparing the two up front fails in seconds and names both values.
# Note this only spans releases: ET_VERSION comes from the source tree's
# version.txt, so it cannot tell the fork's patches apart from upstream,
# and it says nothing about TOKENIZERS_COMMIT.
- name: Check the header and test-dependency ExecuTorch versions agree
run: |
headers=$(sed -n 's/^#define ET_VERSION "\(.*\)"$/\1/p' \
third-party/include/executorch/runtime/core/version.h)
pinned=$(sed -n 's/^EXECUTORCH_VERSION="v\(.*\)"$/\1/p' \
scripts/build-native-test-deps.sh)
if [ -z "$headers" ] || [ -z "$pinned" ]; then
echo "::error::could not read the ExecuTorch versions" \
"(headers='$headers' pinned='$pinned')"
exit 1
fi
if [ "$headers" != "$pinned" ]; then
echo "::error::third-party/include is ExecuTorch $headers but" \
"scripts/build-native-test-deps.sh pins v$pinned." \
"Bump EXECUTORCH_VERSION (and TOKENIZERS_COMMIT) to match" \
"the artifacts release."
exit 1
fi
echo "ExecuTorch $headers on both sides"

# Hermes and ExecuTorch are pinned to exact tags, so the cache only misses
# when scripts/build-native-test-deps.sh changes those pins.
#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ HERMES_REPO="https://github.com/facebook/hermes.git"
# errors or, worse, ABI drift at runtime. cpp/extensions/llm additionally reads
# private members of TextLLMRunner/MultimodalRunner, so a version skew there
# fails to compile rather than silently misbehaving.
EXECUTORCH_VERSION="v1.3.1"
EXECUTORCH_VERSION="v1.4.1"
EXECUTORCH_REPO="https://github.com/pytorch/executorch.git"

# The shipped native libraries are built from software-mansion-labs/executorch
# @rne-split-build, which is ExecuTorch 1.3.1 with the tokenizers submodule
# @ms/separate-backends-1.4.1, which is ExecuTorch 1.4.1 with the tokenizers submodule
# swapped for the fork below (it adds the WordPiece/Unigram models and the NFC
# normalizer that upstream has not taken). third-party/include carries that
# fork's headers, so linking upstream's libtokenizers.a here would compile
Expand All @@ -47,7 +47,7 @@ EXECUTORCH_REPO="https://github.com/pytorch/executorch.git"
# Keep this commit in sync with the tokenizers submodule of the fork commit that
# produced the current headers.tar.gz.
TOKENIZERS_REPO="https://github.com/software-mansion-labs/pytorch-tokenizers.git"
TOKENIZERS_COMMIT="56a30afbe2e6b4ca881d0fb7b961b9f9da156be4"
TOKENIZERS_COMMIT="a03231a20a72036bf9a8e4a3b1d63494b90da1a6"

cd "$(dirname "$0")/.."
PACKAGE_DIR="$(pwd)"
Expand Down
27 changes: 23 additions & 4 deletions packages/react-native-executorch/scripts/download-libs.js
Original file line number Diff line number Diff line change
Expand Up @@ -390,17 +390,36 @@
return result.toString().split(' ')[0].trim();
}

function isCacheValid(artifact) {
async function isCacheValid(artifact) {
if (!fs.existsSync(artifact.cacheFile)) return false;
if (!fs.existsSync(artifact.cacheChecksumFile)) return false;
// Refresh the checksum from the release before trusting the cache. Comparing
// a cached tarball against a CACHED checksum lets a stale cache validate
// itself: the cache directory is keyed on the libs version, so a release
// re-cut at the same version is never picked up -- every artifact reports a
// cache hit and the old files are reused indefinitely.
try {
await download(artifact.checksumUrl, artifact.cacheChecksumFile);
} catch {
// Unreachable checksum (offline, rate limited): fall back to the cached
// one so an already-populated cache still builds without a network.
if (!fs.existsSync(artifact.cacheChecksumFile)) return false;
}
const expectedChecksum = fs.readFileSync(artifact.cacheChecksumFile, 'utf8').trim();
const actualChecksum = sha256(artifact.cacheFile);
return expectedChecksum === actualChecksum;
}

function extract(tarball, destDir) {
ensureDir(destDir);
execSync(`tar -xzf "${tarball}" -C "${destDir}"`);
// `-m` stamps extracted files with the extraction time instead of the mtime
// recorded in the archive. Without it, headers keep the timestamp they had
// when the release was cut, so upgrading to a NEWER artifacts release can
// hand ninja headers that look OLDER than object files from a previous build.
// Ninja then treats those objects as up to date and never recompiles them,

Check warning on line 418 in packages/react-native-executorch/scripts/download-libs.js

View workflow job for this annotation

GitHub Actions / lint

Unknown word: "recompiles"
// and they get archived and linked against the new libraries -- which shows
// up as an undefined symbol for whatever API changed between the two
// releases, far away from the actual cause.
execSync(`tar -xzmf "${tarball}" -C "${destDir}"`);

Check warning on line 422 in packages/react-native-executorch/scripts/download-libs.js

View workflow job for this annotation

GitHub Actions / lint

Unknown word: "xzmf"
}

// ---- Main ------------------------------------------------------------------
Expand Down Expand Up @@ -432,7 +451,7 @@
for (const artifact of artifacts) {
console.log(`[react-native-executorch] Preparing ${artifact.name}...`);

if (isCacheValid(artifact)) {
if (await isCacheValid(artifact)) {
console.log(` ✓ Cache hit, skipping download`);
} else {
console.log(` ↓ Downloading ${artifact.url}`);
Expand Down