Vision and Around

Dedicated to my research and life

"Undefined References" Errors in Gcc/g++ Compiling

| Comments

(For C/C++ compiling in Linux-like environments with GCC)

The two probable causes,

1)      External libraries are not completely acknowledged

2)      External libraries are not properly acknowledge

Math functions such as sin() normally entails the header #include <math.h> in programs. However, to serve the full purpose, when compiling and linking the program, the math library needs to be linked by adding the flag  - lm (short for –libm) to the command line. External libraries all require similar procedures for deployment (e.g., -lgsl for the GNU Science Library).

The second point is much trickier and not easy to detect. Referring to this introduction to GCC,


traditional behavior of linkers is to search for external functions from left to right in the libraries specified on the command line.

So it means if my libA requires libB, in the linking specification, I must put –libA  ahead of –libB. Moreover, if a program calc.c requires the math library, I need to specify the compiling command line as (in the webpage):

$ gcc –Wall  calc.c –lm –o calc

to ensure that calc.c find the math library without a problem.

I have experimented with this for several cases, on my Ubuntu 9.10 Linux that comes with GCC 4.4.1. The blessing is that it seems at least this version has been equipped with the powerful linker that discards the order constraints

Most current linkers will search all libraries, regardless of order, but since some do not do this it is best to follow the convention of ordering libraries from left to right.

But wait, there are exceptions!  We know that there are two possibilities for linking, static linking and dynamic linking.

Dyamic linking (with shared libraries signalled by the .so extensions in Linux) is the default behavior of the linker, because it always produces relatively slim executables or objects, as compared to static linking. The whole point of static linking (with static libraries that ends with .a), on the other hand, is to put the priority on portability by copying the content of the dependent libraries in and eliminating the needs for the dependency library setup on the running platform. Static linking can be turned on by adding the –static flag when compiling and linking.

Seriously, my experiments suggest one has to be orthodox and observe the linking order rule when the –static flag is turned on.  It seems that within the external functions, this is not strict. But one needs to ensure that the program files be put ahead of its pertinent functions. E.g., when calc.c requires both the math library and the GNU science library, the command for static linking should be:

$ gcc –Wall –static calc.c –lm –lgsl  –o calc

and it’ll sparkle the reference error if one insists on

$ gcc –Wall –static –lm –lgsl  calc.c –o calc