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

 

2.1 -c选项

  该选项(小写c)表示编译、汇编指定的源文件,但是不进行链接。该选项的使用方法如下:

gcc -c source.c

也就是在-c选项后面紧跟要编译、汇编的C源文件,最终生成与源文件名称相同,但是后缀为*.o结尾的目标文件。

xiaomanon@xiaomanon-machine:~/Documents/c_code$ ls

main.c  test1.c  test2.c

xiaomanon@xiaomanon-machine:~/Documents/c_code$ gcc -c test1.c

xiaomanon@xiaomanon-machine:~/Documents/c_code$ ls

main.c  test1.c  test1.o  test2.c

可以看到,使用-c选项编译之后生成了对应的*.o目标文件。当然,你也可以一次性指定多个C源文件,使用-c选项后,会针对每一个C源文件生成一个相应的*.o目标文件。

xiaomanon@xiaomanon-machine:~/Documents/c_code$ gcc -c test2.c main.c

xiaomanon@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结尾的汇编语言文件。

xiaomanon@xiaomanon-machine:~/Documents/c_code$ gcc -S test1.c

xiaomanon@xiaomanon-machine:~/Documents/c_code$ ls

main.c  test1.c  test1.s  test2.c

当然,输入的源文件也不止一个,你可以编译当前目录下的所有C语言源文件:

xiaomanon@xiaomanon-machine:~/Documents/c_code$ gcc -S *.c

xiaomanon@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

那么,编译我们的测试程序可以使用下面的方式:

xiaomanon@xiaomanon-machine:~/Documents/c_code$ gcc -o app *.c

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

xiaomanon@xiaomanon-machine:~/Documents/c_code$ ./app 

result = 60

还有另外一种方式,即-o选项放置在最后:

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

这种方式的逻辑性更强,语义可以理解为编译C语言源文件得到最终的可执行程序app,使用这种方式编译我们的测试程序过程如下:

xiaomanon@xiaomanon-machine:~/Documents/c_code$ rm app 

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

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

xiaomanon@xiaomanon-machine:~/Documents/c_code$ ./app 

result = 60

 

此外,此选项很多时候用作链接多个目标文件的时候,我们可能需要先对不同的源文件进行相应的操作来得到目标文件*.o,然后在最后将这些目标文件链接成一个可执行文件。

xiaomanon@xiaomanon-machine:~/Documents/c_code$ gcc -c *.c

xiaomanon@xiaomanon-machine:~/Documents/c_code$ ls

main.c  main.o  test1.c  test1.o  test2.c  test2.o

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

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

xiaomanon@xiaomanon-machine:~/Documents/c_code$ ./app 

result = 60

 

2.5 -I选项

  该选项用于指定包含的头文件的目录,这一点对于大型的代码组织来说是很有用的。

 

2.6 -g选项

  该选项用来生成可以被gdb调试器使用的调试信息。只有使用了该选项后生成的可执行文件才带有程序中引用的符号表,这是gdb调试程序才能对可执行程序进行调试。

xiaomanon@xiaomanon-machine:~/Documents/c_code$ gcc *.c -o app

xiaomanon@xiaomanon-machine:~/Documents/c_code$ ll app

-rwxrwxr-x 1 xiaomanon xiaomanon 7381 12月 29 15:23 app*

xiaomanon@xiaomanon-machine:~/Documents/c_code$ gcc -g *.c -o app

xiaomanon@xiaomanon-machine:~/Documents/c_code$ ll app

-rwxrwxr-x 1 xiaomanon xiaomanon 8825 12月 29 15:23 app*

以上命令分别生成了不带调试信息的可执行文件和带有调试信息的可执行文件,并对比了两者的文件大小,可以看出使用的-g选项生成的可执行文件明显要比没有使用-g选项的可执行文件大。

 

你可能感兴趣的:(gcc)