Skip to content

Commit 82b6105

Browse files
committed
Refactor metadata generator for improved architecture handling and error reporting
1 parent 91ea884 commit 82b6105

File tree

3 files changed

+67
-19
lines changed

3 files changed

+67
-19
lines changed

metadata-generator/include/Util.h

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
#pragma once
22

33
#include <clang-c/Index.h>
4+
45
#include <algorithm>
56
#include <cctype>
6-
#include <cstring>
77
#include <cstdlib>
8+
#include <cstring>
89
#include <string>
910
#include <vector>
1011

@@ -19,24 +20,36 @@ enum class AvailabilityPlatform {
1920
XROS,
2021
};
2122

22-
inline AvailabilityPlatform gAvailabilityPlatform = AvailabilityPlatform::Unknown;
23+
inline AvailabilityPlatform gAvailabilityPlatform =
24+
AvailabilityPlatform::Unknown;
2325
inline int gAvailabilityTargetMajor = -1;
2426
inline int gAvailabilityTargetMinor = -1;
2527

26-
inline AvailabilityPlatform platformFromTargetTriple(const std::string& targetTriple) {
27-
if (targetTriple.find("macosx") != std::string::npos) return AvailabilityPlatform::MacOS;
28-
if (targetTriple.find("ios") != std::string::npos) return AvailabilityPlatform::IOS;
29-
if (targetTriple.find("tvos") != std::string::npos) return AvailabilityPlatform::TvOS;
30-
if (targetTriple.find("watchos") != std::string::npos) return AvailabilityPlatform::WatchOS;
31-
if (targetTriple.find("xros") != std::string::npos) return AvailabilityPlatform::XROS;
28+
inline AvailabilityPlatform platformFromTargetTriple(
29+
const std::string& targetTriple) {
30+
// Check 'macosx' before 'macos' to avoid partial match; also handle modern
31+
// 'macos' spelling used in triples like x86_64-apple-macos11.0.
32+
if (targetTriple.find("macosx") != std::string::npos ||
33+
targetTriple.find("macos") != std::string::npos)
34+
return AvailabilityPlatform::MacOS;
35+
if (targetTriple.find("ios") != std::string::npos)
36+
return AvailabilityPlatform::IOS;
37+
if (targetTriple.find("tvos") != std::string::npos)
38+
return AvailabilityPlatform::TvOS;
39+
if (targetTriple.find("watchos") != std::string::npos)
40+
return AvailabilityPlatform::WatchOS;
41+
if (targetTriple.find("xros") != std::string::npos)
42+
return AvailabilityPlatform::XROS;
3243
return AvailabilityPlatform::Unknown;
3344
}
3445

35-
inline bool parsePlatformVersionFromTargetTriple(const std::string& targetTriple, int& major,
36-
int& minor) {
46+
inline bool parsePlatformVersionFromTargetTriple(
47+
const std::string& targetTriple, int& major, int& minor) {
3748
size_t pos = std::string::npos;
3849
if ((pos = targetTriple.find("macosx")) != std::string::npos) {
39-
pos += 6;
50+
pos += 6; // skip "macosx"
51+
} else if ((pos = targetTriple.find("macos")) != std::string::npos) {
52+
pos += 5; // skip "macos" (modern spelling, e.g. x86_64-apple-macos11.0)
4053
} else if ((pos = targetTriple.find("watchos")) != std::string::npos) {
4154
pos += 7;
4255
} else if ((pos = targetTriple.find("tvos")) != std::string::npos) {
@@ -63,7 +76,8 @@ inline bool parsePlatformVersionFromTargetTriple(const std::string& targetTriple
6376
size_t minorStart = pos;
6477
while (pos < targetTriple.size() && std::isdigit(targetTriple[pos])) pos++;
6578
if (minorStart < pos) {
66-
minor = std::atoi(targetTriple.substr(minorStart, pos - minorStart).c_str());
79+
minor =
80+
std::atoi(targetTriple.substr(minorStart, pos - minorStart).c_str());
6781
}
6882
}
6983

@@ -148,7 +162,7 @@ inline std::vector<std::string> splitCamelCase(const std::string& value) {
148162
return result;
149163
}
150164

151-
inline std::string &rtrim(std::string &s) {
165+
inline std::string& rtrim(std::string& s) {
152166
s.erase(std::find_if(s.rbegin(), s.rend(),
153167
[](unsigned char ch) { return !std::isspace(ch); })
154168
.base(),
@@ -197,8 +211,12 @@ inline std::string getFrameworkName(CXCursor cursor) {
197211
CXSourceLocation srcloc = clang_getCursorLocation(cursor);
198212
CXFile file;
199213
clang_getFileLocation(srcloc, &file, nullptr, nullptr, nullptr);
214+
if (file == nullptr) {
215+
return "Runtime";
216+
}
200217
CXString fileName = clang_getFileName(file);
201-
std::string fileNameStr = clang_getCString(fileName);
218+
const char* fileNameCStr = clang_getCString(fileName);
219+
std::string fileNameStr = fileNameCStr ? fileNameCStr : "";
202220
clang_disposeString(fileName);
203221
auto pos = fileNameStr.find(".framework/");
204222
if (pos == std::string::npos) {
@@ -246,7 +264,8 @@ inline bool isAvailable(CXCursor cursor) {
246264
clang_disposeString(deprecatedMessage);
247265
clang_disposeString(unavailableMessage);
248266

249-
const char* wantedPlatform = platformNameForAvailability(gAvailabilityPlatform);
267+
const char* wantedPlatform =
268+
platformNameForAvailability(gAvailabilityPlatform);
250269
bool isCursorAvailableForTarget = true;
251270
for (auto& item : platformAvailability) {
252271
const char* platform = clang_getCString(item.Platform);
@@ -356,4 +375,4 @@ inline bool cursorHasReturnsRetainedAttribute(CXCursor cursor) {
356375
return search.hasAttribute;
357376
}
358377

359-
} // namespace metagen
378+
} // namespace metagen

metadata-generator/src/IR/Factory.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,12 @@ bool MetadataFactory::shouldProcess(CXCursor cursor, bool required) {
8787
CXSourceLocation srcloc = clang_getCursorLocation(cursor);
8888
CXFile file;
8989
clang_getFileLocation(srcloc, &file, nullptr, nullptr, nullptr);
90+
if (file == nullptr) {
91+
return false;
92+
}
9093
CXString fileName = clang_getFileName(file);
91-
std::string fileNameStr = clang_getCString(fileName);
94+
const char* fileNameCStr = clang_getCString(fileName);
95+
std::string fileNameStr = fileNameCStr ? fileNameCStr : "";
9296
clang_disposeString(fileName);
9397

9498
auto cached = shouldProcessCache.find(fileNameStr);

scripts/metagen.js

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,19 @@ async function main() {
130130
await fs.mkdir(typesDir, { recursive: true });
131131

132132
for (const arch of Object.keys(sdk.targets)) {
133-
const exec = path.resolve(
133+
// Use the matching arch binary when available, falling back to arm64.
134+
// build_metadata_generator.sh produces both dist/arm64 and dist/x86_64.
135+
const preferredArch = arch;
136+
const preferredExec = path.resolve(
137+
__dirname,
138+
"..",
139+
"metadata-generator",
140+
"dist",
141+
preferredArch,
142+
"bin",
143+
"objc-metadata-generator",
144+
);
145+
const fallbackExec = path.resolve(
134146
__dirname,
135147
"..",
136148
"metadata-generator",
@@ -140,6 +152,14 @@ async function main() {
140152
"objc-metadata-generator",
141153
);
142154

155+
let exec;
156+
try {
157+
await fs.access(preferredExec);
158+
exec = preferredExec;
159+
} catch {
160+
exec = fallbackExec;
161+
}
162+
143163
const args = [
144164
`types=${typesDir}`,
145165
...(sdkName === "macos"
@@ -187,7 +207,12 @@ async function main() {
187207
console.error(`Failed to generate metadata for ${sdkName} ${arch}`);
188208
console.error(`Command: ${exec} ${args.join(" ")}`);
189209
console.error(`Exit code: ${output.status}`);
190-
console.error(`Error output: ${output.stderr.toString()}`);
210+
if (output.signal) {
211+
console.error(`Killed by signal: ${output.signal}`);
212+
}
213+
if (output.error) {
214+
console.error(`Spawn error: ${output.error.message}`);
215+
}
191216
throw new Error("Failed to generate metadata");
192217
}
193218
}

0 commit comments

Comments
 (0)