300 likes | 311 Views
Learn about useful commands and options in C programming for compiling and running single-module programs using the gcc compiler.
E N D
Some Compiler Options $ gcc -c Just compile, don’t link $ gcc -E Just preprocess, print out source $ gcc -S Produce assembly code $ gcc -o <file> Save result into <file> $ gcc -I<path> Add <path> to search for include files $ gcc -D<symbol> Define the macro symbol <symbol> Equivalent to #define <symbol>
The Link Editor (ld) The compiler produces machine code and a table of names (symbol table) of variables and procedures This is called an object file (.o) The link editor (or linker) takes several object files and merges them, by associating the symbols with machine code addresses Performs relocation Works with position-independent code (PIC)
Symbol Table Example #include <stdio.h> #include <math.h> int im_a_global; int main(void) { double pi; pi = 4.0*atan(1.0); printf(“Pi is %lf\n”,pi); return 0; } $ gcc –c pi.c $ nm pi.o 00000004 C im_a_global 00000000 T main U printf $ gcc –o pi pi.o $ ./pi Pi is 3.141593
Executable Files The link editor produces an executable file which is compatible with the program loader Format: ELF (Executable and Linking Format) When a program is executed, the program loader copies the sections of the executable file into the virtual address space and execution can begin
Executable Files, Example $ gcc –o pi pi.c $ nm ./pi 08049508 D _DYNAMIC 080495dc D _GLOBAL_OFFSET_TABLE_ 08048470 T __i686.get_pc_thunk.bx 080494f4 A __init_array_end 080494f4 A __init_array_start 08048420 T __libc_csu_fini 080483c0 T __libc_csu_init U __libc_start_main@@GLIBC_2.0 080495fc A _edata 08049604 A _end 080484b4 T _fini 080484d0 R _fp_hw 08048284 T _init 080482d0 T _start 08049600 B im_a_global 08048374 T main 080495f8 d p.4385 U printf@@GLIBC_2.0 #include <stdio.h> #include <math.h> int im_a_global; int main(void) { double pi; pi = 4.0*atan(1.0); printf(“Pi is %lf\n”,pi); return 0; }
Multimodule Program • Keep reusable functions in separate modules • Create header power.h (prototype) int power (int x, int n); • Create source file power.c #include “power.h” int power (int x, int n){ return n==0? 1: x*power(x, n-1);} • main.c #include<stdio.h> #include “power.h” void main(){printf (“%d\n”, power (5,6))};
make, Maintenance Tool make is usually used to compile and link programs consisting of several files A program often uses, or depends on, several other modules or libraries A Makefile specifies the dependencies between the program and the modules If a file changes, make recompiles only those files which depend on the changed file
The UNIX File-Dependency System:make • A makefile is a list of all interdependencies for each executable file. • make [–f makefile] • targetList: dependencyList commandList • Each line in command list must start with a tab character. • Rules must be separated by at least one blank line. <TAB>
make, Concepts target: A file that depends on other files dependencies: A list of files that a target depends on rule: How to build a target
Example of Makefile main1: main.o power.o cc power.o main.o -o main1 main.o: main.c power.h cc -c main.c power.o: power.c power.h cc -c power.c
The Order of Make Rules • Starts from the first rule and creates a tree with target files at the root and the dependency files as children. main1 1 7 2 main.o 5 power.o 3 6 power.c power.h power.h 6 3 7 4 main.c 4 1 5 2
Order of Make rules • The make utility then works up the tree • From the leaf nodes to the root node • Looking to see if the last modification time of each node is more recent than the last modification time of the immediate parent node • If so, the associated parent's rule is executed
Simplifying Make Files • main1: main.o power.o cc power.o main.o -o main1 main.o: main.c power.h cc -c main.c power.o: power.c power.h cc -c power.c • xxx.o: reverse.c reverse.h gcc -c xxx.c • Knows that <file>.o is dependent on <file>.c main1: main.o power.o • cc power.o main.o -o main1 • main.o: power.h • power.o: power.h
touch Utility • touch -c {fileName}+ • Updates the last modification and access times of the named files to the current time. • By default, if a specified file does not exist it is created with zero size. • To prevent this default, use -c option. • Use touch to force make to recompile files.
ARCHIVING MODULES: AR • ar key archivename {file}* • Creates archive files (.a) • Key: • r: adds file to an archive or replaces it there • d: delete a file from archive • q: append a file to end of archive • t: displays table of contents • x: copies archive content to current directory • v: generates verbose output
GNU Profiler Utility gprof profiles a running program lets you see how the program spends its time Must use -pg option with gcc Creates file gmon.out by default
[c33225@snowball ~]$ cc -pg power.c main.c -o main3[c33225@snowball ~]$ ./main315625[c33225@snowball ~]$ gprof main3Flat profile:Each sample counts as 0.01 seconds. no time accumulated % cumulative self self total time seconds seconds calls Ts/call Ts/call name 0.00 0.00 0.00 1 0.00 0.00 power % the percentage of the total running time of thetime program used by this function. Call graph (explanation follows)granularity: each sample hit covers 2 byte(s) no time propagatedindex % time self children called name 6 power [1] 0.00 0.00 1/1 main [8][1] 0.0 0.00 0.00 1+6 power [1] 6 power [1]-----------------------------------------------
Debuggers A debugger helps you find causes of errors in your code Must use -g option when compiling Executes your code like an interpreter You can step through your program Set breakpoints Print and set variables Catch run-time exceptions Two standard debuggers gdb (GNU) dbx
Debug Information with -g #include <stdio.h> #include <math.h> int im_a_global; int main(void) { double pi; pi = 4.0*atan(1.0); printf(“Pi is %lf\n”,pi); return 0; } $ gcc –c –g pi.c
Using gdb $ gdb ./pi (gdb) break main Breakpoint 1 at 0x8048380: file pi.c, line 10. (gdb) run Starting program: /afs/ir.stanford.edu/users/h/e/henlof/test/trunk/pi Breakpoint 1, main (argc=1 ,..) at debug_me.c:19 (gdb) print pi $2 = 4.8542713620543657e-270 (gdb) next 11 printf("Pi is %lf\n",pi); (gdb) print pi $3 = 3.1415926535897931 (gdb) list 6 int main(void) { 7 8 double pi; 9 10 pi = 4.0*atan(1.0); 11 printf("Pi is %lf\n",pi); 12 13 return 0; 14 } (gdb) where #0 main () at pi.c:11
More on gdb Type help in the gdb prompt help breakpoints, help running gdb can also debug core dumps and attach to already-running processes that you own There is a graphical interface to gdb called the “Dynamic Data Debugger” ddd $ ddd ./a.out Allows you to visualize data and breakpoints
Strip Utility Utility strip removes extra info from a program Useful after debug / profile strip {fileName}+ [c33225@snowball ~]$ ls -l main3 -rwxrwxr-x 1 c33225 c33225 5866 Jul 11 17:30 main3 [c33225@snowball ~]$ strip main3 [c33225@snowball ~]$ ls -l main3 -rwxrwxr-x 1 c33225 c33225 3792 Jul 11 18:01 main3
Review Compiling .c files Including multiple files Using make to compile several related files How to simplify an example makefile touch command