From 34845e2ae2a0555e665742bde33352b6289bf83d Mon Sep 17 00:00:00 2001 From: Eduardo Speroni Date: Fri, 30 Oct 2026 15:36:15 -0300 Subject: [PATCH 1/4] fix(build): build libffi for arm64 Mac Catalyst build_libffi.sh had no arm64-maccatalyst slice, so the Catalyst framework's -lffi found no archive and the linker fell back to the macOS SDK's libffi.tbd: the shipped Catalyst slice links Apple's /usr/lib/libffi.dylib while the runtime compiles against our fork's headers (vector types and the fork's closure layout included). arm64 macabi has no deployment target below 14.0, so the slice gets its own minimum. --- NativeScript/lib/arm64-maccatalyst/libffi.a | Bin 0 -> 57424 bytes build_libffi.sh | 6 ++++++ 2 files changed, 6 insertions(+) create mode 100644 NativeScript/lib/arm64-maccatalyst/libffi.a diff --git a/NativeScript/lib/arm64-maccatalyst/libffi.a b/NativeScript/lib/arm64-maccatalyst/libffi.a new file mode 100644 index 0000000000000000000000000000000000000000..ab876e2f8be6389272712e4012b51ba0e2761d7b GIT binary patch literal 57424 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 Date: Fri, 30 Oct 2026 15:36:15 -0300 Subject: [PATCH 2/4] fix(metadata-generator): resolve the deployment target in Catalyst builds Xcode does not export IPHONEOS_DEPLOYMENT_TARGET to Mac Catalyst script phases, so the fallback raised KeyError and, since the phase does not fail the build, left a 0-byte metadata file. Fall back to LLVM_TARGET_TRIPLE_OS_VERSION, which Catalyst builds always carry. --- metadata-generator/build-step-metadata-generator.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/metadata-generator/build-step-metadata-generator.py b/metadata-generator/build-step-metadata-generator.py index 1acd946c9..ce21e6c2d 100755 --- a/metadata-generator/build-step-metadata-generator.py +++ b/metadata-generator/build-step-metadata-generator.py @@ -86,9 +86,11 @@ def map_and_list(func, iterable): src_root = env("SRCROOT") deployment_target_flag_name = env_or_empty("DEPLOYMENT_TARGET_CLANG_FLAG_NAME") or default_deployment_target_flag_name # Xcode does not export MACCATALYST_DEPLOYMENT_TARGET unless the project sets it, -# so fall back to the iOS deployment target rather than dying with a KeyError. +# and may not export IPHONEOS_DEPLOYMENT_TARGET to Catalyst script phases either; +# LLVM_TARGET_TRIPLE_OS_VERSION (e.g. "ios13.1") always carries the iOS version. deployment_target = env_or_none(env_or_empty("DEPLOYMENT_TARGET_CLANG_ENV_NAME") or default_deployment_target_clang_env_name) \ - or env("IPHONEOS_DEPLOYMENT_TARGET") + or env_or_none("IPHONEOS_DEPLOYMENT_TARGET") \ + or env_or_empty("LLVM_TARGET_TRIPLE_OS_VERSION").lstrip("abcdefghijklmnopqrstuvwxyz") std = env("GCC_C_LANGUAGE_STANDARD") header_search_paths = env_or_empty("HEADER_SEARCH_PATHS") header_search_paths_parsed = map_and_list((lambda s: "-I" + s), shlex.split(header_search_paths)) From 16e968bb6ed8738b617a593c108ec8fb4b11e9ea Mon Sep 17 00:00:00 2001 From: Eduardo Speroni Date: Fri, 30 Oct 2026 15:36:15 -0300 Subject: [PATCH 3/4] feat(runtime): run V8's JIT on Mac Catalyst when the process may map JIT memory Catalyst V8 now ships with Sparkplug, Maglev and TurboFan. A hardened runtime process may only map JIT memory with com.apple.security.cs.allow-jit (or allow-unsigned-executable-memory), and V8 does not fall back on its own, so before V8::Initialize the runtime probes an mmap(MAP_JIT) allocation and passes --jitless when it fails. `"ios": { "jit": false }` in the app's package.json forces the interpreter. iOS is unchanged: its V8 is lite mode, which implies --jitless. --- NativeScript/runtime/Runtime.mm | 51 +++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/NativeScript/runtime/Runtime.mm b/NativeScript/runtime/Runtime.mm index 3e15883fa..e65af254a 100644 --- a/NativeScript/runtime/Runtime.mm +++ b/NativeScript/runtime/Runtime.mm @@ -30,9 +30,14 @@ #include "IsolateWrapper.h" +#include #include #include #include +#if TARGET_OS_MACCATALYST +#include +#include +#endif #include "HttpLoader.h" #include "ModuleBinding.hpp" #include "ModuleInternalCallbacks.h" @@ -328,6 +333,42 @@ void DisposeIsolateWhenPossible(Isolate* isolate, int gateId) { return static_cast(isolate->GetData(Constants::RUNTIME_SLOT)); } +#if TARGET_OS_MACCATALYST +// Mac Catalyst ships V8 with its JIT tiers, but a hardened-runtime process may +// only map JIT memory with com.apple.security.cs.allow-jit (or +// allow-unsigned-executable-memory). V8 does not fall back on its own: without +// --jitless it dies at its first code-space allocation, so ask the kernel the +// same question V8 will. +static bool CanMapJitMemory() { + const size_t size = static_cast(getpagesize()); + void* memory = mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANON | MAP_JIT, -1, 0); + if (memory == MAP_FAILED) { + return false; + } + munmap(memory, size); + return true; +} + +// `"ios": { "jit": false }` in the app's package.json forces the interpreter; +// otherwise the JIT runs whenever the process may map JIT memory. +static bool ShouldEnableJit() { + id iosConfig = Runtime::GetAppConfigValue("ios"); + id jitValue = [iosConfig isKindOfClass:[NSDictionary class]] ? iosConfig[@"jit"] : nil; + if ([jitValue isKindOfClass:[NSNumber class]] && ![jitValue boolValue]) { + return false; + } + if (CanMapJitMemory()) { + return true; + } + if (jitValue != nil) { + Log(@"NativeScript: \"ios.jit\" is set, but this process may not map JIT memory (missing " + @"the com.apple.security.cs.allow-jit entitlement?). Running without the JIT."); + } + return false; +} +#endif + Isolate* Runtime::CreateIsolate(const IsolateLimits& limits) { if (!v8Initialized_) { // Runtime::platform_ = RuntimeConfig.IsDebug @@ -335,10 +376,14 @@ void DisposeIsolateWhenPossible(Isolate* isolate, int gateId) { // : platform::NewDefaultPlatform(); // Flags must be set before V8::Initialize(), which freezes them; changing a - // flag afterwards aborts the process. Don't pass --jitless either: - // v8_enable_lite_mode already implies it and makes the flag read-only, - // which is likewise fatal to set. + // flag afterwards aborts the process. iOS V8 is built in lite mode, which + // already implies --jitless; only Mac Catalyst decides at launch. std::string flags = RuntimeConfig.IsDebug ? "--expose_gc" : "--expose_gc --no-lazy"; +#if TARGET_OS_MACCATALYST + if (!ShouldEnableJit()) { + flags += " --jitless"; + } +#endif V8::SetFlagsFromString(flags.c_str(), flags.size()); // wrap the default platform so foreground tasks ride each runtime From ffcfea6431ebd532343b10f38253ae155df1c8e2 Mon Sep 17 00:00:00 2001 From: Eduardo Speroni Date: Fri, 30 Oct 2026 15:36:17 -0300 Subject: [PATCH 4/4] test: run the suite on Mac Catalyst with the JIT TestRunner and its dependencies now build for Mac Catalyst (arm64), ad-hoc signed with hardened runtime and allow-jit like a shipped app, and `./run_tests.sh --catalyst` runs the suite on the host Mac. A CI job does the same on macos-15. CatalystJitTests asserts that V8 holds executable memory there, which it maps only with its JIT on. The UI-testing runner needs macOS Automation Mode without authentication (preconfigured on GitHub's macOS images); run_tests.sh checks for it. --- .../collect-test-diagnostics/action.yml | 16 ++++ .github/workflows/pull_request.yml | 57 ++++++++++++ TestFixtures/Functions/TNSFunctions.h | 4 + TestFixtures/Functions/TNSFunctions.m | 19 ++++ TestFixtures/NapiCoverageModule.mm | 4 +- TestFixtures/exported-symbols.txt | 1 + TestRunner/TestRunner-Catalyst.entitlements | 12 +++ TestRunner/app/tests/CatalystJitTests.js | 9 ++ TestRunner/app/tests/index.js | 3 + run_tests.sh | 87 ++++++++++++++++++- v8ios.xcodeproj/project.pbxproj | 41 +++++++-- 11 files changed, 240 insertions(+), 13 deletions(-) create mode 100644 TestRunner/TestRunner-Catalyst.entitlements create mode 100644 TestRunner/app/tests/CatalystJitTests.js diff --git a/.github/actions/collect-test-diagnostics/action.yml b/.github/actions/collect-test-diagnostics/action.yml index 49603765c..f9569678e 100644 --- a/.github/actions/collect-test-diagnostics/action.yml +++ b/.github/actions/collect-test-diagnostics/action.yml @@ -14,6 +14,11 @@ inputs: Name of the uploaded artifact. Artifact names are unique per workflow run, so jobs that can both fail in one run need distinct names. default: test-diagnostics + host-process-log: + description: > + "true" when the app ran on the host (Mac Catalyst): also save the host's + unified log for TestRunner processes. + default: "false" runs: using: composite steps: @@ -45,6 +50,17 @@ runs: else echo "No booted simulator; relying on the xcresult's captured app output." fi + if [ "${{ inputs.host-process-log }}" = "true" ]; then + echo "Collecting host unified log slice" + log show --style compact --last 45m \ + --predicate 'process CONTAINS "TestRunner"' \ + > "$DIAG/host-unified.log" 2>/dev/null & + LOG_PID=$! + ( sleep 120 && kill -9 "$LOG_PID" ) 2>/dev/null & + KILLER_PID=$! + wait "$LOG_PID" || echo "log show failed or was killed after 120s" + kill "$KILLER_PID" 2>/dev/null || true + fi echo "Collected diagnostics:" du -sh "$DIAG"/* 2>/dev/null || true - name: Upload test diagnostics diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 857c93fd1..4e35c5254 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -145,3 +145,60 @@ jobs: path: | ${{env.TEST_FOLDER}}/test_results.xcresult ${{env.TEST_FOLDER}}/test_results_attempt1.xcresult + test-catalyst: + name: Test (Mac Catalyst) + runs-on: macos-15 + needs: build + steps: + - uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1.7.0 + with: + xcode-version: ${{env.XCODE_VERSION}} + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + submodules: true + persist-credentials: false # disable to prevent leaking credentials to build scripts + - name: LLVM cache + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ./llvm + key: ${{ hashFiles('download_llvm.sh') }} + - uses: ./.github/actions/setup-build-env + with: + install-test-tools: "true" + - name: Prepare test folder + run: echo TEST_FOLDER=$(pwd)/build/tests/catalyst >> $GITHUB_ENV + - name: Xcode Tests + uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0 + with: + timeout_minutes: 40 + max_attempts: 2 + command: ./run_tests.sh --catalyst + # run_tests.sh empties its results folder, so move the failed + # attempt's bundle out of it first. + on_retry_command: rm -rf $TEST_FOLDER-attempt1; mv $TEST_FOLDER $TEST_FOLDER-attempt1 2>/dev/null || true + - name: Test report summary + if: ${{ !cancelled() }} + uses: mikepenz/action-junit-report@a9170d5795813c01ab4901ffb045b52bab4ab09d # v6.5.0 + with: + report_paths: build/tests/catalyst/test-out/*junit*.xml + annotate_only: true + detailed_summary: true + - name: Validate Test Results + run: | + find $TEST_FOLDER/test-out -name "*junit*.xml" -maxdepth 1 -print0 | xargs -n 1 -0 npx junit-cli-report-viewer + find $TEST_FOLDER/test-out -name "*junit*.xml" -maxdepth 1 -print0 | xargs -n 1 -0 npx verify-junit-xml + - name: Collect test diagnostics + if: failure() + uses: ./.github/actions/collect-test-diagnostics + with: + test-folder: ${{env.TEST_FOLDER}} + artifact-name: test-diagnostics-catalyst + host-process-log: "true" + - name: Archive Test Result Data + if: always() + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + name: test-results-catalyst + path: | + ${{env.TEST_FOLDER}}/test_results.xcresult + ${{env.TEST_FOLDER}}-attempt1/test_results.xcresult diff --git a/TestFixtures/Functions/TNSFunctions.h b/TestFixtures/Functions/TNSFunctions.h index dba6339d8..1282453c3 100644 --- a/TestFixtures/Functions/TNSFunctions.h +++ b/TestFixtures/Functions/TNSFunctions.h @@ -3,3 +3,7 @@ CFArrayRef CFArrayCreateWithString(CFStringRef string); // Declared for the metadata generator but intentionally left undefined, so the // symbol is listed in metadata yet absent at runtime. void TNSFunctionMissingAtRuntime(void); + +// Whether the process holds executable memory carrying V8's VM tag (255). +// V8 maps executable memory only when its JIT is on. +bool TNSHasExecutableV8Memory(void); diff --git a/TestFixtures/Functions/TNSFunctions.m b/TestFixtures/Functions/TNSFunctions.m index 0977578ab..c2a639a3d 100644 --- a/TestFixtures/Functions/TNSFunctions.m +++ b/TestFixtures/Functions/TNSFunctions.m @@ -1,4 +1,23 @@ #import "TNSFunctions.h" +#include + +bool TNSHasExecutableV8Memory(void) { + vm_address_t address = 0; + for (;;) { + vm_size_t size = 0; + natural_t depth = 0; + struct vm_region_submap_info_64 info; + mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64; + if (vm_region_recurse_64(mach_task_self(), &address, &size, &depth, + (vm_region_recurse_info_t)&info, &count) != KERN_SUCCESS) { + return false; + } + if (info.user_tag == 255 && (info.protection & VM_PROT_EXECUTE)) { + return true; + } + address += size; + } +} CFArrayRef CFArrayCreateWithString(CFStringRef string) { const void* values[] = { string }; diff --git a/TestFixtures/NapiCoverageModule.mm b/TestFixtures/NapiCoverageModule.mm index 45fd11eaf..a5d5832b5 100644 --- a/TestFixtures/NapiCoverageModule.mm +++ b/TestFixtures/NapiCoverageModule.mm @@ -157,7 +157,7 @@ static napi_value StringStatus(napi_env env, napi_callback_info info) { //=== Numbers ============================================================== -static napi_value NumberParts(napi_env env, napi_callback_info info) { +static napi_value NumberPartsMethod(napi_env env, napi_callback_info info) { size_t argc = 1; napi_value args[1]; NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL)); @@ -1345,7 +1345,7 @@ static napi_value InitNapiCoverageModule(napi_env env, napi_value exports) { NAPI_METHOD("copyString", CopyString), NAPI_METHOD("createStrings", CreateStrings), NAPI_METHOD("stringStatus", StringStatus), - NAPI_METHOD("numberParts", NumberParts), + NAPI_METHOD("numberParts", NumberPartsMethod), NAPI_METHOD("createNumbers", CreateNumbers), NAPI_METHOD("numberStatus", NumberStatus), NAPI_METHOD("createSymbol", CreateSymbol), diff --git a/TestFixtures/exported-symbols.txt b/TestFixtures/exported-symbols.txt index 9a915ec8e..a7060ed5c 100644 --- a/TestFixtures/exported-symbols.txt +++ b/TestFixtures/exported-symbols.txt @@ -1,4 +1,5 @@ _CFArrayCreateWithString +_TNSHasExecutableV8Memory _functionExplicitCreateNSObject _functionImplicitCreate _functionReturningFunctionPtrAsVoidPtr diff --git a/TestRunner/TestRunner-Catalyst.entitlements b/TestRunner/TestRunner-Catalyst.entitlements new file mode 100644 index 000000000..005a379fb --- /dev/null +++ b/TestRunner/TestRunner-Catalyst.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.cs.allow-jit + + + com.apple.security.cs.disable-library-validation + + + diff --git a/TestRunner/app/tests/CatalystJitTests.js b/TestRunner/app/tests/CatalystJitTests.js new file mode 100644 index 000000000..aa4caaf1d --- /dev/null +++ b/TestRunner/app/tests/CatalystJitTests.js @@ -0,0 +1,9 @@ +// TestRunner's Catalyst build is signed with com.apple.security.cs.allow-jit, +// so the runtime must leave V8's JIT on there. +if (NSProcessInfo.processInfo.macCatalystApp) { + describe("Mac Catalyst JIT", function () { + it("runs V8 with its JIT when the process may map JIT memory", function () { + expect(TNSHasExecutableV8Memory()).toBe(true); + }); + }); +} diff --git a/TestRunner/app/tests/index.js b/TestRunner/app/tests/index.js index c8d657702..e535e5a29 100644 --- a/TestRunner/app/tests/index.js +++ b/TestRunner/app/tests/index.js @@ -209,6 +209,9 @@ require("./WorkerTerminateTests"); // interop.setExternalSize and the runtime's own external memory charges require("./ExternalMemoryTests"); +// The runtime's launch-time JIT decision on Mac Catalyst +require("./CatalystJitTests"); + // Tests common for all runtimes (git submodule of NativeScript/common-runtime-tests-app). require("../shared/index").runAllTests(); diff --git a/run_tests.sh b/run_tests.sh index d54644e59..e8c719adf 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -266,13 +266,17 @@ usage() { cat < Existing simulator by name (e.g. 'iPhone 16 Pro') -u, --udid Existing simulator by UDID --temp-sim Create a throwaway ${SIM_PREFIX}* simulator for this run and delete it afterwards --keep-sim Run on ${SIM_PREFIX}, creating and booting it if needed, and leave it booted for later runs + --catalyst Build TestRunner for Mac Catalyst and run the suite on this + Mac (hardened runtime, ad-hoc signed, allow-jit entitlement). + Cannot be combined with any simulator option. Only one + Catalyst run per Mac at a time: later ones wait for it. Simulator management (no tests run): --create-sim Create and boot ${SIM_PREFIX}, print its UDID, exit @@ -294,7 +298,8 @@ Run options: -t, --temp-folder Write results to a random temp folder instead of build/tests/ -h, --help Show this help -Results go to build/tests/ (one simulator can only run one suite at a time). +Results go to build/tests/ (one simulator can only run one suite at a time), +or build/tests/catalyst with --catalyst. EOF } @@ -314,6 +319,7 @@ SIM_DEVICE_TYPE="" SIM_RUNTIME="" DELETE_TARGET="" TEST_FOLDER="" +CATALYST=0 set_sim_mode() { if [ -n "$SIM_MODE" ] && [ "$SIM_MODE" != "$1" ]; then @@ -360,6 +366,7 @@ while [ $# -gt 0 ]; do set_sim_mode "delete-sim"; shift "$OPT_SHIFT" ;; --list-sims) set_sim_mode "list-sims"; shift ;; --delete-sims) set_sim_mode "delete-sims"; shift ;; + --catalyst) CATALYST=1; shift ;; -a|--asan) ASAN=1; shift ;; -t|--temp-folder) TEMP_FOLDER=1; shift ;; -h|--help) usage; exit 0 ;; @@ -367,6 +374,25 @@ while [ $# -gt 0 ]; do esac done +if [ "$CATALYST" -eq 1 ]; then + if [ -n "$SIM_MODE" ] || [ -n "$DEVICE_NAME" ] || [ -n "$DEVICE_UDID" ] || [ -n "$SIM_NAME" ] \ + || [ -n "$SIM_DEVICE_TYPE" ] || [ -n "$SIM_RUNTIME" ]; then + die_usage "--catalyst runs on this Mac and cannot be combined with simulator options." + fi + # TestRunner's Catalyst build is arm64-only (EXCLUDED_ARCHS[sdk=macosx*]). + if [ "$(uname -m)" != "arm64" ]; then + echo "--catalyst needs an Apple Silicon Mac." >&2 + exit 1 + fi + # TestRunnerTests is a UI-testing bundle; on macOS its runner must switch the + # session into Automation Mode, which otherwise asks for an admin password and + # times out unattended. GitHub's macOS runner images come preconfigured. + if ! automationmodetool 2>/dev/null | grep -q "DOES NOT REQUIRE"; then + echo "--catalyst needs Automation Mode without authentication. Enable it once with:" >&2 + echo " sudo automationmodetool enable-automationmode-without-authentication" >&2 + exit 1 + fi +fi if [ -n "$SIM_MODE" ] && { [ -n "$DEVICE_NAME" ] || [ -n "$DEVICE_UDID" ]; }; then die_usage "--$SIM_MODE cannot be combined with --device or --udid." fi @@ -402,6 +428,12 @@ for devices in json.load(sys.stdin)['devices'].values(): # always say which simulator was used and whether it still exists. finish_run() { local status=$? + if [ "$CATALYST" -eq 1 ]; then + release_catalyst_lock + [ -n "$TEST_FOLDER" ] && echo "Test folder: $TEST_FOLDER" + echo "Simulator: none (--catalyst ran on this Mac)" + exit "$status" + fi [ -n "$DEVICE_UDID" ] || exit "$status" local label disposition label=$(sim_label "$DEVICE_UDID") @@ -425,7 +457,48 @@ finish_run() { exit "$status" } +# XCUIApplication.launch() terminates any running app with the same bundle +# identifier, so concurrent Catalyst runs from different checkouts would kill +# each other's TestRunner. Serialize them per user with a mkdir lock. +CATALYST_LOCK="${TMPDIR:-/tmp}/ns-test-catalyst.lock" +CATALYST_LOCK_HELD=0 + +acquire_catalyst_lock() { + local waited=0 holder + until mkdir "$CATALYST_LOCK" 2>/dev/null; do + holder=$(cat "$CATALYST_LOCK/pid" 2>/dev/null) + if [ -n "$holder" ] && ! kill -0 "$holder" 2>/dev/null; then + echo "Removing stale Catalyst run lock (pid $holder is gone)." >&2 + rm -rf "$CATALYST_LOCK" + continue + fi + if [ "$waited" -eq 0 ]; then + echo "Another --catalyst run (pid ${holder:-unknown}) is in progress; waiting for it to finish..." >&2 + waited=1 + fi + sleep 10 + done + echo $$ > "$CATALYST_LOCK/pid" + CATALYST_LOCK_HELD=1 +} + +release_catalyst_lock() { + if [ "$CATALYST_LOCK_HELD" -eq 1 ]; then + rm -rf "$CATALYST_LOCK" + CATALYST_LOCK_HELD=0 + fi +} + +if [ "$CATALYST" -eq 1 ]; then + SIM_MODE="catalyst" +fi + case "$SIM_MODE" in + catalyst) + trap finish_run EXIT + trap 'exit 130' INT TERM + acquire_catalyst_lock + ;; list-sims) print_temp_sims exit $? @@ -466,13 +539,19 @@ esac trap finish_run EXIT trap 'exit 130' INT TERM -DESTINATION="platform=iOS Simulator,id=$DEVICE_UDID" +if [ "$CATALYST" -eq 1 ]; then + DESTINATION="platform=macOS,variant=Mac Catalyst,arch=arm64" + RESULTS_NAME="catalyst" +else + DESTINATION="platform=iOS Simulator,id=$DEVICE_UDID" + RESULTS_NAME="$DEVICE_UDID" +fi mkdir -p "$TESTS_ROOT" if [ "$TEMP_FOLDER" -eq 1 ]; then TEST_FOLDER=$(mktemp -d "$TESTS_ROOT/tmp.XXXXXXXX") else - TEST_FOLDER="$TESTS_ROOT/$DEVICE_UDID" + TEST_FOLDER="$TESTS_ROOT/$RESULTS_NAME" rm -rf "$TEST_FOLDER" mkdir -p "$TEST_FOLDER" fi diff --git a/v8ios.xcodeproj/project.pbxproj b/v8ios.xcodeproj/project.pbxproj index 40102693c..f6f7d968f 100644 --- a/v8ios.xcodeproj/project.pbxproj +++ b/v8ios.xcodeproj/project.pbxproj @@ -78,8 +78,8 @@ C22536B6241A318900192740 /* ffi.h in Headers */ = {isa = PBXBuildFile; fileRef = C22536B1241A318900192740 /* ffi.h */; }; C22536B7241A318900192740 /* ffitarget.h in Headers */ = {isa = PBXBuildFile; fileRef = C22536B3241A318900192740 /* ffitarget.h */; }; C22536B8241A318900192740 /* ffi.h in Headers */ = {isa = PBXBuildFile; fileRef = C22536B4241A318900192740 /* ffi.h */; }; - C2253789241A41C500192740 /* TKLiveSync.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C2253782241A41C500192740 /* TKLiveSync.framework */; platformFilters = (ios, xros, ); }; - C225378A241A41C500192740 /* TKLiveSync.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C2253782241A41C500192740 /* TKLiveSync.framework */; platformFilters = (ios, xros, ); settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + C2253789241A41C500192740 /* TKLiveSync.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C2253782241A41C500192740 /* TKLiveSync.framework */; platformFilters = (ios, maccatalyst, xros, ); }; + C225378A241A41C500192740 /* TKLiveSync.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C2253782241A41C500192740 /* TKLiveSync.framework */; platformFilters = (ios, maccatalyst, xros, ); settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; C2253790241A421E00192740 /* zip_fopen_index_encrypted.c in Sources */ = {isa = PBXBuildFile; fileRef = C2A5E05A2328CA6F00A91A76 /* zip_fopen_index_encrypted.c */; }; C2253791241A422400192740 /* zip_get_num_entries.c in Sources */ = {isa = PBXBuildFile; fileRef = C2A5E0422328CA6F00A91A76 /* zip_get_num_entries.c */; }; C2253805241A5C3200192740 /* zip_get_encryption_implementation.c in Sources */ = {isa = PBXBuildFile; fileRef = C2A5E0302328CA6F00A91A76 /* zip_get_encryption_implementation.c */; }; @@ -254,8 +254,8 @@ C2A6EF3123745A0B00E8FBE7 /* MetadataInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = C2A6EF3023745A0B00E8FBE7 /* MetadataInlines.h */; }; C2C8EE7222CE323C001F8CEC /* ConcurrentMap.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C8EE7022CE323C001F8CEC /* ConcurrentMap.h */; }; C2C8EE7422CE3266001F8CEC /* ConcurrentQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2C8EE7322CE3266001F8CEC /* ConcurrentQueue.cpp */; }; - C2C8EE7522CE54EE001F8CEC /* NativeScript.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C2DDEB32229EAB3B00345BFE /* NativeScript.framework */; platformFilters = (ios, xros, ); }; - C2C8EE7622CE54EE001F8CEC /* NativeScript.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C2DDEB32229EAB3B00345BFE /* NativeScript.framework */; platformFilters = (ios, xros, ); settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + C2C8EE7522CE54EE001F8CEC /* NativeScript.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C2DDEB32229EAB3B00345BFE /* NativeScript.framework */; platformFilters = (ios, maccatalyst, xros, ); }; + C2C8EE7622CE54EE001F8CEC /* NativeScript.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C2DDEB32229EAB3B00345BFE /* NativeScript.framework */; platformFilters = (ios, maccatalyst, xros, ); settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; C2C8EE7A22CF64E4001F8CEC /* SimpleAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2C8EE7822CF64E4001F8CEC /* SimpleAllocator.cpp */; }; C2C8EE7B22CF64E4001F8CEC /* SimpleAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C8EE7922CF64E4001F8CEC /* SimpleAllocator.h */; }; C2CC8EEA22BBA01E00B78928 /* FastEnumerationAdapter.mm in Sources */ = {isa = PBXBuildFile; fileRef = C2CC8EE822BBA01E00B78928 /* FastEnumerationAdapter.mm */; }; @@ -2122,7 +2122,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "cd ${PROJECT_DIR}/metadata-generator/build/bin\ncp ../../build-step-metadata-generator.py .\n./build-step-metadata-generator.py\n\n# create temporary empty metadata files for XCode LD/LDPLUSPLUS flag analysis\nfor arch in $VALID_ARCHS\ndo :\n echo \"creating empty $CONFIGURATION_BUILD_DIR/metadata-$arch.bin\"\n touch \"$CONFIGURATION_BUILD_DIR/metadata-$arch.bin\"\ndone\n"; + shellScript = "set -e\ncd ${PROJECT_DIR}/metadata-generator/build/bin\ncp ../../build-step-metadata-generator.py .\n./build-step-metadata-generator.py\n\n# create temporary empty metadata files for XCode LD/LDPLUSPLUS flag analysis\nfor arch in $VALID_ARCHS\ndo :\n echo \"creating empty $CONFIGURATION_BUILD_DIR/metadata-$arch.bin\"\n touch \"$CONFIGURATION_BUILD_DIR/metadata-$arch.bin\"\ndone\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -2413,6 +2413,7 @@ isa = PBXTargetDependency; platformFilters = ( ios, + maccatalyst, xros, ); target = C2253781241A41C500192740 /* TKLiveSync */; @@ -2422,6 +2423,7 @@ isa = PBXTargetDependency; platformFilters = ( ios, + maccatalyst, xros, ); target = C2DDEB31229EAB3B00345BFE /* NativeScript */; @@ -2447,6 +2449,7 @@ isa = PBXTargetDependency; platformFilters = ( ios, + maccatalyst, xros, ); target = C29374E1229FC0F60075CB16 /* TestFixtures */; @@ -2545,7 +2548,9 @@ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CLANG_ENABLE_MODULES = NO; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; + "ENABLE_HARDENED_RUNTIME[sdk=macosx*]" = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", @@ -2556,12 +2561,15 @@ "$(inherited)", "@executable_path/Frameworks", ); + MACOSX_DEPLOYMENT_TARGET = 10.15; PRODUCT_BUNDLE_IDENTIFIER = org.nativescript.TestRunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTS_MACCATALYST = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; + "TARGETED_DEVICE_FAMILY[sdk=macosx*]" = 2; TEST_TARGET_NAME = TestRunner; }; name = Debug; @@ -2572,7 +2580,9 @@ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CLANG_ENABLE_MODULES = NO; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; + "ENABLE_HARDENED_RUNTIME[sdk=macosx*]" = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", @@ -2583,12 +2593,15 @@ "$(inherited)", "@executable_path/Frameworks", ); + MACOSX_DEPLOYMENT_TARGET = 10.15; PRODUCT_BUNDLE_IDENTIFIER = org.nativescript.TestRunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTS_MACCATALYST = YES; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; + "TARGETED_DEVICE_FAMILY[sdk=macosx*]" = 2; TEST_TARGET_NAME = TestRunner; }; name = Release; @@ -2807,6 +2820,7 @@ OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; + SUPPORTS_MACCATALYST = YES; SYMROOT = build; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -2830,6 +2844,7 @@ OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; + SUPPORTS_MACCATALYST = YES; SYMROOT = build; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -2841,10 +2856,15 @@ CLANG_CXX_LANGUAGE_STANDARD = "c++20"; CLANG_CXX_LIBRARY = "compiler-default"; CLANG_ENABLE_MODULES = NO; + "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "TestRunner/TestRunner-Catalyst.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = CS838V553Y; + "DEVELOPMENT_TEAM[sdk=macosx*]" = ""; + "ENABLE_HARDENED_RUNTIME[sdk=macosx*]" = YES; EXCLUDED_ARCHS = ""; + "EXCLUDED_ARCHS[sdk=macosx*]" = x86_64; EXPORTED_SYMBOLS_FILE = "$(PROJECT_DIR)/TestFixtures/exported-symbols.txt"; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -2883,10 +2903,11 @@ SDKROOT = iphoneos; STRIPFLAGS = "-s $(PROJECT_DIR)/TestFixtures/exported-symbols.txt"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; - SUPPORTS_MACCATALYST = NO; + SUPPORTS_MACCATALYST = YES; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; TARGETED_DEVICE_FAMILY = "1,7"; + "TARGETED_DEVICE_FAMILY[sdk=macosx*]" = 2; USER_HEADER_SEARCH_PATHS = ""; }; name = Debug; @@ -2897,10 +2918,15 @@ CLANG_CXX_LANGUAGE_STANDARD = "c++20"; CLANG_CXX_LIBRARY = "compiler-default"; CLANG_ENABLE_MODULES = NO; + "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "TestRunner/TestRunner-Catalyst.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = 8V7T28DG39; + "DEVELOPMENT_TEAM[sdk=macosx*]" = ""; + "ENABLE_HARDENED_RUNTIME[sdk=macosx*]" = YES; EXCLUDED_ARCHS = ""; + "EXCLUDED_ARCHS[sdk=macosx*]" = x86_64; EXPORTED_SYMBOLS_FILE = "$(PROJECT_DIR)/TestFixtures/exported-symbols.txt"; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -2939,10 +2965,11 @@ SDKROOT = iphoneos; STRIPFLAGS = "-s $(PROJECT_DIR)/TestFixtures/exported-symbols.txt"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; - SUPPORTS_MACCATALYST = NO; + SUPPORTS_MACCATALYST = YES; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; TARGETED_DEVICE_FAMILY = "1,7"; + "TARGETED_DEVICE_FAMILY[sdk=macosx*]" = 2; USER_HEADER_SEARCH_PATHS = ""; }; name = Release;