Why linking with CC instead of ld
By Maxim Kartashev on сен 22, 2009
Let's execute the following:
$ /opt/12/SUNWspro/bin/CC a.cand see what this command boils down to by adding -v option:
$ /opt/12/SUNWspro/bin/CC a.c -v ... /usr/ccs/bin/ld -u __1cH__CimplKcplus_init6F_v_ ... -R/export/opt/12/SUNWspro/lib/rw7:...:/opt/SUNWspro/lib:/usr/ccs/lib:/lib:/usr/lib -o a.out /export/opt/12/SUNWspro/prod/lib/crti.o /export/opt/12/SUNWspro/prod/lib/CCrti.o /export/opt/12/SUNWspro/prod/lib/crt1.o /export/opt/12/SUNWspro/prod/lib/misalign.o /export/opt/12/SUNWspro/prod/lib/values-xa.o -Y P,/export/opt/12/SUNWspro/lib/rw7:...:/usr/ccs/lib:/lib:/usr/lib a.o -lCstd -lCrun -lm -lc /export/opt/12/SUNWspro/prod/lib/CCrtn.o /export/opt/12/SUNWspro/prod/lib/crtn.o⁞
Let's see what these lines are for:
-R... - this is where the difference between CC and ld starts; -R option is used to specify RUNPATH, i.e. list of directories searched at run time to find libraries that this program depends on. We can check that after a.out is built by doing
$ elfdump -d a.out | grep RUNPATH  RUNPATH 0x251 /export/opt/12/SUNWspro/lib/rw7:...:/opt/SUNWspro/lib:/usr/ccs/lib:/lib:/usr/lib
This option is followed by a number of C++ run-time support code that needs to be linked with the executable; here's what those pre-built object files are for:
crti.o - prologues for init and fini routines; used for all languages;
CCrti.o - C++ addition to init and fini - call constructors/destructors;
crt1.o - defines, among other things, _start routine that eventually calls main();
misalign.o - exists on sparc only and contains routines that support misaligned memory references; see -xmemalign option in CC(1) man page;
values-xa.o - lets run-time support know about ANSI conforming mode; see -Xa option in cc(1) man page.
-Y P,... - specifies directories to find libraries at compilation time.
Then follows a.o, the only object file we have provided.
It is linked with several obligatory run-time support libraries:
libc.so - C run-time support routines like printf(3C) are defined here;
libm.so - miscellaneous math routines like tan(3M), for example;
libCrun.so - C++ support for exceptions, operator new, etc.;
libCstd.so - older STL implementation; not strictly obligatory and is usually replaced with newer implementation, libstlport.so (-library=stlport4 option).
The list is concluded with the code for endings of init and fini routines:
CCrtn.o - C++ part of init/fini;
crtn.o - common part of init/fini (code that handles return from those routines).
As you can see for yourself, it is rather error-prone way to manually specify all those object files and libraries; one also has to keep them in correct order: if, for example, list of object files is started with CCrti.o instead of crti.o, a.out will probably crash during startup as CCrti.o code expects certain things to be in specific registers, which is crti.o job.