Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

configure: generate a fully statically linked executable #8274

Closed
wants to merge 2 commits into from
Closed

configure: generate a fully statically linked executable #8274

wants to merge 2 commits into from

Conversation

piranna
Copy link

@piranna piranna commented Aug 27, 2014

Allow to create an executable with no external dynamic libraries, also the
ones from the system. This is somewhat dependent of the used C lib, for
example glibc has some internal dynamic libraries loaded by itself, but for
other ones like eglibc or dietlib, this would produce a true static linked
executable. This can be of interest for embebers or resource constraints
platforms, but the main reason for this is to allow to use a Javascript
file as Linux kernel 'init' on NodeOS.

Allow to create an executable with no external dynamic libraries, also the
ones from the system. This is somewhat dependent of the used C lib, for
example glibc has some internal dynamic libraries loaded by itself, but for
other ones like eglibc or dietlib, this would produce a true static linked
executable. This can be of interest for embebers or resource constraints
platforms, but the main reason for this is to allow to use a Javascript
file as Linux kernel 'init' on NodeOS.
@piranna
Copy link
Author

piranna commented Aug 27, 2014

This is the same that issue #8250, only that pointing against branch v0.12

@indutny
Copy link
Member

indutny commented Aug 27, 2014

Appears to be failing on OSX:

ld: library not found for -lcrt0.o

@indutny
Copy link
Member

indutny commented Aug 27, 2014

Ok, crt1.o is present...

@indutny
Copy link
Member

indutny commented Aug 27, 2014

Hm... after symlinking crt1.o to crt0.o it fails with:

ld: library not found for -lstdc++

@indutny
Copy link
Member

indutny commented Aug 27, 2014

Ok, going to try it out on Ubuntu. Meanwhile could you make configure print something like "This option is unavailable on OSX".

@piranna
Copy link
Author

piranna commented Aug 27, 2014

I have been searching a little bit and seems it's an issue of GCC on OSX, but probably there could be workarounds...

http://stackoverflow.com/questions/3801011/ld-library-not-found-for-lcrt0-o-on-osx-10-6-with-gcc-clang-static-flag
http://stackoverflow.com/questions/5259249/creating-static-mac-os-x-c-build
http://appliedprocrastination.blogspot.com.es/2008/12/dread-lcrt0o-error-on-mac-os-x.html

Anyway, I'll add a warning on the flag help message.

@piranna
Copy link
Author

piranna commented Aug 27, 2014

I've added the OSX issue info on the flag help and also I print it on console when the flag is enabled and running on a Mac.

@bnoordhuis
Copy link
Member

the main reason for this is to allow to use a Javascript file as Linux kernel 'init' on NodeOS

Just curious, do you need a statically linked binary in order to run as init? Because the dynamic linker is loaded by the kernel and indeed on my system PID 1 is a dynamically linked systemd. Or is NodeOS a platform without a dynamic linker?

(Apropos systemd, mine is actually linked to no less than 20 libraries, including such curious ones as libpcre and liblzma. I never knew.)

@piranna
Copy link
Author

piranna commented Aug 28, 2014

I though I needed a statically linked binary, but after talking about it at musl mail-list I found just yesterday that's not neccesary, and seems it was a fault of me (probably missed one of the dynamica libraries, maybe /lib/ld-linux.so.2). The same happened with /usr/bin/env as she-bang, that maybe failed by the same reason. Now I'm using a vanilla dynamically linked Node.js executable.

This flag is still useful, I have been using it the last days and it worked perfectly. It had some compilation issues, for example glibc don't generate trully statically linked executables (libc.so is still needed) so I used musl and OpenSSL had problems with it so I disabled ssl support (musl guys suggested me to try to use LibreSSL instead), and dlopen() in musl is a stub function on statically linked executables so Node.js compiled modules didn't load. Besides that, for pure Javascript scripts and dependencies, it works without problems.

@indutny
Copy link
Member

indutny commented Sep 2, 2014

Hm... @piranna I don't think that it would be a nice addition then :)

@bnoordhuis
Copy link
Member

Apropos glibc, I've noticed in the past that static linking makes it segfault inside getaddrinfo() when you copy the binary to a machine without libnss. Gotchas like that should be documented somewhere if this patch lands.

@indutny
Copy link
Member

indutny commented Sep 2, 2014

Hm... yeah, I think we will need a wiki page for this.

@indutny
Copy link
Member

indutny commented Sep 2, 2014

Landed in cdc01fa, thank you! Please create a wiki page if you feel comfortable with this ;)

@indutny indutny closed this Sep 2, 2014
@piranna piranna deleted the statically_linked branch September 2, 2014 18:52
@piranna
Copy link
Author

piranna commented Sep 2, 2014

Thank you! :-) It's true this would need some tune-ups to fix the corner cases, but a wiki page would do the job by the moment, I'll do it :-)

@piranna
Copy link
Author

piranna commented Sep 2, 2014

I've created a wiki page

@retrohacker
Copy link

So it would seem that somewhere inside of the dns package, a call to the system call getaddrinfo is made. This is psuedo-statically linked, but if you move the binary off of the system it was compiled on it becomes unstable. gcc's exact warning is: warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking. I ran into this when I used the method from this pull request to build a static binary of 0.10.33 to put inside a docker container.

From what I can tell, it seems that everything else is safe to statically link except for libc

disclaimer it is entirely possibly that I am doing something silly.

@piranna
Copy link
Author

piranna commented Dec 13, 2014

From what I can tell, it seems that everything else is safe to statically link except for libc

Yes, that is. You can compile Node.js with other libc like musl to have a
fully statically linked binary (there are some problems with OpenSSL in
that case regarding to its usage of some GLIB-specific macros but can be
fixed), and the other day I've read about a configure option of glibc to
use a static version of nds, that is not recomended because it goes agains
the purpose of a plugable name resolution system (obvious... :-P) but seems
is the only missing piece to fully statically link glibc itself, so you can
try it :-) If it works, tell us to improve the Node.js build system or do
it yourself if you want it :-)

@retrohacker
Copy link

Thanks :-) this PR is awesome work by the way.

Since libc is already in the shared libs in my container, I think I'm going to go the route of leaving libc dynamically linked and call it a day.

@piranna
Copy link
Author

piranna commented Dec 25, 2014

I've just tested to compile Node.js statically by using musl, and besides the fact that I needed to patch OpenSSL, I can confirm this flag generates a trully fully static binary. Whoa! :-D

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants