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,"",@progbitstest1.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 的下載地址:請點這裡