Skip to content

Conversation

kraenhansen
Copy link
Collaborator

@kraenhansen kraenhansen commented May 12, 2025

(stacked on #49)

Merging this PR will close #42 by:

  • Renaming the xcframework after creating it and updating the path utils to look for the right file.
  • Update and add documentation on the structure of prebuilds.

This makes it easier for a developer to tell that the xcframework is meant for Node-API auto-linking and it is renamed to .xframework when copied into the host package as part of auto-linking.

@kraenhansen kraenhansen self-assigned this May 12, 2025
Copy link

changeset-bot bot commented May 12, 2025

⚠️ No Changeset found

Latest commit: a61f9fa

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@kraenhansen kraenhansen added Apple 🍎 Anything related to the Apple platform (iOS, macOS, Cocoapods, Xcode, XCFrameworks, etc.) CMake RN Our `cmake` wrapping CLI Ferric 🦀 labels May 12, 2025
@kraenhansen kraenhansen requested a review from mani3xis May 12, 2025 09:09
Comment on lines -77 to -83
export function replaceWithNodeExtension(modulePath: string) {
return path.format({
...path.parse(modulePath),
base: undefined,
ext: ".node",
});
}
Copy link
Collaborator Author

@kraenhansen kraenhansen May 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleting this since the test was failing and it turned out it wasn't actually called from anywhere.

const xcframeworkExtensionOption = new Option(
"--xcframework-extension",
"Don't rename the xcframework to .apple.node"
).default(false);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm adding this option, since we're using this tool to build weak-node-api and we're manually referencing the output artifact via vendored_frameworks (no linking involved).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I'm thinking whether this renaming should be something that the users needs to opt-in, instead of asking not to do it. Moreover, I'm a little afraid that the .apple.node extension might suggest that this will also work out-of-the-box on macOS (hinting that it might be compatible with "old-school" N-API addons & node.js). macOS can load dylibs directly and doesn't require packaging into Xcframeworks, and we are currently doing it only for mobile devices, right?

@kraenhansen kraenhansen force-pushed the kh/weak-node-api-injection branch from 629a063 to 74b48e1 Compare May 15, 2025 05:53
@kraenhansen kraenhansen force-pushed the kh/apple-prebuilds-renamed branch from 51e41d9 to 1848720 Compare May 15, 2025 05:54
Copy link
Contributor

@mani3xis mani3xis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job 👍 I just found minor nitpicks (or more like conversation starters) -- feel free to ignore them.

const xcframeworkExtensionOption = new Option(
"--xcframework-extension",
"Don't rename the xcframework to .apple.node"
).default(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I'm thinking whether this renaming should be something that the users needs to opt-in, instead of asking not to do it. Moreover, I'm a little afraid that the .apple.node extension might suggest that this will also work out-of-the-box on macOS (hinting that it might be compatible with "old-school" N-API addons & node.js). macOS can load dylibs directly and doesn't require packaging into Xcframeworks, and we are currently doing it only for mobile devices, right?

Cargo.lock

/*.xcframework/
/*.apple.node/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Shouldn't .node be reserved for binary files (shared libraries)? Aren't we breaking this assumption here, by making it a directory? In the Node-API docs I've found this quote (emphasis mine):

The string passed to require() is the name of the target in binding.gyp responsible for creating the .node file.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are definitely walking a fine line here and I agree it could cause confusion.

The "problem" is that one of the use-cases we want to support is taking an existing library (with source-code packaged in) and building the Apple and Android binaries for it.
If we were true to the spirit of the docs you referenced, we would have to override the ".node" file which was already included in the package and we couldn't use that for iOS and Android simultaneously. We would have to "swap out" the .node file for the right (platform+arch) at build time, just before it's copied into the app bundle. As an example, I know this is also what a tool like electron-builder is doing when it's building the final app bundle.

☝️ I feel that approach is not the right one, and I would like the prebuilds for different platforms and architectures to co-exist on the filesystem.

To my understanding, Node.js has no standardized way to publish multiple .node files (for multiple platforms / architectures) - we could spent some more time digging into the output formats of tools like:

(slightly unrelated, I found this extension point in node-gyp-build where a platform can implement require.addon https://github.com/prebuild/node-gyp-build/blob/6822ec52423a2b3ed48ef8960a9fe05902e9e1a3/index.js#L3 ... somewhat similar to our requireNodeAddon 🙂)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you help me formulate a problem statement?

@shirakaba also wrote about this in this thread on discord: https://discord.com/channels/426714625279524876/1343407685462130780

@kraenhansen kraenhansen force-pushed the kh/weak-node-api-injection branch from 74b48e1 to 9578c63 Compare May 17, 2025 21:13
@kraenhansen kraenhansen force-pushed the kh/apple-prebuilds-renamed branch from 1848720 to 8c83d1c Compare May 17, 2025 21:31
Base automatically changed from kh/weak-node-api-injection to main May 19, 2025 14:33
@kraenhansen kraenhansen force-pushed the kh/apple-prebuilds-renamed branch from 555a2a6 to a61f9fa Compare May 19, 2025 14:35
@kraenhansen kraenhansen merged commit d789e82 into main May 19, 2025
3 checks passed
@kraenhansen kraenhansen deleted the kh/apple-prebuilds-renamed branch May 19, 2025 14:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Apple 🍎 Anything related to the Apple platform (iOS, macOS, Cocoapods, Xcode, XCFrameworks, etc.) CMake RN Our `cmake` wrapping CLI Ferric 🦀

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use .apple.node extension for prebuilds instead of .xcframework

2 participants