歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

GCC編譯器入門

GCC(GNU Compiler Collection,GNU編譯器套件),是由 GNU 開發的編程語言編譯器。它是以GPL許可證所發行的自由軟件,也是 GNU計劃的關鍵部分。GCC原本作為GNU操作系統的官方編譯器,現已被大多數類Unix操作系統(如Linux、BSD、Mac OS X等)采納為標准的編譯器,GCC同樣適用於微軟的Windows。 GCC是自由軟件過程發展中的著名例子,由自由軟件基金會以GPL協議發布。它處理能夠高效的編譯C語言以外,還可以編譯其他語言。並且,現在的GCC已經不光包括編譯器本身,還包含了編譯過程中的工具鏈。

1 GCC編譯流程

在學習使用GCC編譯程序之前,首先要知道編譯C程序的基本流程,一般情況下分為下面四步:

(1) 對C語言進行預處理,生成*.i文件。

(2) 將上一步生成的*.i文件編譯生成匯編語言文件,後綴名為*.s

(3) 將匯編語言文件*.s經過匯編,生成目標文件,後綴名為*.o

(4) 將各個模塊的*.o文件鏈接起來,生成最終的可執行文件 

2 GCC常用選項

GCC的編譯選項非常多,現在有上千個,但是我們常用的並不多,下面我們只介紹其中非常實用的幾個。

在這之前,我們先編寫下面的幾個源文件,以備測試只用。 

 1 //main.c
 2 #include <stdio.h>
 3 
 4 extern int add(int a, int b);
 5 extern int mul(int a, int b);
 6 
 7 int main(void)
 8 {
 9     int a = 10, b = 5;
10     int result;
11     
12     result = add(a, mul(a,  b));
13     printf("result = %d\n", result);
14     return 0;
15 }
main.c
1 //test1.c
2 int add(int a, int b)
3 {
4     return a+b;
5 }
test1.c
1 //test2.c
2 int mul(int a, int b)
3 {
4     return a*b;
5 }
test2.c

1 //test2.c
2 int mul(int a, int b)
3 {
4    return a*b;
5 }

2.1 -c選項

  該選項(小寫c)表示編譯、匯編指定的源文件,但是不進行鏈接。該選項的使用方法如下:

gcc -c source.c

也就是在-c選項後面緊跟要編譯、匯編的C源文件,最終生成與源文件名稱相同,但是後綴為*.o結尾的目標文件。

linuxidc@xiaomanon-machine:~/Documents/c_code$ ls
main.c  test1.c  test2.c
linuxidc@xiaomanon-machine:~/Documents/c_code$ gcc -c test1.c
linuxidc@xiaomanon-machine:~/Documents/c_code$ ls
main.c  test1.c  test1.o  test2.c

可以看到,使用-c選項編譯之後生成了對應的*.o目標文件。當然,你也可以一次性指定多個C源文件,使用-c選項後,會針對每一個C源文件生成一個相應的*.o目標文件。

linuxidc@xiaomanon-machine:~/Documents/c_code$ gcc -c test2.c main.c
linuxidc@xiaomanon-machine:~/Documents/c_code$ ls
main.c  main.o  test1.c  test1.o  test2.c  test2.o

 

2.2 -S選項

  該選項(大寫S)將C語言源文件編譯生成匯編語言文件,但是並不匯編該程序。注意:匯編過程的作用是將匯編語言文件編譯成目標文件*.o,而-S選項的作用是得到匯編語言文件*.s。該選項的使用方法為:

gcc -S source.c

使用該選項,最終生成與源文件名稱相同,但是後綴為*.s結尾的匯編語言文件。

linuxidc@xiaomanon-machine:~/Documents/c_code$ gcc -S test1.c
linuxidc@xiaomanon-machine:~/Documents/c_code$ ls
main.c  test1.c  test1.s  test2.c

當然,輸入的源文件也不止一個,你可以編譯當前目錄下的所有C語言源文件:

linuxidc@xiaomanon-machine:~/Documents/c_code$ gcc -S *.c
linuxidc@xiaomanon-machine:~/Documents/c_code$ ls
main.c  main.s  test1.c  test1.s  test2.c  test2.s

我們也可以查看生成的匯編語言代碼:

 1     .file    "test1.c"
 2     .text
 3     .globl    add
 4     .type    add, @function
 5 add:
 6 .LFB0:
 7     .cfi_startproc
 8     pushl    %ebp
 9     .cfi_def_cfa_offset 8
10     .cfi_offset 5, -8
11     movl    %esp, %ebp
12     .cfi_def_cfa_register 5
13     movl    12(%ebp), %eax
14     movl    8(%ebp), %edx
15     addl    %edx, %eax
16     popl    %ebp
17     .cfi_restore 5
18     .cfi_def_cfa 4, 4
19     ret
20     .cfi_endproc
21 .LFE0:
22     .size    add, .-add
23     .ident    "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
24     .section    .note.GNU-stack,"",@progbits
test1.s

 

2.3 -E選項

  該選項對C語言源文件進行預處理,但是並不編譯該程序。對於一般的預處理問題(比如,宏的展開問題、文件的包含問題等),可以使用這個選項進行查看。另外,如果直接使用此選項,程序會將預處理結果直接輸出到終端,不便於查看,因此,一般可以使用重定向將程序輸出結果保存到一個文本文件中,格式如下:

gcc -E source.c > output

如果我們對main.c執行預編譯,得到的output文件內容如下:

  1 # 1 "main.c"
  2 # 1 "<command-line>"
  3 # 1 "/usr/include/stdc-predef.h" 1 3 4
  4 # 1 "<command-line>" 2
  5 # 1 "main.c"
  6 
  7 # 1 "/usr/include/stdio.h" 1 3 4
  8 # 27 "/usr/include/stdio.h" 3 4
  9 # 1 "/usr/include/features.h" 1 3 4
 10 # 374 "/usr/include/features.h" 3 4
 11 # 1 "/usr/include/i386-linux-gnu/sys/cdefs.h" 1 3 4
 12 # 385 "/usr/include/i386-linux-gnu/sys/cdefs.h" 3 4
 13 # 1 "/usr/include/i386-linux-gnu/bits/wordsize.h" 1 3 4
 14 # 386 "/usr/include/i386-linux-gnu/sys/cdefs.h" 2 3 4
 15 # 375 "/usr/include/features.h" 2 3 4
 16 # 398 "/usr/include/features.h" 3 4
 17 # 1 "/usr/include/i386-linux-gnu/gnu/stubs.h" 1 3 4
 18 
 19 
 20 
 21 
 22 
 23 
 24 # 1 "/usr/include/i386-linux-gnu/gnu/stubs-32.h" 1 3 4
 25 # 8 "/usr/include/i386-linux-gnu/gnu/stubs.h" 2 3 4
 26 # 399 "/usr/include/features.h" 2 3 4
 27 # 28 "/usr/include/stdio.h" 2 3 4
 28 
 29 
 30 
 31 
 32 
 33 # 1 "/usr/lib/gcc/i686-linux-gnu/4.8/include/stddef.h" 1 3 4
 34 # 212 "/usr/lib/gcc/i686-linux-gnu/4.8/include/stddef.h" 3 4
 35 typedef unsigned int size_t;
 36 # 34 "/usr/include/stdio.h" 2 3 4
 37 
 38 # 1 "/usr/include/i386-linux-gnu/bits/types.h" 1 3 4
 39 # 27 "/usr/include/i386-linux-gnu/bits/types.h" 3 4
 40 # 1 "/usr/include/i386-linux-gnu/bits/wordsize.h" 1 3 4
 41 # 28 "/usr/include/i386-linux-gnu/bits/types.h" 2 3 4
 42 
 43 
 44 typedef unsigned char __u_char;
 45 typedef unsigned short int __u_short;
 46 typedef unsigned int __u_int;
 47 typedef unsigned long int __u_long;
 48 
 49 
 50 typedef signed char __int8_t;
 51 typedef unsigned char __uint8_t;
 52 typedef signed short int __int16_t;
 53 typedef unsigned short int __uint16_t;
 54 typedef signed int __int32_t;
 55 typedef unsigned int __uint32_t;
 56 
 57 
 58 
 59 
 60 __extension__ typedef signed long long int __int64_t;
 61 __extension__ typedef unsigned long long int __uint64_t;
 62 
 63 
 64 
 65 
 66 
 67 
 68 
 69 __extension__ typedef long long int __quad_t;
 70 __extension__ typedef unsigned long long int __u_quad_t;
 71 # 121 "/usr/include/i386-linux-gnu/bits/types.h" 3 4
 72 # 1 "/usr/include/i386-linux-gnu/bits/typesizes.h" 1 3 4
 73 # 122 "/usr/include/i386-linux-gnu/bits/types.h" 2 3 4
 74 
 75 
 76 __extension__ typedef __u_quad_t __dev_t;
 77 __extension__ typedef unsigned int __uid_t;
 78 __extension__ typedef unsigned int __gid_t;
 79 __extension__ typedef unsigned long int __ino_t;
 80 __extension__ typedef __u_quad_t __ino64_t;
 81 __extension__ typedef unsigned int __mode_t;
 82 __extension__ typedef unsigned int __nlink_t;
 83 __extension__ typedef long int __off_t;
 84 __extension__ typedef __quad_t __off64_t;
 85 __extension__ typedef int __pid_t;
 86 __extension__ typedef struct { int __val[2]; } __fsid_t;
 87 __extension__ typedef long int __clock_t;
 88 __extension__ typedef unsigned long int __rlim_t;
 89 __extension__ typedef __u_quad_t __rlim64_t;
 90 __extension__ typedef unsigned int __id_t;
 91 __extension__ typedef long int __time_t;
 92 __extension__ typedef unsigned int __useconds_t;
 93 __extension__ typedef long int __SUSEconds_t;
 94 
 95 __extension__ typedef int __daddr_t;
 96 __extension__ typedef int __key_t;
 97 
 98 
 99 __extension__ typedef int __clockid_t;
100 
101 
102 __extension__ typedef void * __timer_t;
103 
104 
105 __extension__ typedef long int __blksize_t;
106 
107 
108 
109 
110 __extension__ typedef long int __blkcnt_t;
111 __extension__ typedef __quad_t __blkcnt64_t;
112 
113 
114 __extension__ typedef unsigned long int __fsblkcnt_t;
115 __extension__ typedef __u_quad_t __fsblkcnt64_t;
116 
117 
118 __extension__ typedef unsigned long int __fsfilcnt_t;
119 __extension__ typedef __u_quad_t __fsfilcnt64_t;
120 
121 
122 __extension__ typedef int __fsword_t;
123 
124 __extension__ typedef int __ssize_t;
125 
126 
127 __extension__ typedef long int __syscall_slong_t;
128 
129 __extension__ typedef unsigned long int __syscall_ulong_t;
130 
131 
132 
133 typedef __off64_t __loff_t;
134 typedef __quad_t *__qaddr_t;
135 typedef char *__caddr_t;
136 
137 
138 __extension__ typedef int __intptr_t;
139 
140 
141 __extension__ typedef unsigned int __socklen_t;
142 # 36 "/usr/include/stdio.h" 2 3 4
143 # 44 "/usr/include/stdio.h" 3 4
144 struct _IO_FILE;
145 
146 
147 
148 typedef struct _IO_FILE FILE;
149 
150 
151 
152 
153 
154 # 64 "/usr/include/stdio.h" 3 4
155 typedef struct _IO_FILE __FILE;
156 # 74 "/usr/include/stdio.h" 3 4
157 # 1 "/usr/include/libio.h" 1 3 4
158 # 31 "/usr/include/libio.h" 3 4
159 # 1 "/usr/include/_G_config.h" 1 3 4
160 # 15 "/usr/include/_G_config.h" 3 4
161 # 1 "/usr/lib/gcc/i686-linux-gnu/4.8/include/stddef.h" 1 3 4
162 # 16 "/usr/include/_G_config.h" 2 3 4
163 
164 
165 
166 
167 # 1 "/usr/include/wchar.h" 1 3 4
168 # 82 "/usr/include/wchar.h" 3 4
169 typedef struct
170 {
171   int __count;
172   union
173   {
174 
175     unsigned int __wch;
176 
177 
178 
179     char __wchb[4];
180   } __value;
181 } __mbstate_t;
182 # 21 "/usr/include/_G_config.h" 2 3 4
183 typedef struct
184 {
185   __off_t __pos;
186   __mbstate_t __state;
187 } _G_fpos_t;
188 typedef struct
189 {
190   __off64_t __pos;
191   __mbstate_t __state;
192 } _G_fpos64_t;
193 # 32 "/usr/include/libio.h" 2 3 4
194 # 49 "/usr/include/libio.h" 3 4
195 # 1 "/usr/lib/gcc/i686-linux-gnu/4.8/include/stdarg.h" 1 3 4
196 # 40 "/usr/lib/gcc/i686-linux-gnu/4.8/include/stdarg.h" 3 4
197 typedef __builtin_va_list __gnuc_va_list;
198 # 50 "/usr/include/libio.h" 2 3 4
199 # 144 "/usr/include/libio.h" 3 4
200 struct _IO_jump_t; struct _IO_FILE;
201 # 154 "/usr/include/libio.h" 3 4
202 typedef void _IO_lock_t;
203 
204 
205 
206 
207 
208 struct _IO_marker {
209   struct _IO_marker *_next;
210   struct _IO_FILE *_sbuf;
211 
212 
213 
214   int _pos;
215 # 177 "/usr/include/libio.h" 3 4
216 };
217 
218 
219 enum __codecvt_result
220 {
221   __codecvt_ok,
222   __codecvt_partial,
223   __codecvt_error,
224   __codecvt_noconv
225 };
226 # 245 "/usr/include/libio.h" 3 4
227 struct _IO_FILE {
228   int _flags;
229 
230 
231 
232 
233   char* _IO_read_ptr;
234   char* _IO_read_end;
235   char* _IO_read_base;
236   char* _IO_write_base;
237   char* _IO_write_ptr;
238   char* _IO_write_end;
239   char* _IO_buf_base;
240   char* _IO_buf_end;
241 
242   char *_IO_save_base;
243   char *_IO_backup_base;
244   char *_IO_save_end;
245 
246   struct _IO_marker *_markers;
247 
248   struct _IO_FILE *_chain;
249 
250   int _fileno;
251 
252 
253 
254   int _flags2;
255 
256   __off_t _old_offset;
257 
258 
259 
260   unsigned short _cur_column;
261   signed char _vtable_offset;
262   char _shortbuf[1];
263 
264 
265 
266   _IO_lock_t *_lock;
267 # 293 "/usr/include/libio.h" 3 4
268   __off64_t _offset;
269 # 302 "/usr/include/libio.h" 3 4
270   void *__pad1;
271   void *__pad2;
272   void *__pad3;
273   void *__pad4;
274   size_t __pad5;
275 
276   int _mode;
277 
278   char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)];
279 
280 };
281 
282 
283 typedef struct _IO_FILE _IO_FILE;
284 
285 
286 struct _IO_FILE_plus;
287 
288 extern struct _IO_FILE_plus _IO_2_1_stdin_;
289 extern struct _IO_FILE_plus _IO_2_1_stdout_;
290 extern struct _IO_FILE_plus _IO_2_1_stderr_;
291 # 338 "/usr/include/libio.h" 3 4
292 typedef __ssize_t __io_read_fn (void *__cookie, char *__buf, size_t __nbytes);
293 
294 
295 
296 
297 
298 
299 
300 typedef __ssize_t __io_write_fn (void *__cookie, const char *__buf,
301      size_t __n);
302 
303 
304 
305 
306 
307 
308 
309 typedef int __io_seek_fn (void *__cookie, __off64_t *__pos, int __w);
310 
311 
312 typedef int __io_close_fn (void *__cookie);
313 # 390 "/usr/include/libio.h" 3 4
314 extern int __underflow (_IO_FILE *);
315 extern int __uflow (_IO_FILE *);
316 extern int __overflow (_IO_FILE *, int);
317 # 434 "/usr/include/libio.h" 3 4
318 extern int _IO_getc (_IO_FILE *__fp);
319 extern int _IO_putc (int __c, _IO_FILE *__fp);
320 extern int _IO_feof (_IO_FILE *__fp) __attribute__ ((__nothrow__ , __leaf__));
321 extern int _IO_ferror (_IO_FILE *__fp) __attribute__ ((__nothrow__ , __leaf__));
322 
323 extern int _IO_peekc_locked (_IO_FILE *__fp);
324 
325 
326 
327 
328 
329 extern void _IO_flockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));
330 extern void _IO_funlockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));
331 extern int _IO_ftrylockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));
332 # 464 "/usr/include/libio.h" 3 4
333 extern int _IO_vfscanf (_IO_FILE * __restrict, const char * __restrict,
334    __gnuc_va_list, int *__restrict);
335 extern int _IO_vfprintf (_IO_FILE *__restrict, const char *__restrict,
336     __gnuc_va_list);
337 extern __ssize_t _IO_padn (_IO_FILE *, int, __ssize_t);
338 extern size_t _IO_sgetn (_IO_FILE *, void *, size_t);
339 
340 extern __off64_t _IO_seekoff (_IO_FILE *, __off64_t, int, int);
341 extern __off64_t _IO_seekpos (_IO_FILE *, __off64_t, int);
342 
343 extern void _IO_free_backup_area (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));
344 # 75 "/usr/include/stdio.h" 2 3 4
345 
346 
347 
348 
349 typedef __gnuc_va_list va_list;
350 # 90 "/usr/include/stdio.h" 3 4
351 typedef __off_t off_t;
352 # 102 "/usr/include/stdio.h" 3 4
353 typedef __ssize_t ssize_t;
354 
355 
356 
357 
358 
359 
360 
361 typedef _G_fpos_t fpos_t;
362 
363 
364 
365 
366 # 164 "/usr/include/stdio.h" 3 4
367 # 1 "/usr/include/i386-linux-gnu/bits/stdio_lim.h" 1 3 4
368 # 165 "/usr/include/stdio.h" 2 3 4
369 
370 
371 
372 extern struct _IO_FILE *stdin;
373 extern struct _IO_FILE *stdout;
374 extern struct _IO_FILE *stderr;
375 
376 
377 
378 
379 
380 
381 
382 extern int remove (const char *__filename) __attribute__ ((__nothrow__ , __leaf__));
383 
384 extern int rename (const char *__old, const char *__new) __attribute__ ((__nothrow__ , __leaf__));
385 
386 
387 
388 
389 extern int renameat (int __oldfd, const char *__old, int __newfd,
390        const char *__new) __attribute__ ((__nothrow__ , __leaf__));
391 
392 
393 
394 
395 
396 
397 
398 
399 extern FILE *tmpfile (void) ;
400 # 209 "/usr/include/stdio.h" 3 4
401 extern char *tmpnam (char *__s) __attribute__ ((__nothrow__ , __leaf__)) ;
402 
403 
404 
405 
406 
407 extern char *tmpnam_r (char *__s) __attribute__ ((__nothrow__ , __leaf__)) ;
408 # 227 "/usr/include/stdio.h" 3 4
409 extern char *tempnam (const char *__dir, const char *__pfx)
410      __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) ;
411 
412 
413 
414 
415 
416 
417 
418 
419 extern int fclose (FILE *__stream);
420 
421 
422 
423 
424 extern int fflush (FILE *__stream);
425 
426 # 252 "/usr/include/stdio.h" 3 4
427 extern int fflush_unlocked (FILE *__stream);
428 # 266 "/usr/include/stdio.h" 3 4
429 
430 
431 
432 
433 
434 
435 extern FILE *fopen (const char *__restrict __filename,
436       const char *__restrict __modes) ;
437 
438 
439 
440 
441 extern FILE *freopen (const char *__restrict __filename,
442         const char *__restrict __modes,
443         FILE *__restrict __stream) ;
444 # 295 "/usr/include/stdio.h" 3 4
445 
446 # 306 "/usr/include/stdio.h" 3 4
447 extern FILE *fdopen (int __fd, const char *__modes) __attribute__ ((__nothrow__ , __leaf__)) ;
448 # 319 "/usr/include/stdio.h" 3 4
449 extern FILE *fmemopen (void *__s, size_t __len, const char *__modes)
450   __attribute__ ((__nothrow__ , __leaf__)) ;
451 
452 
453 
454 
455 extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) __attribute__ ((__nothrow__ , __leaf__)) ;
456 
457 
458 
459 
460 
461 
462 extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) __attribute__ ((__nothrow__ , __leaf__));
463 
464 
465 
466 extern int setvbuf (FILE *__restrict __stream, char *__restrict __buf,
467       int __modes, size_t __n) __attribute__ ((__nothrow__ , __leaf__));
468 
469 
470 
471 
472 
473 extern void setbuffer (FILE *__restrict __stream, char *__restrict __buf,
474          size_t __size) __attribute__ ((__nothrow__ , __leaf__));
475 
476 
477 extern void setlinebuf (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
478 
479 
480 
481 
482 
483 
484 
485 
486 extern int fprintf (FILE *__restrict __stream,
487       const char *__restrict __format, ...);
488 
489 
490 
491 
492 extern int printf (const char *__restrict __format, ...);
493 
494 extern int sprintf (char *__restrict __s,
495       const char *__restrict __format, ...) __attribute__ ((__nothrow__));
496 
497 
498 
499 
500 
501 extern int vfprintf (FILE *__restrict __s, const char *__restrict __format,
502        __gnuc_va_list __arg);
503 
504 
505 
506 
507 extern int vprintf (const char *__restrict __format, __gnuc_va_list __arg);
508 
509 extern int vsprintf (char *__restrict __s, const char *__restrict __format,
510        __gnuc_va_list __arg) __attribute__ ((__nothrow__));
511 
512 
513 
514 
515 
516 extern int snprintf (char *__restrict __s, size_t __maxlen,
517        const char *__restrict __format, ...)
518      __attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3, 4)));
519 
520 extern int vsnprintf (char *__restrict __s, size_t __maxlen,
521         const char *__restrict __format, __gnuc_va_list __arg)
522      __attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3, 0)));
523 
524 # 412 "/usr/include/stdio.h" 3 4
525 extern int vdprintf (int __fd, const char *__restrict __fmt,
526        __gnuc_va_list __arg)
527      __attribute__ ((__format__ (__printf__, 2, 0)));
528 extern int dprintf (int __fd, const char *__restrict __fmt, ...)
529      __attribute__ ((__format__ (__printf__, 2, 3)));
530 
531 
532 
533 
534 
535 
536 
537 
538 extern int fscanf (FILE *__restrict __stream,
539      const char *__restrict __format, ...) ;
540 
541 
542 
543 
544 extern int scanf (const char *__restrict __format, ...) ;
545 
546 extern int sscanf (const char *__restrict __s,
547      const char *__restrict __format, ...) __attribute__ ((__nothrow__ , __leaf__));
548 # 443 "/usr/include/stdio.h" 3 4
549 extern int fscanf (FILE *__restrict __stream, const char *__restrict __format, ...) __asm__ ("" "__isoc99_fscanf")
550 
551                                ;
552 extern int scanf (const char *__restrict __format, ...) __asm__ ("" "__isoc99_scanf")
553                               ;
554 extern int sscanf (const char *__restrict __s, const char *__restrict __format, ...) __asm__ ("" "__isoc99_sscanf") __attribute__ ((__nothrow__ , __leaf__))
555 
556                       ;
557 # 463 "/usr/include/stdio.h" 3 4
558 
559 
560 
561 
562 
563 
564 
565 
566 extern int vfscanf (FILE *__restrict __s, const char *__restrict __format,
567       __gnuc_va_list __arg)
568      __attribute__ ((__format__ (__scanf__, 2, 0))) ;
569 
570 
571 
572 
573 
574 extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg)
575      __attribute__ ((__format__ (__scanf__, 1, 0))) ;
576 
577 
578 extern int vsscanf (const char *__restrict __s,
579       const char *__restrict __format, __gnuc_va_list __arg)
580      __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__format__ (__scanf__, 2, 0)));
581 # 494 "/usr/include/stdio.h" 3 4
582 extern int vfscanf (FILE *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vfscanf")
583 
584 
585 
586      __attribute__ ((__format__ (__scanf__, 2, 0))) ;
587 extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vscanf")
588 
589      __attribute__ ((__format__ (__scanf__, 1, 0))) ;
590 extern int vsscanf (const char *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vsscanf") __attribute__ ((__nothrow__ , __leaf__))
591 
592 
593 
594      __attribute__ ((__format__ (__scanf__, 2, 0)));
595 # 522 "/usr/include/stdio.h" 3 4
596 
597 
598 
599 
600 
601 
602 
603 
604 
605 extern int fgetc (FILE *__stream);
606 extern int getc (FILE *__stream);
607 
608 
609 
610 
611 
612 extern int getchar (void);
613 
614 # 550 "/usr/include/stdio.h" 3 4
615 extern int getc_unlocked (FILE *__stream);
616 extern int getchar_unlocked (void);
617 # 561 "/usr/include/stdio.h" 3 4
618 extern int fgetc_unlocked (FILE *__stream);
619 
620 
621 
622 
623 
624 
625 
626 
627 
628 
629 
630 extern int fputc (int __c, FILE *__stream);
631 extern int putc (int __c, FILE *__stream);
632 
633 
634 
635 
636 
637 extern int putchar (int __c);
638 
639 # 594 "/usr/include/stdio.h" 3 4
640 extern int fputc_unlocked (int __c, FILE *__stream);
641 
642 
643 
644 
645 
646 
647 
648 extern int putc_unlocked (int __c, FILE *__stream);
649 extern int putchar_unlocked (int __c);
650 
651 
652 
653 
654 
655 
656 extern int getw (FILE *__stream);
657 
658 
659 extern int putw (int __w, FILE *__stream);
660 
661 
662 
663 
664 
665 
666 
667 
668 extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
669      ;
670 # 638 "/usr/include/stdio.h" 3 4
671 extern char *gets (char *__s) __attribute__ ((__deprecated__));
672 
673 
674 # 665 "/usr/include/stdio.h" 3 4
675 extern __ssize_t __getdelim (char **__restrict __lineptr,
676           size_t *__restrict __n, int __delimiter,
677           FILE *__restrict __stream) ;
678 extern __ssize_t getdelim (char **__restrict __lineptr,
679         size_t *__restrict __n, int __delimiter,
680         FILE *__restrict __stream) ;
681 
682 
683 
684 
685 
686 
687 
688 extern __ssize_t getline (char **__restrict __lineptr,
689        size_t *__restrict __n,
690        FILE *__restrict __stream) ;
691 
692 
693 
694 
695 
696 
697 
698 
699 extern int fputs (const char *__restrict __s, FILE *__restrict __stream);
700 
701 
702 
703 
704 
705 extern int puts (const char *__s);
706 
707 
708 
709 
710 
711 
712 extern int ungetc (int __c, FILE *__stream);
713 
714 
715 
716 
717 
718 
719 extern size_t fread (void *__restrict __ptr, size_t __size,
720        size_t __n, FILE *__restrict __stream) ;
721 
722 
723 
724 
725 extern size_t fwrite (const void *__restrict __ptr, size_t __size,
726         size_t __n, FILE *__restrict __s);
727 
728 # 737 "/usr/include/stdio.h" 3 4
729 extern size_t fread_unlocked (void *__restrict __ptr, size_t __size,
730          size_t __n, FILE *__restrict __stream) ;
731 extern size_t fwrite_unlocked (const void *__restrict __ptr, size_t __size,
732           size_t __n, FILE *__restrict __stream);
733 
734 
735 
736 
737 
738 
739 
740 
741 extern int fseek (FILE *__stream, long int __off, int __whence);
742 
743 
744 
745 
746 extern long int ftell (FILE *__stream) ;
747 
748 
749 
750 
751 extern void rewind (FILE *__stream);
752 
753 # 773 "/usr/include/stdio.h" 3 4
754 extern int fseeko (FILE *__stream, __off_t __off, int __whence);
755 
756 
757 
758 
759 extern __off_t ftello (FILE *__stream) ;
760 # 792 "/usr/include/stdio.h" 3 4
761 
762 
763 
764 
765 
766 
767 extern int fgetpos (FILE *__restrict __stream, fpos_t *__restrict __pos);
768 
769 
770 
771 
772 extern int fsetpos (FILE *__stream, const fpos_t *__pos);
773 # 815 "/usr/include/stdio.h" 3 4
774 
775 # 824 "/usr/include/stdio.h" 3 4
776 
777 
778 extern void clearerr (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
779 
780 extern int feof (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
781 
782 extern int ferror (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
783 
784 
785 
786 
787 extern void clearerr_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
788 extern int feof_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
789 extern int ferror_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
790 
791 
792 
793 
794 
795 
796 
797 
798 extern void perror (const char *__s);
799 
800 
801 
802 
803 
804 
805 # 1 "/usr/include/i386-linux-gnu/bits/sys_errlist.h" 1 3 4
806 # 26 "/usr/include/i386-linux-gnu/bits/sys_errlist.h" 3 4
807 extern int sys_nerr;
808 extern const char *const sys_errlist[];
809 # 854 "/usr/include/stdio.h" 2 3 4
810 
811 
812 
813 
814 extern int fileno (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
815 
816 
817 
818 
819 extern int fileno_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
820 # 873 "/usr/include/stdio.h" 3 4
821 extern FILE *popen (const char *__command, const char *__modes) ;
822 
823 
824 
825 
826 
827 extern int pclose (FILE *__stream);
828 
829 
830 
831 
832 
833 extern char *ctermid (char *__s) __attribute__ ((__nothrow__ , __leaf__));
834 # 913 "/usr/include/stdio.h" 3 4
835 extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
836 
837 
838 
839 extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
840 
841 
842 extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
843 # 943 "/usr/include/stdio.h" 3 4
844 
845 # 3 "main.c" 2
846 
847 extern int add(int a, int b);
848 extern int mul(int a, int b);
849 
850 int main(void)
851 {
852  int a = 10, b = 5;
853  int result;
854 
855  result = add(a, mul(a, b));
856  printf("result = %d\n", result);
857  return 0;
858 }
output

當然,我們也可以使用接下來要介紹的-o命令來指定輸出文件名稱,格式如下:

gcc -E source.c -o source.i

使用該命令對main.c進行預處理,得到的main.i文件內容與之前重定向輸出得到的output文件的內容完全相同。

 

2.4 -o選項

  該選項(小寫O)用於將輸入文件編譯後輸出指定名稱的文件。該選項有兩種使用方法,第一種是緊跟gcc命令之後:

gcc -o app source1.c source2.c source3.c

那麼,編譯我們的測試程序可以使用下面的方式:

linuxidc@xiaomanon-machine:~/Documents/c_code$ gcc -o app *.c
linuxidc@xiaomanon-machine:~/Documents/c_code$ ls
app  main.c  test1.c  test2.c
linuxidc@xiaomanon-machine:~/Documents/c_code$ ./app 
result = 60

還有另外一種方式,即-o選項放置在最後:

gcc source1.c source2.c source3.c -o app 

這種方式的邏輯性更強,語義可以理解為編譯C語言源文件得到最終的可執行程序app,使用這種方式編譯我們的測試程序過程如下:

linuxidc@xiaomanon-machine:~/Documents/c_code$ rm app 
linuxidc@xiaomanon-machine:~/Documents/c_code$ gcc test1.c test2.c main.c -o app
linuxidc@xiaomanon-machine:~/Documents/c_code$ ls
app  main.c  test1.c  test2.c
linuxidc@xiaomanon-machine:~/Documents/c_code$ ./app 
result = 60 

此外,此選項很多時候用作鏈接多個目標文件的時候,我們可能需要先對不同的源文件進行相應的操作來得到目標文件*.o,然後在最後將這些目標文件鏈接成一個可執行文件。

linuxidc@xiaomanon-machine:~/Documents/c_code$ gcc -c *.c
linuxidc@xiaomanon-machine:~/Documents/c_code$ ls
main.c  main.o  test1.c  test1.o  test2.c  test2.o
linuxidc@xiaomanon-machine:~/Documents/c_code$ gcc main.o test1.o test2.o -o app
linuxidc@xiaomanon-machine:~/Documents/c_code$ ls
app  main.c  main.o  test1.c  test1.o  test2.c  test2.o
linuxidc@xiaomanon-machine:~/Documents/c_code$ ./app 
result = 60 

2.5 -I選項

  該選項用於指定包含的頭文件的目錄,這一點對於大型的代碼組織來說是很有用的。 

2.6 -g選項

  該選項用來生成可以被gdb調試器使用的調試信息。只有使用了該選項後生成的可執行文件才帶有程序中引用的符號表,這是gdb調試程序才能對可執行程序進行調試。

linuxidc@xiaomanon-machine:~/Documents/c_code$ gcc *.c -o app
linuxidc@xiaomanon-machine:~/Documents/c_code$ ll app
-rwxrwxr-x 1 linuxidc xiaomanon 7381 12月 29 15:23 app*
linuxidc@xiaomanon-machine:~/Documents/c_code$ gcc -g *.c -o app
linuxidc@xiaomanon-machine:~/Documents/c_code$ ll app
-rwxrwxr-x 1 linuxidc xiaomanon 8825 12月 29 15:23 app*

以上命令分別生成了不帶調試信息的可執行文件和帶有調試信息的可執行文件,並對比了兩者的文件大小,可以看出使用的-g選項生成的可執行文件明顯要比沒有使用-g選項的可執行文件大。

Ubuntu 12.04嵌入式交叉編譯環境arm-linux-GCC搭建過程圖解 http://www.linuxidc.com/Linux/2013-06/85902.htm

Ubuntu 12.10安裝交叉編譯器arm-none-linux-gnueabi-GCC http://www.linuxidc.com/Linux/2013-03/82016.htm

Ubuntu下Vim+GCC+GDB安裝及使用 http://www.linuxidc.com/Linux/2013-01/78159.htm

Ubuntu下兩個GCC版本切換 http://www.linuxidc.com/Linux/2012-10/72284.htm

GCC 的詳細介紹:請點這裡
GCC 的下載地址:請點這裡

Copyright © Linux教程網 All Rights Reserved