Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shirakaba/5fb986174ba856f71249d97a54be2de8 to your computer and use it in GitHub Desktop.
Save shirakaba/5fb986174ba856f71249d97a54be2de8 to your computer and use it in GitHub Desktop.
Building and running the NativeScript metadata generator

Building and running the NativeScript metadata generator from the repo

This focuses on the V8 iOS metadata generator.

Links

https://github.com/NativeScript/ns-v8ios-runtime/tree/main/metadata-generator

Installing

Cloning

The repo git history is at least 1 GB in size because V8 binaries get committed to it. So you may prefer a shallow clone:

git clone --recursive --depth 1 git@github.com:NativeScript/ns-v8ios-runtime.git

Downloading LLVM

The metadata generator is designed against a specific version of LLVM which it searches for in the repo, so you'll need to run this script as a prerequisite:

# in the root of the repo
$ ./download_llvm.sh

Building

Bear in mind that cmake reuses previously-built objects, so if you run into any issues, you can consider removing your build folder (e.g. rm -rf build) before any rebuild attempt.

Note that I am passing the -DCMAKE_PREFIX_PATH flag because for whatever reason, cmake can't find libxml2 (as discussed in #174). You may wish to try it without that flag first just so that you have a shorter command to run.

Building the metadata generator on its own

# In the metadata-generator folder:
METADATA_ARCH="arm64" && cmake -DCMAKE_PREFIX_PATH=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr -B build -DCMAKE_BUILD_TYPE=Release -DMETADATA_BINARY_ARCH=$METADATA_ARCH -DCMAKE_OSX_ARCHITECTURES=$METADATA_ARCH && cmake --build build 

Building the metadata generator and an Xcode project with which to debug it

I don't really get it, but it's a two-step process involving two build folders. I edited build_metadata_generator.sh.

# In `build_metadata_generator.sh`, swap out the first call to cmake (line 14) for these two lines:

# Make the binary in `build` (which is later moved to `dist`)
cmake -DCMAKE_PREFIX_PATH=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr -B build -DCMAKE_BUILD_TYPE=Release -DMETADATA_BINARY_ARCH=$1 -DCMAKE_OSX_ARCHITECTURES=$1

# Make the xcode project in `xcode-build`
cmake -DCMAKE_PREFIX_PATH=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr -B xcode-build -DCMAKE_PREFIX_PATH=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr -G Xcode

... now to build just arm64, run:

./build_metadata_generator.sh arm64

Running

(Assuming you have built the metadata generator into the build folder), rather than running build/objc-metadata-generator directly, the idea is that you'd run build/build-step-metadata-generator.py, which is a convenience tool that passes along flags to the former.

That said, the python tool still relies upon a large number of environment variables being populated. These normally get filled in for you when building a NativeScript project, but if you're trying to run the tool standalone, you'll have to either pull those flags out of an existing NativeScript project (the Readme does provide some instructions) or just guess them like I have.

Running for an iOS project

# Assuming we're starting in the root of the repo, and have already
# built the metadata-generator tool into a folder called 'build':
$ cd metadata-generator/build

# We create another build directory, `conf_build_dir`, (where the tool
# itself can write its metadata into), which I have chosen just to
# nest inside the build folder. We also provide a subdirectory, `ts`,
# for outputting the TypeScript declarations into.
#
# We then provide a bunch of environment variables targeting iOS 15.5.
# It's also mandatory to specify the SRCROOT of an existing project. I
# find this a bit annoying as my use-case is often just to analyse the
# iOS SDK and not any particular project, but in any case I provided
# an arbitrary Objective-C-based project that I had lying around.
#
# There are likely more flags you can pass - it didn't pick up my
# project's Cocoapods, so I suspect there is more work that can be
# done to specify header search paths.
$ mkdir -vp conf_build_dir/ts && NS_TYPESCRIPT_DECLARATIONS_PATH=conf_build_dir/ts EFFECTIVE_PLATFORM_NAME=-iphoneos IPHONEOS_DEPLOYMENT_TARGET=15.5 SDK_VERSION=15.5 GCC_C_LANGUAGE_STANDARD=gnu99 ARCHS=arm64 LLVM_TARGET_TRIPLE_VENDOR=apple CONFIGURATION_BUILD_DIR=conf_build_dir SDKROOT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator15.5.sdk SRCROOT=/Users/jamie/Documents/git/react-native-native-runtime/example/ios ./build-step-metadata-generator.py -verbose
Python version: 3.8.9 (default, May 17 2022, 12:55:41) 
[Clang 13.1.6 (clang-1316.0.21.2.5)]
Generating metadata for arm64
Generating TypeScript declarations in: "conf_build_dir/ts/arm64"
Metadata Generator Arguments: 
./objc-metadata-generator -verbose -output-bin conf_build_dir/metadata-arm64.bin -output-umbrella conf_build_dir/umbrella-arm64.h -docset-path /Users/jamie/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.iOS.docset -output-typescript conf_build_dir/ts/arm64 Xclang -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator15.5.sdk -std=gnu99 -target arm64-apple-ios15.5 
Clang Arguments: 
"-v", "-x", "objective-c", "-fno-objc-arc", "-fmodule-maps", "-ferror-limit=0", "-Wno-unknown-pragmas", "-Wno-ignored-attributes", "-Wno-nullability-completeness", "-Wno-expansion-to-defined", "-D__NATIVESCRIPT_METADATA_GENERATOR=1", "-isysroot", "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator15.5.sdk", "-std=gnu99", "-target", "arm64-apple-ios15.5", 
Merged 859 categories.
Result: 47750 declarations from 155 top level modules
Done! Running time: 2.2733 sec 
Saving metadata generation's stderr stream to: conf_build_dir/metadata-generation-stderr-arm64.txt

You'll see that as the Python tool prints out the exact arguments that it's passing along to the metadata generator executable, you can save a bit of startup time by running that command directly rather than going via the Python script each time. e.g.:

./objc-metadata-generator -verbose -output-bin conf_build_dir/metadata-arm64.bin -output-umbrella conf_build_dir/umbrella-arm64.h -docset-path /Users/jamie/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.iOS.docset -output-typescript conf_build_dir/ts/arm64 Xclang -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator15.5.sdk -std=gnu99 -target arm64-apple-ios15.5 

Alternatively: Using a ready-built metadata-generator from @nativescript/ios

This OUT folder was generated as follows:

# Install the @nativescript/ios npm package into some node project.
npm install @nativescript/ios@8.3.3

# Change directory into the 'internal' folder shipped by @nativescript/ios.
cd node_modules/@nativescript/ios/framework/internal

# Change directory into the appropriate build of the metadata generator CLI
# tool for your system:
cd metadata-generator-arm64/bin
# or:
cd metadata-generator-x86_64/bin

# Create an output folder for the metadata we're about to generate.
mkdir OUT

# Run the metadata generator.
./objc-metadata-generator -verbose -output-bin OUT/metadata-arm64.bin -output-umbrella OUT/umbrella-arm64.h -docset-path /Users/jamie/Library/Developer/Shared/Documentation/DocSets/com.apple.adc.documentation.iOS.docset -output-typescript OUT/ts/arm64 -output-yaml OUT/yaml/arm64 Xclang -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator16.2.sdk -std=gnu99 -target arm64-apple-ios16.2

This command generates:

  • ts: TypeScript typings
  • yaml: The YAML metadata
  • metadata-arm64.bin The metadata binary file (it's an object file to be linked in via -sectcreate - I explain this and the bigger picture a little more here)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment