For .so I use nm -gC, for .a I use just nm. What should I use for .la?
.la files are only auxiliary files used by libtool, so they contain no executable code and no symbols.
Related
Given ar libraries and possibly object files, what is the best way to find all of the unresolved external symbols? One possibility is to run the linker and then capture the errors, but sometimes it stops after a certain number of symbols. Is there a better way?
In your mingw-w64 installation's bin directory, along with
the C and C++ compilers, linker and make tool, you should other
programs that make up the GNU binutils.
Several of these (nm, objdump, readelf) can parse the symbol tables of object files or shared or
static libraries. The simplest to use is probably nm. Assuming
that the bin directory is in your PATH, open a command prompt
in the directory containing the libraries or object files your are
interested in and run:
nm -u libfoo.a
or:
nm -u foo.obj
to list the undefined symbols in libfoo.a or in foo.obj.
If these files contain C++ symbols that you want to see demangled then
add -C to the nm options.
These tools all recognize that a static library libfoo.a is just
an archive of object files so nm ... libfoo.a gives you just the
same results as if libfoo.a was replaced with a list of the object
files within it.
When I link executable elf file dynamically it needs libc.so.6 shared library.
When I link executable elf file statically it doesn't need libc.so.6 shared library (it's not surprise).
Does it mean, that to assemble executable file with --static, linker includes libc.so.6 in it?
If not - what file does linker include? where can I search it?
As far as I know, linker includes static libraries in statically assembled file.
If you link as static, the linker will link all the needed object (.o) files from the static libraries (.a). For example, the following command lists the object files which are included in the libc6 library:
ar t /usr/lib/libc.a
(the exact path to libc.a of course differs from system to system)
So answer to your question is no, it will not link the whole libc6 library, but only the needed object files. And also, it doesn't do anything with libc.so.6, since this is only for dynamic linking. It works with the libc.a - static version of the library.
According to #janneb comment, the smallest unit to be linked is "section", so it might not even need to link the whole object files.
The linker is the ld command. If you use that command, it does what you ask. Notice that GNU ld can accept scripts
However, most people are using the gcc command. This is a compiler from the Gnu Compiler Collection suite. Actually, the gcc command is just a driver program, which will run cc1 (the proper C compiler), as, ld and collect2 (which deals with initializations, etc. then invoke the linker).
To understand what exact command[s] gcc is running, pass it the -v program flag.
When you pass -static to gcc it will probably link with e.g. /usr/lib/x86_64-linux-gnu/libc.a or some other static form of the GNU Libc library.
I'm building a library that needs to be dynamically linked to my project. The output is a .so file, so I think I'm on the right track. I'm concerned by the way it's being linked at compile time - by specifying the location of its makefile and depending on a bunch of macros, which I've never encountered before.
Can I assume that since I'm building a .so library (rather than a .a) that I'm in fact dynamically linking? Or is it possible for .so libs to be statically linked, in which case I need to rip apart the make/config files to better understand what's going on?
Thanks,
Andrew
I'm not familiar with internal structure of executables and shared objects, so I could only give some practical hints.
Assuming you use gcc, it should have -shared option when linking object files into library - this way ld (called by gcc) makes shared object instead of executable binary.
gcc -shared -o libabc.so *.o ...
When you link some application with this libabc.so it should link without errors and after that with ldd command you should be able to see libabc.so among its dependencies.
$ ldd app
...
libabc.so => ...............
How can I link a shared library function statically in gcc?
Refer to:
http://www.linuxquestions.org/questions/linux-newbie-8/forcing-static-linking-of-shared-libraries-696714/
You need the static version of the library to link it.
A shared library is actually an executable in a special format
with entry points specified (and some sticky addressing issues
included). It does not have all the information needed to
link statically.
You can't statically link a shared library (or dynamically link a static one).
The flag -static will force the linker to use static libraries (.a) instead of shared (.so) ones. But static libraries aren't always installed by default, so you may have to install the static library yourself.
Another possible approach is to use statifier or Ermine. Both tools take as input a dynamically linked executable and as output create a self-contained executable with all shared libraries embedded.
If you want to link, say, libapplejuice statically, but not, say, liborangejuice, you can link like this:
gcc object1.o object2.o -Wl,-Bstatic -lapplejuice -Wl,-Bdynamic -lorangejuice -o binary
There's a caveat -- if liborangejuice uses libapplejuice, then libapplejuice will be dynamically linked too.
You'll have to link liborangejuice statically alongside with libapplejuice to get libapplejuice static.
And don't forget to keep -Wl,-Bdynamic else you'll end up linking everything static, including libc (which isn't a good thing to do).
Yeah, I know this is an 8 year-old question, but I was told that it was possible to statically link against a shared-object library and this was literally the top hit when I searched for more information about it.
To actually demonstrate that statically linking a shared-object library is not possible with ld (gcc's linker) -- as opposed to just a bunch of people insisting that it's not possible -- use the following gcc command:
gcc -o executablename objectname.o -Wl,-Bstatic -l:libnamespec.so
(Of course you'll have to compile objectname.o from sourcename.c, and you should probably make up your own shared-object library as well. If you do, use -Wl,--library-path,. so that ld can find your library in the local directory.)
The actual error you receive is:
/usr/bin/ld: attempted static link of dynamic object `libnamespec.so'
collect2: error: ld returned 1 exit status
Hope that helps.
If you have the .a file of your shared library (.so) you can simply include it with its full path as if it was an object file, like this:
This generates main.o by just compiling:
gcc -c main.c
This links that object file with the corresponding static library and creates the executable (named "main"):
gcc main.o mylibrary.a -o main
Or in a single command:
gcc main.c mylibrary.a -o main
It could also be an absolute or relative path:
gcc main.c /usr/local/mylibs/mylibrary.a -o main
A bit late but ... I found a link that I saved a couple of years ago and I thought it might be useful for you guys:
CDE: Automatically create portable Linux applications
http://www.pgbovine.net/cde.html
Just download the program
Execute the binary passing as a argument the name of the binary you want make portable, for example: nmap
./cde_2011-08-15_64bit nmap
The program will read all of libs linked to nmap and its dependencias and it will save all of them in a folder called cde-package/ (in the same directory that you are).
Finally, you can compress the folder and deploy the portable binary in whatever system.
Remember, to launch the portable program you have to exec the binary located in cde-package/nmap.cde
Best regards
In gcc, this isn't supported. In fact, this isn't supported in any existing compiler/linker i'm aware of.
I'd like GCC to include files from $HOME/include in addition to the usual include directories, but there doesn't seem to be an analogue to $LD_LIBRARY_PATH.
I know I can just add the include directory at command line when compiling (or in the makefile), but I'd really like a universal approach here, as in the library case.
Try setting C_INCLUDE_PATH (for C header files) or CPLUS_INCLUDE_PATH (for C++ header files) environment variables.
As Ciro mentioned, CPATH will set the path for both C and C++ (and any other language).
On Windows these may be set to semicolon-separated lists. On most other platforms they may be set to colon-separated lists.
More details in GCC's documentation.
Create an alias for gcc with your favorite includes.
alias mygcc='gcc -I /whatever/'
Just a note: CPLUS_INCLUDE_PATH and C_INCLUDE_PATH are not the equivalent of LD_LIBRARY_PATH.
LD_LIBRARY_PATH serves the ld (the dynamic linker at runtime) whereas the equivalent of the former two that serves your C/C++ compiler with the location of libraries is LIBRARY_PATH.
A gcc spec file can do the job, however all users on the machine will be affected.
See HOWTO Use the GCC specs file