490 likes | 660 Views
Advanced UNIX. 240-491 Special Topics in Comp. Eng. 1 Semester 2, 2000-2001. Objectives of these slides: learn how to write/manage large programs consisting of multiple files, which may use libraries. 13. Large Programs. Overview. 1. Independent Compilation 2. Global Information
E N D
Advanced UNIX 240-491 Special Topics in Comp. Eng. 1Semester 2, 2000-2001 • Objectives of these slides: • learn how to write/manage large programs consisting of multiple files, which may use libraries 13. Large Programs
Overview 1. Independent Compilation 2. Global Information 3. Header Files 4. Information Hiding 5. The makeUtility 6. Libraries 7. A Static Library Example
1. Independent Compilation • Split a large program into two files: main.c others.c :int main(){ ... x = maxi(a, b); ...} : :int maxi(int x,int y){ ... return w;} :
Compilation and Linking • Compilation: $ gcc -c main.c /* produces main.o */ $ gcc -c others.c /* produces others.o */ • Linking: $ gcc -o foo main.o others.o /* creates foo */
Why Split the Code into Files? • Advantages: • reduces the complexity of the complete program by organizing it into separate files • speeds up recompilation: • only recompile what’s needed • linking is faster than compilation continued
Disadvantages: • multiple object files use more storage space • compiling all the separate “.c” files takes longer than a single combined “.c” file
2. Global Information • extern variables • declarations of global variables used across multiple files • function prototypes • add to every file where the function is used • constants, types, macros • repeat in every file that uses them
Example main.c others.c #include <stdio.h>#define SIZE 10int maxi(int x, int y) ;int flag;float f:int main(){ int x, a, b: f = 2.0; x = maxi(a, b); while (x < SIZE) :} : #include <stdio.h>#define SIZE 10int maxi(int x, int y) ; extern int flag;extern float f: int maxi(int x, int y){ ... f = f + 1.0; while (x < SIZE) ... return w;} :
Definition vs. Declaration • float f; int flag; • variable definition: name, type, and storage • extern float f; extern int flag; • variable declaration: name, type • Each variable must have only one definition, but can have many declarations.
3. Header Files • Use a “.h” file to put global information in a single place, and then use #include to include it in all the “.c” files. • Used to store: • constant definitions • type declarations, externdeclarations • macros • function prototypes
Example defs.h #define SIZE 10int maxi(int x, int y); extern int flag;extern float f:
Use main.c others.c #include <stdio.h>#include “defs.h”int flag;float f:int main(){ int x, a, b: f = 2.0; x = maxi(a, b); while (x < SIZE) :} : #include <stdio.h>#include “defs.h” int maxi(int x, int y){ ... f = f + 1.0; while (x < SIZE) ... return w;} :
Compilation / Linking • As before: $ gcc -c main.c $ gcc -c others.c $ gcc -o foo main.o others.o • defs.h must be accessible (i.e. in the same directory).
4. Information Hiding • If a global variable or function definition is preceded by staticthen it can only be accessed by other things in its file. others.c :static int table[SIZE]; :static int search(int key){ ... }int maxi(int a, int b){ ... }
5. The make Utility • Write down the compilation dependencies between files in a “makefile”. • make uses the makefile to decide what to recompile when a file is changed: • make decides on recompilation, not you
5.1. The makefile Format dependency line • target file: list of files--tab-- command line • e.g. foo: main.c others.c defs.h gcc -o foo main.c others.c • Use: make foo makefile
5.2. A more efficient makefile • Split compilation process into 3 stages: foo: main.o others.o gcc -o foo main.o others.omain.o: main.c defs.h gcc -c main.cothers.o: others.c defs.h gcc -c others.c • The compiler will only execute those command lines where the dependent files have changed.
5.3. Using Built-in Rules • make knows the connection between “.c”, “.o” and “.h” files • this means that the makefile can be shorter • foo: main.o others.o gcc -o foo main.o others.omain.o: defs.hothers.o: defs.h or:main.o others.o: defs.h
Changing Rules • make uses cc -cO by default • Change by redefining the CC and CFLAG values at the start of makefile: CC = gccCFLAGS = -g /* options become -cg */
5.4. Declaring Variables • Create the variable OBJS: OBJS = main.o file1.o file2.o \ file3.o file4.o • Use: foo: $(OBJS) gcc -o foo $(OBJS)$(OBJS): defs.h
5.5. Other Uses of makefile • Common addtions to makefile: :test: foo rm -f test.out foo test.in > test.outclean: rm -f $(OBJS) rm -f test.outall: foo test clean
Uses • make foo • make test • make clean • make all
5.6. Options to make • Options Meaning-f Use a file other than makefile.-k Try to continue after a command has failed.-n Only print the commands. • e.g. make -f bm all make -k foo make -n all good for testing the makefile
5.7. Touching Files • touch file • touches the file, updating its modification date • touch foo • updates foo’s modification date • make foo will now cause footo be regenerated since its modification date has changed
6. Libraries • A library is a collection of useful functions (e.g. for graphics manipulation) in a single file. • Linux supports two types of library: • static libraries (files end in '.a') • shared libraries (files end in '.so') continued
When several programs use a static library, they each load a copy into memory • a copy is included inside your program when it is compiled • the object file can be quite large • a static library is sometimes called a archive continued
When several programs use a shared library, only one copy is loaded into memory • it is loaded when the program is first run (if there isn't a copy already in memory) • less memory is used • Linux is moving over to shared libraries • based on the ELF binary format
6.1. The Linking Stage • Linking example: $ gcc -o foo main.o others.o • The linker does two main tasks: • 1) matches the function calls in main.o, others.o to the function implementations in those files; • 2) matches the function calls to the standard libraries (e.g. printf()). continued
The compiler knows which libraries to use because of the “.h” files that you have included. • The library function implementations are loaded automatically for the standard C library (libc.so) • other libraries must be specified on the gcc command line continued
A library consists of object files • only the object files containing the functions used in your program are loaded • this means it is best to separate functions into many (small) object files inside a library • then less of the library will be loaded
6.2. Library Locations • Standard libraries are in /lib and /usr/lib • Other shared library directories are given in /etc/ld.so.conf • on calvin: $ cat /etc/ld.so.conf/usr/X11R6/lib/Xaw3d/usr/X11R6/lib/usr/lib/libc5-compat/lib/libc5-compat
6.3. Using Libraries • Use the -l option of gcc to specify a library: $ gcc -o examp examp.c -lm • gcc will try to use a shared library (libm.so); failing that it will try to use a static library (libm.a) continued
the library must be supplied last, so all the functions are known • Use a library's full name: $ gcc -o examp examp.c /usr/lib/libm.so • Use a library in a non-standard directory: $ gcc -o foobar -L/usr/foobar/lib fred.c -lfb
6.4. Comparing Static and Shared • /* sqrtest.c */#include <stdio.h>#include <math.h>int main(){ double x = 9.0; printf("%f\n", sqrt(x)); return 0;} continued
ldd prints details on the shared libraries used. • gcc -o sqrtest sqrtest.c -lm$ sqrtest3.000000$ ldd sqrtest libm.so.6 => /lib/libm.so.6 (0x40019000)libc.so.6 => /lib/libc.so.6 (0x40036000)/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)$ ls -alt sqrtest -rwxrwxr-x 1 ad users 4964 Dec 1 14:40 sqrtest* continued
use static libraries • $ gcc -o sqrtest sqrtest.c -static -lm$ sqrtest3.000000$ ldd sqrtest statically linked (ELF)$ ls -alt sqrtest-rwxrwxr-x 1 ad users 246373 Dec 1 14:40 sqrtest* bigger since the libraries are added in at compile time.
6.5. Shared Library Links • When a programmer specifies a shared library (e.g. libm.so), it is actually a link to a soname file • libm.so libm.so.5 • At compile time, the soname filename is stored in the object file • no library code, so the object file is small link continued
When the object file is executed, the soname is used to load the real shared library • the soname file is often just a link to the real library • libm.so.5 libm.so.5.0.9 link
6.7. Some Common Shared Libraries • libc.so standard C library • libg++.so standard C++ library • libgdbm.so GNU dbm database • libncurses.so terminal-based graphics • libtiff.so TIFF image manipulation
6.8. Dynamic Libraries • A dynamic library is a variant of a shared library • the library code is loaded at run time, but under the control of the program itself • the program can also unload a library • useful for programs that occasionally use very big libraries
6.9. The old '.sa' Format • Older versions of Linux used the a.out binary file format • shared library filenames in that file format end with '.sa' • you should not see them in new Linux's
7. A Static Library Example • Static libraries are fine for libraries which will not be heavily used. • Creating shared libraries still varies between UNIXes • but static library creation has been standardized
7.1. A Static Library for Graphics • graphics.h: typedef struct { int x, y, z; ...} Image;void display_im(Image im);void move_im(Image im, int x, int y, int z); :
Function Implementations • idisplay.c: #include “graphics.h”void display_im(Image im){ ... } • imove.c: #include “graphics.h”void move_im(Image im, int x, int y, int z){ ... }
7.2. Creating the Static Library • Compile: $ gcc -c idisplay.c $ gcc -c imove.c • Build a static library called glib.a: $ ar ruvs glib.a idisplay.o imove.o • The library is made from two object files and a symbol definition file (a list of function names, constants used in the “.o” files).
ar Options • Operator Meaningr Replace files.u Update files if changed.v Verbose.s Create symbol definition file.
Other Commands • Some versions of ar do not have an “s” option, so you must use ranlib: $ ar ruv glib.a idisplay.o imove.o $ ranlib glib.a • Listing the object files in a library with “t”: $ ar tv glib.a /* verbose listing */
7.3. Using the Library main.c foop.c #include <stdio.h>#include “graphics.h” :int main(){ Image i; ... display_im(i); foop(i); move_im(i, 2,3,4): ...} #include <stdio.h>#include “graphics.h” :void foop(Image j){ Image i; ... display_im(i); display_im(j); ...}
Compilation / Linking • Compile and link: $ gcc -c main.c $ gcc -c foop.c $ gcc -o foo main.o foop.o glib.a • The “.a” file must be at the end so that all the symbols uses in the object files are known. • The linker links in the files from the “.a” library which contain functions, constants, etc. used by the “.c” code.