-
Notifications
You must be signed in to change notification settings - Fork 7.3k
build: add --enable-shared and --enable-static #7336
Conversation
Thank you for contributing this pull request! Here are a few pointers to make sure your submission will be considered for inclusion. The following commiters were not found in the CLA:
You can fix all these things without opening another issue. Please see CONTRIBUTING.md for more information |
In case you're wondering, three people asked me about this in the last two weeks (where this == how to build a library and the run-time error with the static library) so I figured I'd just write the patch and point people at it. :-) |
I am very interested in having this as an option for node, but right now we have perhaps the worst concept about what is and isn't our public api -- so I'm not quite ready to make this easier for people until we can solidify that. |
I feel that but if it helps: two out of the three people that approached me just wanted a way to start node in-process - the only public API they're interested in is node::Start(). If it helps, I can hide the configure switches from the output of --help and add 'here be dragons' comments. |
I encountered this when upgrading the node fork in atom/atom-shell, I checked the final binary and some modules' DSO constructors were not found in it, the found ones were only:
The DSO constructors' symbols were correct in each module's object file, so it should a linker bug, and my investigation has stopped here. |
Found this post when investigating on this, so this is indeed an expected behavior of linker when building node as static library. |
I have got a workaround for the linking problem when building node as static library, first we need to export the DSO constructors, then reference the DSO constructors](electron/electron@69adff1) somewhere else to force the linker to include them. |
@zcbenz I don't think that's a general solution; it will neatly address the issue with built-in modules but making constructors public is bound to result in symbol clashes between third-party modules. Perhaps you can add the |
@bnoordhuis still relevant? |
Well, it won't merge cleanly if that is what you mean and the constructor issue still exists but I do believe it's a useful feature. I can dust it off if people feel the same way. |
@bnoordhuis heck, why not. if it's not much effort don't see why it shouldn't be included. |
Add configure switches for building a shared or static library. The switches are mutually exclusive for now; building both a shared and a static library at the same time requires a fair amount of overhaul. Undo the change from commit 76b9846 ("node: register modules from DSO constructors") for built-in modules. Constructor functions don't show up in the final binary unless something explicitly references them.
@trevnorris Updated. The workaround for the module registration issue is somewhat pervasive but it seemed cleanest to me. |
👍 |
@indutny I'm reviewing/testing it now, but would also like your eyes as a sanity check. |
@bnoordhuis I ran Edit: Same thing happens w/ |
I really don't want to drop the way the modules are being loaded here, we had to do similar work arounds for windows to not drop the initializers. We should try and figure out a way around that. Initialization of modules through the constructor mechanism provides us the opportunity for people to include binary addons during build without code modification, but can be passed as a configuration option that defines the path to the object that should be linked in We still don't really have a good conversation about what our supportable interface is for Node, beyond |
I'm not sure how to stop that from happening without a nasty hack to the Makefile (write build type to config.mk, then wrap Alternatively, I can add a documentation note somewhere explaining that you should build the library with
I'm open to suggestions. The only way I know of to make it work is linking the final executable with It also pushes the responsibility to the consumer of the archive, making it harder to use. That's something I'd like to avoid if possible.
Commits da30c00 and ba09409 by @deanm export |
Just a note on the original problem, if you are looking at solving the constructor problem without explicitly referencing the symbols, it should just be a matter of using the archive with --whole-archive (gcc) / -force_load (osx). Not sure what's required on Windows but likely something similar. |
If your linker so requires (it seems like the illumos linker does not, as I cannot reproduce this behaviour), then --whole-archive or -zallextract, or whatever equivalent your linker offers, is not heavy-handed; it is in fact the only correct solution. The alternative is to teach your linker about init and fini sections, but even if you so modified every linker in the world there would still be older ones in use. This is not a bug in the DSO loader, it is a basic shortcoming of static libraries, which is why most modern systems no longer make use of static libraries. Use a shared library, or tell the linker what you want it to do. Please don't change the DSO loader to work around buggy linkers and/or incorrect linker flags in consumers. |
@bnoordhuis Eh, I'm not worried about it. Maybe you can just conditionally |
I'm going to close this PR because it's well and truly stale by now. |
Add configure switches for building a shared or static library.
The switches are mutually exclusive for now; building both a shared and
a static library at the same time requires a fair amount of overhaul.
Caveat emptor: the static library (libnode.a) builds but is not useful
yet, it doesn't find built-in modules like contextify at run-time.
The prime suspect is commit 76b9846 ("node: register modules from DSO
constructors"); it looks like the constructors aren't linked into the
final binary.
R=@indutny