raco exe makes dynamic executables, and raco distribute doesn't change that:
$ ldd ./tst
linux-vdso.so.1 (0x00007ffc9ed46000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fbeb4c09000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbeb4a18000)
/lib64/ld-linux-x86-64.so.2 (0x00007fbeb4c67000)
On windows, it looks like one can --embed-dlls, which is kindof what I want, but for all platforms.
I'd like to compile statically for ease of distribution and deployment. Is this possible?
Related
I am currently searching for a way to make a binary that I just compiled, a portable binary for most of all linux environment. I was considering Ermine but it's not free (looking for a free solution right now) and tried also with Statifier but didn't work either. Here is the details on the binary I am trying to make static and portable:
sirius#blackb0x:~/MINING/ARIONUM/ariominer/build$ ldd /home/sirius/MINING/ARIONUM/ariominer/build/ariominer
linux-vdso.so.1 => (0x00007fff692fe000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fdfee979000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fdfee775000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fdfee45f000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fdfee159000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fdfedf42000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdfedb79000)
/lib64/ld-linux-x86-64.so.2 (0x00007fdfeeb97000)
If some could tell me how exactly to link all the libs to the binary so it could run easy on all or almost all linux env (2.6.18 kernels to latest) it would be very appreciated.
Thanks
Rebuild the program and its dependencies from source (while having LIBS set to -static), and make sure to pass --enable-static --disable-shared to their configure scripts.
If that doesn't work, just compile it on a very old machine and provide binaries for glibc and musl.
I'm working with legacy system and I need to statically build ImageMagick (6.9 and/or 7.x), because the one in use is very old and has some bugs fixed by more recent versions (and I need these fixes).
I've checked plenty of resources, all coming with different solutions and they got me confused. I have no idea how to work with make and configure and thus I really need something definitive.
For current version I only have executables (ldd says "not a dynamic executable" for each one of them) and etc directory containing some XML configuration (I assume) files.
I need the same thing, just with more recent ImageMagick version.
UPDATE
Just wanted to say that when I use this command to configure it:
LDFLAGS="-static" ./configure --without-modules --enable-static --enable-delegate-build --disable-shared
I end up with
ldd convert
linux-vdso.so.1 => (0x00007ffc71518000)
libgomp.so.1 => /usr/lib/x86_64-linux-gnu/libgomp.so.1 (0x00007f88f254f000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f88f2246000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f88f202f000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f88f1e12000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f88f1a48000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f88f1843000)
/lib64/ld-linux-x86-64.so.2 (0x0000559c6e584000)
Which obviously doesn't work for me, I'd like the whole thing to be statically linked.
I have a simple hello_world.cpp program. I compiled it using g++4.4.7 on a CentOS 6.6 system. When I look at ldd a.out:
linux-vdso.so.1 => (0x00007fffbd79e000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002ab6f6819000)
libm.so.6 => /lib64/libm.so.6 (0x00002ab6f6b1f000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002ab6f6da4000)
libc.so.6 => /lib64/libc.so.6 (0x00002ab6f6fba000)
/lib64/ld-linux-x86-64.so.2 (0x00002ab6f65f7000)
When I load a module for gcc-4.9.2, LD_LIBRARY_PATH is set to /path/to/gcc-4.9.2/lib64 and running ldd a.out yields :
linux-vdso.so.1 => (0x00007ffff9393000)
libstdc++.so.6 => /path/to/gcc-4.9.2/lib64/libstdc++.so.6 (0x00002b2b7c104000)
libm.so.6 => /lib64/libm.so.6 (0x00002b2b7c435000)
libgcc_s.so.1 => /path/to/gcc-4.9.2/lib64/libgcc_s.so.1 (0x00002b2b7c6b9000)
libc.so.6 => /lib64/libc.so.6 (0x00002b2b7c8cf000)
/lib64/ld-linux-x86-64.so.2 (0x00002b2b7bee2000)
QUESTION : Why is the 4.9.2 version of the gcc libraries used when LD_LIBRARY_PATH is set, even though I compiled with with 4.4.7?
This seems to pose a problem of knowing which version of a library is being used. A user may compile a program with one compiler version, load a different compiler versions (via module) and then run the executable which uses a different library version than expected.
I don't know whether you're aware that the use of Environment Modules
is not a necessary or normal part of using GCC, or even using multiple versions of GCC.
Setting LD_LIBRARY_PATH to override the system dynamic linker's default directory search order
is a practice that has been long and loudly censured, for reasons that include the
one expressed in the last paragraph of your post. See e.g. Gurus say that LD_LIBRARY_PATH is bad
Doing so within environment modules in a system tailored for the use of multiple versions of tools or toolchains
can be regarded as a regulated application of a hazardous practice. In that context, however, the
setting of LD_LIBRARY_PATH in your gcc-4.9.2 environment module is doing exactly what
such a setting is supposed to do: overriding the
dynamic linker's default directory search order. See the documentation: 3.3.1.
In principle it is possible that a program compiled and linked with an older or
later version of GCC would behave unexpectedly if you choose to run it in the
environment of the gcc-4.9.2 module. Environment modules are a niche convenience,
and they come with this risk. Although if you built the program in the native
environment, or specifically in a module-enabled environment for gcc 4.4.7, then
the risk attendant on running it in your gcc-4.9.2 environment is presumably one
that you don't have to take.
I'm trying to build a project using a static library, so that the binary can be used even if the library isn't installed. However, I get lots of errors about undefined symbols when I try to do so.
Looking at the library, I see it has tons of undefined symbols, even though it's a .a static lib:
nm - u /usr/local/lib/libthis.a
....
U EVP_DigestFinal_ex
U EVP_DigestInit_ex
U EVP_DigestUpdate
U EVP_MD_CTX_cleanup
U EVP_MD_CTX_init
Those seem to be from openssl; others seem to be from libbzip2; etc.
Questions:
1. Why does the static (.a) lib have dependencies on shared objects (e.g. libopenssl) that aren't statically compiled?
2. How do I solve this? Trying to manually add -lssl doesn't seem to work. How do I get the binary to compile and not have external dependcies?
Why does the static (.a) lib have dependencies on shared objects (e.g. libopenssl) that aren't statically compiled?
Just about every static library that you can build will have unresolved symbols, e.g.
int my_open_for_read(const char *filename)
{
return open(filename, O_RDONLY); // unresolved reference to open
}
As Marc Glisse pointed out, this a plain unresolved symbol, not a dependency on libc.so.
How do I solve this?
There is no problem to solve here. When you link your binary, you get to decide which libraries to link statically, and which to link dynamically.
Trying to manually add -lssl doesn't seem to work.
This should work:
gcc main.o -lthis -lssl
Possibly you did something like
gcc main.o -lssl -lthis
which is wrong: the order of libraries on the link line matters.
How do I get the binary to compile and not have external dependcies?
Most OSes support using fully-static binaries. Generally this should not be your goal: it makes for less portable binaries, and their use is strongly discouraged.
If you really do want to produce a fully-static binary, link it with -static flag.
Why do you say full static is less portable?
Because they are.
if the user doesn't have the exact same build of the lib, the binary won't be portable with shared libs, but will be portable with static.
This is incorrect: most shared libraries support backward compatibility, e.g. libc.so.6 version 2.22 will happily run executables linked against version 2.3.6 from 10 years ago.
If you do ldd firefox
You need to pay attention to what you are doing:
file -L `which /usr/bin/firefox`
/usr/bin/firefox: POSIX shell script, ASCII text executable
If you look inside the shell script, you'll discover that it invokes /usr/lib/firefox/firefox, and that binary is dynamically linked:
ldd /usr/lib/firefox/firefox
linux-vdso.so.1 => (0x00007ffca278d000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f511731b000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f5117117000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f5116e13000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f5116b0d000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f51168f7000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5116532000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5117757000)
If you compile and link in a shared library does it store the soname of the library somewhere in the binary so it knows which one to link to? In other words if I link against a version 1.0.0 of liba.so and then I update my library to 2.0.0 and the ABI/API has changed and now my sym link to liba.so is pointing to the 2.0.0 version will the binary still know to look at liba.so.1? In other words does it store the specific soname of the linked library in the binary
Yes, you can use ldd to view the dependency of a binary.
Try ldd /bin/bash yourself
On my machine it prints
linux-vdso.so.1 => (0x00007fff10dff000)
libncurses.so.5 => /lib/libncurses.so.5 (0x00007f2237acb000)
libdl.so.2 => /lib/libdl.so.2 (0x00007f22378c7000)
libc.so.6 => /lib/libc.so.6 (0x00007f2237564000)
/lib64/ld-linux-x86-64.so.2 (0x00007f2237d25000)