These page is focused on GNU development Tool, both available on Windows and Unix. The notes about windows specific tools are here: Compiler.
The traditional behavior of linkers is to search for external functions from left to right in the libraries specified on the command line. This means that a library containing the definition of a function should appear after any source files or object files which use it. This includes libraries specified with the short-cut -l option, as shown in the following command:
$ gcc -Wall calc.c -lm -o calc (correct order)With some linkers the opposite ordering (placing the -lm option before the file which uses it) would result in an error,
$ cc -Wall -lm calc.c -o calc (incorrect order)
main.o: In function `main': main.o(.text+0xf): undefined reference to `sqrt' because there is no library or object file containing sqrt after ‘calc.c’. The option -lm should appear after the file ‘calc.c’.
When several libraries are being used, the same convention should be followed for the libraries themselves. A library which calls an external function defined in another library should appear before the library containing the function.
For example, a program ‘data.c’ using the GNU Linear Programming library ‘libglpk.a’, which in turn uses the math library ‘libm.a’, should be compiled as,
$ gcc -Wall data.c -lglpk -lmsince the object files in ‘libglpk.a’ use functions defined in ‘libm.a’.
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.
This is worth keeping in mind if you ever encounter unexpected problems with undefined references, and all the necessary libraries appear to be present on the command line.
List of shared libraries used by an executable:
ldd {executable_name}
List symbols from object files:
nm {library_name|object_name}
Defined Symbols:
Symbols that could be defined multiple times:
To list only the global symbols use the -g option
Usefull, for example, for the debugging of a segmentation fault:
ulimit -c unlimited
gdb exec_name core
| flag | meaning |
|---|---|
| -Wall | Show all reasonable warnings (there are more) |
| -g | Produce debug information, necessary for debugging |
| -l{name} | Links to a standard library. Use -lm to load the standard math library |
| -E | Pre-process only. Output pre-processed code |
| -pthread | Fundamental to don't break linked libraries that are using threads |
| -s | Strip all symbols that are not needed for relocation processing |
| -O{n} | Optimize, where n: (0:No Opt.)(1:Normal Opt.)(2:Hard Opt.) |
| -fpic | Position Indipendent Code (necessary for shared libraries) |
| flag | meaning |
|---|---|
| r | Replace older object files in the library, with the new object files |
| c | Create the library if it doesn't already exist |
| s | Write/Update an object-file index into the archive (equivalent to running ranlib on it) |
To generate makefiles:
cmake .
To see the commands called by CMake set the VERBOSE parameter to 1:
make VERBOSE=1
Adding a target to clean CMake files:
tools/distclean.sh
RM="rm -rf" FILE_LIST="CMakeCache.txt CMakeFiles cmake_install.cmake Makefile" for curr_file in `echo $FILE_LIST` do for i in `find -name "$curr_file" -print | sort` do TMP=`$RM $i`; echo -n "." done done echo -n " Done" echo exit 0
add_custom_target(distclean COMMAND tools/distclean.sh COMMENT "Cleaning Cmake files")
Basic Makefile example
# Compiler # C : gcc # C++: g++ CC=gcc # Compiler flags # -pthread: Foundamental to don't break linked libraries that are using threads # -g : Produce debug information, necessary for debugging # -s : Strip all symbols that are not needed for relocation processing # -Wall : Show all reasonable warnings # -On : Optimize, where n: (0:No Opt.)(1:Normal Opt.)(2:Hard Opt.) CC_FLAGS=-pthread -O1 -Wall -s # Sources extention # c : C files # cpp: C++ files SRC_EXT=c # Header files directories needed by the compiler # All the include paths in source code have to be relative to one of the following base directory CC_INCLUDES=-I. -I/usr/include -I/usr/local/include/dummy # Libraries needed by the linker (absolute paths) LD_LIBS=-L. -L/usr/local/lib -ldummy # Project Files # add here all the project object files (with relative path from makefile working directory) MODULES=./main.o \ ./example/example.o # Target executable file TARGET_EXEC=cast all: $(TARGET_EXEC) clean: rm -f $(TARGET_EXEC) $(MODULES) $(TARGET_EXEC): $(MODULES) $(CC) $(CC_INCLUDES) $(CC_FLAGS) -o $@ $(MODULES) $(LD_LIBS) %.o: %.$(SRC_EXT) $(CC) $(CC_INCLUDES) $(CC_FLAGS) $(LD_LIBS) -c -o $*.o $<
hello.c
#include <stdio.h> void sayHello(void) { printf("Hello World!\n"); }
hello.h
#ifndef HELLO_H_ #define HELLO_H_ void sayHello(void); #endif /*HELLO_H_*/
main.c
#include "hello.h" int main(int argc, char** argv) { sayHello(); return 0; }
static.sh
#!/bin/sh # Clean rm -f hello.o main.o libhello.a static_library_test # ====== STATIC LIBRARY CREATION ====== # 1) Compile all the sources file of the library gcc -Wall -g -c -o hello.o hello.c # 2) Create the static library ar rcs libhello.a hello.o # ====== STATIC LIBRARY USE ====== # 1) Compile all the sources file in object files gcc -Wall -g -c -o main.o main.c # 2) Create the "static_test" program including all the # used objects from the static library gcc -g -o static_library_test main.o -L. -lhello # 3) Execute the "static_library_test" program. ./static_library_test
shared.sh
#!/bin/sh # Clean rm -f hello.o main.o libhello.a # ====== SHARED LIBRARY CREATION ====== # 1) Compile all the sources file of the library as PIC (Position Indipendend Code) gcc -fPIC -Wall -g -c hello.c # 2) Create shared library. # Use -lc to link it against C library, since libhello depends on the C library. gcc -g -shared -Wl,-soname,libhello.so.0 -o libhello.so.0.0 hello.o -lc # 3) Set up the soname: now we need to call ldconfig to fix up the symbolic links. /sbin/ldconfig -n . # 4) Set up the linker name. ln -sf libhello.so.0 libhello.so # ====== SHARED LIBRARY USE ====== # 1) Compile all the sources file in object files gcc -Wall -g -c -o main.o main.c # 2) Create program demo_use. # The -L. causes "." to be searched during creation of the program gcc -g -o shared_library_test main.o -L. -lhello # 3) Execute "shared_library_test" program. # Note that we need to tell the program where # the shared library is, using LD_LIBRARY_PATH. LD_LIBRARY_PATH="." ./shared_library_test