Monday, May 07, 2007

Installing MySQL on Solaris 10 Virtual Machine: gcc and cc Compiler Option Differences

I left the last post in this series at the point of running make for the bitkeeper client. If you have been following the posts and tried to do that, you will be greeted with the following errors:
bash-3.00# make
cc -O2 -Wall -Wno-parentheses bkf.c -o bkf
cc: Warning: option -2 passed to ld
cc: illegal option -Wall
make: *** [bkf] Error 1

The first line shows the compiler options being used followed by a warning and an error. The reason we are getting this error is because cc options != gcc options. We have two solutions at hand at this point:

1. Use gcc (we installed it earlier)
2. Change the compiler options to use cc's compiler options instead of gcc.

Using gcc compiler
To use the gcc compiler instead of cc, do the following:
bash-3.00# CC=`which gcc`
bash-3.00# export CC
bash-3.00# make

This will let you go past the first set of errors. make will now be stopping with the following errors.
bash-3.00# make
/usr/local/bin/gcc -O2 -Wall -Wno-parentheses bkf.c -o bkf
Undefined first referenced
symbol in file
gethostbyname /var/tmp//ccGSplTt.o
socket /var/tmp//ccGSplTt.o
connect /var/tmp//ccGSplTt.o
ld: fatal: Symbol referencing errors. No output written to bkf
collect2: ld returned 1 exit status
make: *** [bkf] Error 1

These errors mean that you need to set LDFLAGS as follows
export LDFLAGS="-lsocket -lnsl -lm"

Now running make should produce no errors.
bash-3.00# make
/usr/local/bin/gcc -O2 -Wall -Wno-parentheses -lsocket -lnsl -lm bkf.c -o bkf

Using the cc compiler flags
To change the gcc compiler flags to cc compiler flags, edit the Makefile and replace the line that specifies the gcc options with a line using options recognized by cc. So, you would find the line:
CFLAGS=-O2 -Wall -Wno-parentheses

and replace with
CFLAGS=-xO2 -v

Regarding -Wno-parentheses, James Carlson of Sun Microsystems pointed out the following:
Gcc does have it documented in the 'info' files; you just have to look
under "-Wparenthesis" in the warning options.

For the equivalent outside of gcc, see lint's "-errchk=no%parenthesis"

option. (Our tool chain doesn't get lint and cc confused. ;-})

Now running make will produce
bash-3.00# make
cc -xO2 -v bkf.c -o bkf
"bkf.c", line 196: warning: Function has no return statement : clone
Undefined first referenced
symbol in file
gethostbyname bkf.o
socket bkf.o
connect bkf.o
ld: fatal: Symbol referencing errors. No output written to bkf
make: *** [bkf] Error 1

To get rid of the undefined symbols, you would need to link the right libraries.

Al Hopper of Logical Approach Inc, once gave me a very handy tip to find more about the "mysterious" undefined symbol. He suggested using something like (run for both /lib and /usr/lib):
for i in /lib/*.so
/usr/ccs/bin/nm -Ag $i |grep -v UNDEF |grep gethostbyname

which produces:
/lib/ [2643]  |    110640|      89|FUNC |GLOB |0    |11     |gethostbyname
/lib/ [2683] | 110202| 222|FUNC |GLOB |0 |11 |gethostbyname_r
/lib/ [3113] | 128448| 174|FUNC |GLOB |0 |11 |_switch_gethostbyname_r
/lib/ [2841] | 110108| 44|FUNC |GLOB |0 |11 |_uncached_gethostbyname_r
/lib/ [1585] | 78996| 38|FUNC |GLOB |0 |11 |res_gethostbyname
/lib/ [1397] | 79034| 41|FUNC |GLOB |0 |11 |res_gethostbyname2
/lib/ [79] | 0| 0|FUNC |GLOB |0 |ABS |gethostbyname

This will tell us that we need the "-lnsl". Similarly running a slightly modified version of the above, we can find out that we also need "-lsocket" specified in LDFLAGS.

The approach I mention above is a bit controversial so use it only if you know the issues it could drag you into. There are other ways to get the same information such as "man socket" and "man gethostbyname" that will do the job in most cases.

export LDFLAGS="-lsocket -lnsl -lm"

At this point, you should be able to run make without any issues.
bash-3.00# make
cc -lsocket -lnsl -lm bkf.o -o bkf

to be continued.

1 comment:

Anonymous said...

I had a similar problem when compiling spine on Solaris 10 sparc (function gethostbyname undefined). I searched and searched through the web and tried several things with no result, until I found this post. Thanks a lot!