1 - Structuring source and binary code
1 - Structuring source and binary code
main_func.c
fact_func.c
Structuring source code
●
How the compiler find header files
– If the path specified in the #include directive is between
double quotes ’’ … ’’ => the location is relative to the
current compilation directory.
– If the path specified in the #include directive is between
angle-bracket <...> => the location is relative to :
●
Standard header location. Ex. /usr/include
●
Or, in a location specified using -I option of the compiler.
Conditional compilation
●
Accommodate varying :
– hardware configurations
– memory limitations
– platform-specific requirements.
●
Conditional compilation enables to :
– tailor the code to different constraints, without having to maintain multiple code
bases.
– optimize the code for different
●
microcontrollers or development boards
●
debugging and production environments.
Conditional compilation
●
In case of Windows platform, the program opens “C:\file.txtinstead of
“/tmp/file.txt”
●
WINDOWS_OS conditional compilation switch can be set either in the
source code (not recommended) or at compilation phase using -D option.
– Ex : gcc -DWINDOWS_OS myprog.c
Structuring the binary code
●
Frequently used functions can be saved in a binary archive files. Ex :
– stdlib → standard library
– stdio → I/O library
– libm → mathematics library
●
The caller program needs :
– The header file of the library at compilation time
– The binary file of the library at linking time
●
The library name should start with “lib” prefix.
●
The location of library can be specified using -L of the linker. Ex.
– If the library directory is /home/user/lib → add -L /home/user/lib option to the linked
●
To link with “libname” library, we need to use -lname option while linking. Ex :
– to link with libm → -lm
– to link with libpthreads → -lpthreads.
Static vs dynamic library
●
Static library
– The binary code of a called function is included in the executable file of the
called program.
●
Advantage : statically liked executable file are more portables since
they contain everything is shipped together
●
Drawbacks :
– Executable files have larger size.
– Code duplication among different programs.
– If a library changes, all the executable files using it should be compiled again.
Static vs dynamic library
●
Dynamic library
– The binary code is loaded at run time phase
●
Advantages :
– code maintainability and update is more easy
●
Drawbacks :
– Slow program startup.
– The dynamic library used while linking should be compatible with the
ones installed in the run time platform.
Static vs dynamic library
●
How to find the location of a dynamic library at
run time ?
– Set the location in the binary file at linking time :
●
-rpath linker option
●
Or, change the LD_RUN_PATH environment variable.
– Set the location at run time :
●
change the LD_LIBRARY_PATH environment variable.
Create static and dynamic library
●
Static library
– $ ar -rcs libname.a file1.o file2.o file3.o …
●
Dynamic library : to build a dynamically linked library, the
object file(s) in the library must be built with position
independent code (using -fPIC)
– $ gcc -fPIC -c file1.c -o file1.o
– $ gcc -fPIC -c file2.c -o file2.o
– $ gcc -shared -o libname.so file1.o file2.o
ldd command
●
ldd command : print shared object (dynamic libraries) dependencies
– $ ldd /usr/bin/ls
linux-vdso.so.1 (0x00007ffff8ff1000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fe18c862000)
libcap.so.2 => /lib64/libcap.so.2 (0x00007fe18c65c000)
libc.so.6 => /lib64/libc.so.6 (0x00007fe18c297000)
libpcre2-8.so.0 => /lib64/libpcre2-8.so.0 (0x00007fe18c013000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fe18be0f000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe18ccaf000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fe18bbef000)
make tool
●
Make : utility to maintain groups of programs
– determines automatically which pieces of a large
program need to be recompiled, and issue the
commands to recompile them.
– make tool compares files timestamps to determine
outdated pieces of programs
Make tool
●
Dependency rules are set in a file named
Makefile
●
The name of the rules files can be set using -f
option
Makefile syntax
targets : dependencies
command1
command2
...
Makefile syntax
out.o : out.c out.h
gcc -c -o out.o out.c
out.exe : out.o
gcc -o out.exe out.o
...
Makefile syntax
●
Automatic variable
out.o: src.c src.h
$@ # "out.o" (target)
$< # "src.c" (first prerequisite)
$^ # "src.c src.h" (all prerequisites)
$+ # prerequisites (all, with duplication)
$? # prerequisites (new ones)
Makefile implicit rules
●
To use implicit rules :
– write a rule with no recipe, no command.
– Or don’t write a rule at all.
●
Then make will figure out which implicit rule to
use based on which kind of source file exists or
can be made.
Makefile implicit rules
●
Example
prog.o:
is equivalent to :