Skip to content

Commit 136bd9f

Browse files
committed
feat(MetadataGenerator): support including non-system frameworks
1 parent 189d451 commit 136bd9f

File tree

101 files changed

+82223
-82044
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+82223
-82044
lines changed

core-test/src/compat.js

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,6 @@ globalThis.__IOS__ = true;
55
globalThis.__VISIONOS__ = false;
66
globalThis.__dirname = NSBundle.mainBundle.bundlePath;
77

8-
function NativeScriptEmbedder() {}
9-
10-
globalThis.NativeScriptEmbedder = NativeScriptEmbedder;
11-
12-
globalThis.nativeScriptEmbedder = new NativeScriptEmbedder();
13-
14-
NativeScriptEmbedder.sharedInstance = function () {
15-
return nativeScriptEmbedder;
16-
};
17-
18-
NativeScriptEmbedder.prototype.setDelegate = function (delegate) {
19-
this.delegate = delegate;
20-
};
21-
228
WeakRef.prototype.get = function () {
239
return this.deref();
2410
};

core-test/src/index.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
11
import "./compat.js";
22
import "../core/globals/index.js";
3-
import { StackLayout, Application } from "../core/index.js";
3+
import { StackLayout, Application, Label } from "../core/index.js";
44

55
Application.run({
66
create: () => {
77
const stackLayout = new StackLayout();
88
stackLayout.backgroundColor = "yellow";
9+
stackLayout.width = 300;
10+
stackLayout.height = 300;
11+
12+
const label = new Label();
13+
label.text = "Hello World!";
14+
label.textAlignment = "center";
15+
label.fontSize = 24;
16+
label.color = "black";
17+
label.width = 200;
18+
label.height = 200;
19+
20+
stackLayout.addChild(label);
21+
922
return stackLayout;
1023
},
1124
});

examples/metal.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class MetalAdder {
4545
const library = device.newLibraryWithSourceOptionsError(
4646
`
4747
#include <metal_stdlib>
48-
using namespace metall; // error
48+
using namespace metal;
4949
5050
kernel void add_arrays(device const float* inA,
5151
device const float* inB,

metadata/include/IR.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ class MetadataFactory {
348348
void processClassRefs();
349349
void processProtocolRefs();
350350

351-
std::unordered_set<std::string> frameworks;
351+
std::unordered_set<std::string> includePaths;
352352

353353
std::unordered_map<std::string, VariableDecl> variables;
354354
std::unordered_map<std::string, EnumDecl> enums;

metadata/metadata.ios.nsmd

1.49 KB
Binary file not shown.

metadata/metadata.macos.nsmd

510 Bytes
Binary file not shown.

metadata/src/IR/Factory.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "IR.h"
22
#include "MetadataWriter.h"
3+
#include <string>
34
#include <unordered_map>
45
#include <unordered_set>
56

@@ -250,9 +251,20 @@ bool MetadataFactory::shouldProcess(CXCursor cursor, bool required) {
250251
return false;
251252
}
252253

253-
// TODO(Dj): Support user defined header files as well.
254-
std::string framework = getFrameworkName(cursor);
255-
return frameworks.contains(framework);
254+
CXSourceLocation srcloc = clang_getCursorLocation(cursor);
255+
CXFile file;
256+
clang_getFileLocation(srcloc, &file, nullptr, nullptr, nullptr);
257+
CXString fileName = clang_getFileName(file);
258+
std::string fileNameStr = clang_getCString(fileName);
259+
clang_disposeString(fileName);
260+
261+
for (const std::string &path : includePaths) {
262+
if (fileNameStr.find(path) != std::string::npos) {
263+
return true;
264+
}
265+
}
266+
267+
return false;
256268
}
257269

258270
void MetadataFactory::processVariable(CXCursor cursor) {

metadata/src/main.cpp

Lines changed: 59 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,24 @@
1111
#include <set>
1212
#include <string>
1313
#include <unordered_map>
14+
#include <unordered_set>
1415
#include <vector>
1516

1617
using namespace metagen;
1718

1819
#define UMBRELLA_HEADER "umbrella.h"
1920

2021
int main(int argc, char **argv) {
21-
char *target = argv[1];
22-
char *outputFile = argv[2];
23-
char *outputTypesDir = argv[3];
24-
std::string sdk = argv[4];
25-
std::string frameworksDir = sdk + "/System/Library/Frameworks";
22+
std::string outputFile;
23+
std::string outputTypesDir;
24+
std::string sdk;
25+
std::string frameworksDir;
2626

27-
std::set<std::string> frameworks;
28-
29-
for (int i = 5; i < argc; i++) {
30-
frameworks.insert(argv[i]);
31-
}
27+
std::string code = "";
3228

3329
std::vector<std::string> args = {"-Xclang",
3430
"-isysroot",
35-
sdk,
31+
"",
3632
"-x",
3733
"objective-c",
3834
"-fno-objc-arc",
@@ -44,18 +40,54 @@ int main(int argc, char **argv) {
4440
"-Wno-expansion-to-defined",
4541
"-Wno-deprecated-declarations",
4642
"-Wno-objc-property-no-attribute",
47-
"-std=gnu11",
48-
"-I" + sdk + "/usr/include",
49-
"-F" + frameworksDir,
50-
"-target",
51-
target};
52-
53-
std::string code = "";
54-
55-
for (auto &framework : frameworks) {
56-
args.emplace_back("-I" + frameworksDir + "/" + framework +
57-
".framework/Headers");
58-
code += "#import <" + framework + "/" + framework + ".h>\n";
43+
"-std=gnu11"};
44+
45+
std::unordered_set<std::string> includePaths;
46+
47+
for (int i = 1; i < argc; i++) {
48+
std::string arg = argv[i];
49+
if (arg.find("framework=") == 0) {
50+
if (frameworksDir.empty()) {
51+
std::cout << "framework= argument must be specified after sdk="
52+
<< std::endl;
53+
std::exit(1);
54+
}
55+
56+
std::string framework = arg.substr(10);
57+
std::string includePath = frameworksDir + "/" + framework + ".framework";
58+
includePaths.emplace(includePath);
59+
args.emplace_back("-I" + includePath + "/Headers");
60+
code += "#import <" + framework + "/" + framework + ".h>\n";
61+
} else if (arg.find("include=") == 0) {
62+
std::string includeDir = arg.substr(8);
63+
includePaths.emplace(includeDir);
64+
} else if (arg.find("headers=") == 0) {
65+
std::string includeDir = arg.substr(8);
66+
args.emplace_back("-I" + includeDir);
67+
} else if (arg.find("import=") == 0) {
68+
std::string import = arg.substr(7);
69+
code += "#import " + import + "\n";
70+
} else if (arg.find("sdk=") == 0) {
71+
sdk = arg.substr(4);
72+
args[2] = sdk;
73+
args.emplace_back("-I" + sdk + "/usr/include");
74+
frameworksDir = sdk + "/System/Library/Frameworks";
75+
args.emplace_back("-F" + frameworksDir);
76+
} else if (arg.find("target=") == 0) {
77+
std::string target = arg.substr(7);
78+
args.emplace_back("-target");
79+
args.emplace_back(target);
80+
} else if (arg.find("arg=") == 0) {
81+
std::string argval = arg.substr(4);
82+
args.emplace_back(argval);
83+
} else if (arg.find("output=") == 0) {
84+
outputFile = arg.substr(7);
85+
} else if (arg.find("types=") == 0) {
86+
outputTypesDir = arg.substr(6);
87+
} else {
88+
std::cout << "Unknown argument: " << arg << std::endl;
89+
std::exit(1);
90+
}
5991
}
6092

6193
std::vector<const char *> argsC(args.size());
@@ -72,13 +104,13 @@ int main(int argc, char **argv) {
72104
index, UMBRELLA_HEADER, argsC.data(), args.size(), nullptr, 0,
73105
CXTranslationUnit_None);
74106

107+
std::remove(UMBRELLA_HEADER);
108+
75109
if (unit == nullptr) {
76110
std::cout << "Failed to parse translation unit" << std::endl;
77111
std::exit(1);
78112
}
79113

80-
std::remove(UMBRELLA_HEADER);
81-
82114
// print diagnostics
83115
unsigned numDiagnostics = clang_getNumDiagnostics(unit);
84116

@@ -100,9 +132,7 @@ int main(int argc, char **argv) {
100132
CXCursor cursor = clang_getTranslationUnitCursor(unit);
101133

102134
MetadataFactory factory;
103-
for (auto fw : frameworks) {
104-
factory.frameworks.emplace(fw);
105-
}
135+
factory.includePaths = includePaths;
106136
factory.process(cursor);
107137
factory.postProcess();
108138

@@ -121,7 +151,6 @@ int main(int argc, char **argv) {
121151
std::cout << " total size: " << result.second / 1024. / 1024.
122152
<< " MB" << std::endl;
123153
std::cout << " total sections: " << MD_NUM_SECTIONS << std::endl;
124-
std::cout << " num frameworks: " << frameworks.size() << std::endl;
125154
std::cout << " strings (n, size): " << writer.strings.size() << ", "
126155
<< writer.strings.section_size / 1024. << " KB" << std::endl;
127156
std::cout << " consts (n, size): " << writer.constants.size() << ","
@@ -141,7 +170,7 @@ int main(int argc, char **argv) {
141170
std::cout << " unions (n, size): " << writer.unions.size() << ", "
142171
<< writer.unions.section_size / 1024. << " KB" << std::endl;
143172

144-
auto file = std::fopen(outputFile, "w");
173+
auto file = std::fopen(outputFile.c_str(), "w");
145174
std::fwrite(result.first, 1, result.second, file);
146175
std::fclose(file);
147176

scripts/metagen.ts

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,42 @@ await Deno.mkdir(new URL(`../types/${sdkName}`, import.meta.url), {
9999

100100
const exec = new URL("../metadata/build/MetadataGenerator", import.meta.url);
101101
const args = [
102-
sdk.target,
103-
new URL(`../metadata/metadata.${sdkName}.nsmd`, import.meta.url)
104-
.pathname,
105-
new URL(`../types/${sdkName}`, import.meta.url)
106-
.pathname,
107-
sdk.path,
108-
...sdk.frameworks,
102+
`target=${sdk.target}`,
103+
`output=${
104+
new URL(`../metadata/metadata.${sdkName}.nsmd`, import.meta.url)
105+
.pathname
106+
}`,
107+
`types=${
108+
new URL(`../types/${sdkName}`, import.meta.url)
109+
.pathname
110+
}`,
111+
`sdk=${sdk.path}`,
109112
];
110113

114+
for (const framework of sdk.frameworks) {
115+
args.push(`framework=${framework}`);
116+
}
117+
118+
const customFrameworks = [
119+
"/Users/dj/Projects/NativeScript/packages/ui-mobile-base/dist/package/platforms/ios/TNSWidgets.xcframework/ios-arm64/TNSWidgets.framework",
120+
];
121+
122+
for (const framework of customFrameworks) {
123+
args.push(`include=${framework}`);
124+
args.push(`headers=${framework}/Headers`);
125+
args.push(`import="TNSWidgets.h"`);
126+
}
127+
128+
args.push(
129+
"include=/Users/dj/Projects/NativeScript/packages/core/platforms/ios/src",
130+
);
131+
args.push(
132+
"headers=/Users/dj/Projects/NativeScript/packages/core/platforms/ios/src",
133+
);
134+
args.push('import="NativeScriptEmbedder.h"');
135+
args.push('import="NativeScriptUtils.h"');
136+
args.push('import="UIView+NativeScript.h"');
137+
111138
console.log(`%c$ MetadataGenerator ${args.join(" ")}`, "color: grey");
112139

113140
const proc = new Deno.Command(

src/TypeConv.mm

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1014,7 +1014,8 @@ void toNative(napi_env env, napi_value value, void *result, bool *shouldFree,
10141014
napi_value elem;
10151015
napi_get_property(env, value, key, &elem);
10161016
toNative(env, elem, (void *)&obj, shouldFree, shouldFreeAny);
1017-
[(*res) setObject:obj forKey:[NSString stringWithUTF8String:buf]];
1017+
if (obj != nil)
1018+
[(*res) setObject:obj forKey:[NSString stringWithUTF8String:buf]];
10181019
}
10191020

10201021
return;

0 commit comments

Comments
 (0)