I am building .so library and was wondering - what is the difference b/w -h and -o cc complier option (using the Sun Studio C++) ?
Aren't they are referring to the same thing - the name of the output file?
I am building .so library and was wondering - what is the difference b/w -h and -o cc complier option (using the Sun Studio C++) ?
Aren't they are referring to the same thing - the name of the output file?
They are referring to different names. Specifically, the -o
option is the file's actual name - the one on the filesystem. The -h
option sets the internal DT_SONAME
in the final object file. This is the name by which the shared object is referenced internally by other modules. I believe it's the name that you also see when you run ldd
on objects that link to it.
-o
is the name of the file that will be written to disk by the compiler
-h
is the name that will be recorded in ELF binaries that link against this file.
One common use is to provide library minor version numbers. For instance, if you're creating the shared library libfoo, you might do:
cc -o libfoo.so.1.0 -h libfoo.so.1 *.o
ln -s libfoo.so.1.0 libfoo.so.1
ln -s libfoo.so libfoo.so.1
Then if you compile your hello world app and link against it with
cc -o hello -lfoo
the elf binary for hello will record a NEEDED
entry for libfoo.so.1
(which you can
see by running elfdump -d hello
).
Then when you need to add new functions later, you could change the -o
value to
libfoo.so.1.1
but leave the -h at libfoo.so.1
- all the programs you already built
with 1.0 still try to load libfoo.so.1
at runtime, so continue to work without being
rebuilt, but you'll see via ls that it's 1.1.
This is also sometimes used when building libraries in the same directory they're used at runtime, if you don't have a separate installation directory or install via a packaging system. To avoid crashing programs that are running when you overwrite the library binary, and to avoid programs not being able to start when you're in the middle of building, some Makefiles will do:
cc -o libfoo.so.1.new -h libfoo.so.1 *.o
rm libfoo.so.1 ; mv libfoo.so.1.new libfoo.so.1
(Makefiles built by the old Imake makefile generator from X commonly do this.)
The -o option will name the output file while the -h option will set an intrinsic name inside the library. This intrinsic name has precedence over the file name when used by the dynamic loader and allows it to use predefined rules to peek the right library.
You can see what intrinsic name was recorded into a given library with that command:
elfdump -d xxx.so | grep SONAME
Have a look here for details:
http://docs.sun.com/app/docs/doc/817-1984/chapter4-97194?a=view