Skip to content

Commit 5e34fec

Browse files
authored
fix: Xcode 26.4 build for runtime, inspector, and metadata-generator (#376)
1 parent 8d238ed commit 5e34fec

6 files changed

Lines changed: 64 additions & 15 deletions

File tree

NativeScript/inspector/JsV8InspectorClient.mm

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,20 @@
2222

2323
namespace v8_inspector {
2424

25+
namespace {
26+
// Build an 8-bit `StringView` directly over a `std::string`'s storage.
27+
// V8 inspector messages on this side are ASCII/UTF-8 JSON, so the
28+
// previous `std::string -> std::vector<uint16_t> -> StringView` path
29+
// inflated each byte to two and then handed it to a 16-bit constructor.
30+
// Going straight through the 8-bit constructor avoids that doubling AND
31+
// dodges the libc++ deprecation that prompted the inspector's
32+
// `UChar = uint16_t -> char16_t` switch.
33+
StringView Make8BitStringView(const std::string& value) {
34+
return StringView(reinterpret_cast<const uint8_t*>(value.data()),
35+
value.size());
36+
}
37+
} // namespace
38+
2539
#define NOTIFICATION(name) \
2640
[[NSString stringWithFormat:@"%@:NativeScript.Debug.%s", \
2741
[[NSBundle mainBundle] bundleIdentifier], name] UTF8String]
@@ -257,8 +271,7 @@
257271
}
258272

259273
void JsV8InspectorClient::dispatchMessage(const std::string& message) {
260-
std::vector<uint16_t> vector = tns::ToVector(message);
261-
StringView messageView(vector.data(), vector.size());
274+
StringView messageView = Make8BitStringView(message);
262275
Isolate* isolate = isolate_;
263276
v8::Locker locker(isolate);
264277
Isolate::Scope isolate_scope(isolate);
@@ -343,8 +356,7 @@
343356
auto returnString = GetReturnMessageFromDomainHandlerResult(result, requestId);
344357

345358
if (returnString.size() > 0) {
346-
std::vector<uint16_t> vector = tns::ToVector(returnString);
347-
StringView messageView(vector.data(), vector.size());
359+
StringView messageView = Make8BitStringView(returnString);
348360
auto msg = StringBuffer::create(messageView);
349361
this->sendNotification(std::move(msg));
350362
}
@@ -486,8 +498,7 @@
486498
Local<v8::String> arg = args[0].As<v8::String>();
487499
std::string message = tns::ToString(isolate, arg);
488500

489-
std::vector<uint16_t> vector = tns::ToVector(message);
490-
StringView messageView(vector.data(), vector.size());
501+
StringView messageView = Make8BitStringView(message);
491502
auto msg = StringBuffer::create(messageView);
492503
client->sendNotification(std::move(msg));
493504
}

NativeScript/inspector/src/inspector/string-16.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,13 @@
1717

1818
namespace v8_inspector {
1919

20-
using UChar = uint16_t;
20+
// Xcode 26.x libc++ deprecates `std::basic_string<unsigned short>`
21+
// (and any `char_traits<T>` specialization for non-standard char types).
22+
// Switch to `char16_t` so `std::basic_string<UChar>` resolves to the
23+
// fully supported `std::u16string`. The V8 inspector public API still
24+
// takes `uint16_t*`, so call sites that cross that boundary now use
25+
// `reinterpret_cast` (see string-util.h).
26+
using UChar = char16_t;
2127

2228
class String16 {
2329
public:

NativeScript/inspector/src/inspector/string-util.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,17 @@ class StringUtil {
3030
}
3131

3232
static String fromUTF16LE(const uint16_t* data, size_t length) {
33-
return String16::fromUTF16LE(data, length);
33+
// V8 inspector protocol passes `uint16_t*` over its public API but
34+
// `String16` is now backed by `std::u16string` (UChar = char16_t).
35+
// The two are bit-identical 16-bit codepoints, so a reinterpret_cast
36+
// is sound at the API boundary.
37+
return String16::fromUTF16LE(reinterpret_cast<const UChar*>(data), length);
3438
}
3539

3640
static const uint8_t* CharactersLatin1(const String& s) { return nullptr; }
3741
static const uint8_t* CharactersUTF8(const String& s) { return nullptr; }
3842
static const uint16_t* CharactersUTF16(const String& s) {
39-
return s.characters16();
43+
return reinterpret_cast<const uint16_t*>(s.characters16());
4044
}
4145
static size_t CharacterCount(const String& s) { return s.length(); }
4246
};

NativeScript/inspector/utils.mm

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,22 @@
3535
}
3636

3737
std::string v8_inspector::ToStdString(const StringView& value) {
38-
std::vector<uint16_t> buffer(value.length());
38+
// Build the std::u16string directly. The previous version went via
39+
// std::vector<uint16_t> + a copy-construct into u16string, which on
40+
// Xcode 26.x's libc++ tripped the `char_traits<unsigned short>`
41+
// deprecation through the construct-from-iterator path. Writing
42+
// char16_t straight into the destination avoids the
43+
// non-standard char-traits specialization entirely.
44+
std::u16string value16;
45+
value16.resize(value.length());
3946
for (size_t i = 0; i < value.length(); i++) {
4047
if (value.is8Bit()) {
41-
buffer[i] = value.characters8()[i];
48+
value16[i] = static_cast<char16_t>(value.characters8()[i]);
4249
} else {
43-
buffer[i] = value.characters16()[i];
50+
value16[i] = static_cast<char16_t>(value.characters16()[i]);
4451
}
4552
}
4653

47-
std::u16string value16(buffer.begin(), buffer.end());
48-
4954
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
5055
// FIXME: std::codecvt_utf8_utf16 is deprecated
5156
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;

NativeScript/v8runtime/V8Runtime.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,12 @@ std::shared_ptr<const jsi::PreparedJavaScript> V8Runtime::prepareJavaScript(
431431

432432
jsi::Value V8Runtime::evaluatePreparedJavaScript(
433433
const std::shared_ptr<const jsi::PreparedJavaScript>& js) {
434-
return evaluateJavaScript(nullptr, nullptr);
434+
// The second arg is a `std::string` sourceURL; newer Clang (Xcode 26.x)
435+
// enforces `-Wnonnull` on its non-null `const char*` constructor, so we
436+
// can no longer pass `nullptr`. Empty string is the documented "unknown
437+
// source URL" value and matches the existing `prepareJavaScript` no-op
438+
// (which already returns nullptr above).
439+
return evaluateJavaScript(nullptr, "");
435440
}
436441

437442
void V8Runtime::queueMicrotask(const jsi::Function& callback) {

metadata-generator/CMakeLists.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
cmake_minimum_required(VERSION 3.20)
22
project(MetadataGenerator)
33
include(CheckCCompilerFlag)
4+
include(CheckCXXCompilerFlag)
45

56
#set(CMAKE_VERBOSE_MAKEFILE ON)
67

@@ -36,6 +37,23 @@ if (HAS_UNUSED_BUT_SET_VARIABLE)
3637
add_compile_options(-Wno-unused-but-set-variable)
3738
endif()
3839

40+
# Newer Apple toolchains (Xcode 26.x with Clang 17+) emit two diagnostics
41+
# inside LLVM 17.0.6's own headers (e.g. `-Wunnecessary-virtual-specifier`
42+
# on `virtual void anchor()` in classes declared `final` in
43+
# `clang/AST/Decl.h`, and `-Wpreferred-type-bitfield-enum-conversion` on
44+
# bitfield-to-enum stores). These are upstream-known issues that don't
45+
# affect generator behavior. Keep `-Werror` for *our* code, but downgrade
46+
# these two to warnings so the build succeeds without bumping LLVM.
47+
check_cxx_compiler_flag(-Wno-error=preferred-type-bitfield-enum-conversion HAS_NO_ERROR_PREFERRED_TYPE_BITFIELD_ENUM_CONVERSION)
48+
if (HAS_NO_ERROR_PREFERRED_TYPE_BITFIELD_ENUM_CONVERSION)
49+
add_compile_options(-Wno-error=preferred-type-bitfield-enum-conversion)
50+
endif()
51+
52+
check_cxx_compiler_flag(-Wno-error=unnecessary-virtual-specifier HAS_NO_ERROR_UNNECESSARY_VIRTUAL_SPECIFIER)
53+
if (HAS_NO_ERROR_UNNECESSARY_VIRTUAL_SPECIFIER)
54+
add_compile_options(-Wno-error=unnecessary-virtual-specifier)
55+
endif()
56+
3957
set(LLVM_LINKER_FLAGS "${LLVM_LINKER_FLAGS} ${LLVM_SYSTEM_LIBS} ${LLVM_LIBS}")
4058

4159
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/lib)

0 commit comments

Comments
 (0)