Development Tools

These page is focused on GNU development Tool, both available on Windows and Unix. The notes about windows specific tools are here: Compiler.

Link order of libraries

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 -lm
since 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.

An Introduction to GCC - for the GNU compilers gcc and g++

LDD

List of shared libraries used by an executable:

ldd {executable_name}

NM

List symbols from object files:

nm {library_name|object_name}

Symbols used, but not defined:

  • U: The symbol is used, but undefined. (defined in another module)


Defined Symbols:

  • B: The symbol is in the uninitialized data section (known as BSS).
  • D: The symbol is in the initialized data section.
  • T: The symbol is in the text (code) section.
  • G: The symbol is in an initialized data section for small objects. Some object file formats permit more efficient access to small data objects, such as a global int variable as opposed to a large global array.
  • N: The symbol is a debugging symbol.
  • R: The symbol is in a read only data section.
  • S: The symbol is in an uninitialized data section for small objects.


Symbols that could be defined multiple times:

  • C The symbol is common. Common symbols are uninitialized data. When linking, multiple common symbols may appear with the same name. If the symbol is defined anywhere, the common symbols are treated as undefined references. For more details on common symbols, see the discussion of –warn-common in Linker options.
  • W: The symbol is a weak symbol. When a weak defined symbol is linked with a normal defined symbol, the normal defined symbol is used with no error. When a weak undefined symbol is linked and the symbol is not defined, the value of the symbol is determined in a system-specific manner without error. On some systems, uppercase indicates that a default value has been specified.

Local/Global * If lowercase, the symbol is local

  • If uppercase, the symbol is global (external)

To list only the global symbols use the -g option

Others similar tools

core dump

Usefull, for example, for the debugging of a segmentation fault:

  1. Compile the target executable with the -g flag (for debug information)
  2. Launch
    ulimit -c unlimited
  3. Launch the target executable, if it will crash, a core file will be generated.
  4. Launch the gdb debugger on the core file with the executable debug information:
    gdb exec_name core
  5. To have information on the back trace of the function calls before the crash: bt

objdump

objdump -t object_name

gcc flags

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)

ar flags

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)

CMake

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")

Makefile

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 $<

Library creation and use example

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

Program Library HOWTO

c/development_tools.txt · Last modified: 2010/08/10 (external edit)
CC Attribution-Noncommercial-Share Alike 3.0 Unported
Valid CSS Driven by DokuWiki Recent changes RSS feed Valid XHTML 1.0