首页 技术 正文
技术 2022年11月23日
0 收藏 843 点赞 4,414 浏览 18323 个字

  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的编译选项非常多,现在有上千个,但是我们常用的并不多,下面我们只介绍其中非常实用的几个。

在这之前,我们先编写下面的几个源文件,以备测试只用。

 //main.c
#include <stdio.h> extern int add(int a, int b);
extern int mul(int a, int b); int main(void)
{
int a = , b = ;
int result; result = add(a, mul(a, b));
printf("result = %d\n", result);
return ;
}

main.c

 //test1.c
int add(int a, int b)
{
return a+b;
}

test1.c

 //test2.c
int mul(int a, int b)
{
return a*b;
}

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

我们也可以查看生成的汇编语言代码:

     .file    "test1.c"
.text
.globl add
.type add, @function
add:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset
.cfi_offset , -
movl %esp, %ebp
.cfi_def_cfa_register
movl (%ebp), %eax
movl (%ebp), %edx
addl %edx, %eax
popl %ebp
.cfi_restore
.cfi_def_cfa ,
ret
.cfi_endproc
.LFE0:
.size add, .-add
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
.section .note.GNU-stack,"",@progbits

test1.s

2.3 -E选项

  该选项对C语言源文件进行预处理,但是并不编译该程序。对于一般的预处理问题(比如,宏的展开问题、文件的包含问题等),可以使用这个选项进行查看。另外,如果直接使用此选项,程序会将预处理结果直接输出到终端,不便于查看,因此,一般可以使用重定向将程序输出结果保存到一个文本文件中,格式如下:

gcc -E source.c > output

如果我们对main.c执行预编译,得到的output文件内容如下:

 #  "main.c"
# "<command-line>"
# "/usr/include/stdc-predef.h"
# "<command-line>"
# "main.c" # "/usr/include/stdio.h"
# "/usr/include/stdio.h"
# "/usr/include/features.h"
# "/usr/include/features.h"
# "/usr/include/i386-linux-gnu/sys/cdefs.h"
# "/usr/include/i386-linux-gnu/sys/cdefs.h"
# "/usr/include/i386-linux-gnu/bits/wordsize.h"
# "/usr/include/i386-linux-gnu/sys/cdefs.h"
# "/usr/include/features.h"
# "/usr/include/features.h"
# "/usr/include/i386-linux-gnu/gnu/stubs.h" # "/usr/include/i386-linux-gnu/gnu/stubs-32.h"
# "/usr/include/i386-linux-gnu/gnu/stubs.h"
# "/usr/include/features.h"
# "/usr/include/stdio.h" # "/usr/lib/gcc/i686-linux-gnu/4.8/include/stddef.h"
# "/usr/lib/gcc/i686-linux-gnu/4.8/include/stddef.h"
typedef unsigned int size_t;
# "/usr/include/stdio.h" # "/usr/include/i386-linux-gnu/bits/types.h"
# "/usr/include/i386-linux-gnu/bits/types.h"
# "/usr/include/i386-linux-gnu/bits/wordsize.h"
# "/usr/include/i386-linux-gnu/bits/types.h" typedef unsigned char __u_char;
typedef unsigned short int __u_short;
typedef unsigned int __u_int;
typedef unsigned long int __u_long; typedef signed char __int8_t;
typedef unsigned char __uint8_t;
typedef signed short int __int16_t;
typedef unsigned short int __uint16_t;
typedef signed int __int32_t;
typedef unsigned int __uint32_t; __extension__ typedef signed long long int __int64_t;
__extension__ typedef unsigned long long int __uint64_t; __extension__ typedef long long int __quad_t;
__extension__ typedef unsigned long long int __u_quad_t;
# "/usr/include/i386-linux-gnu/bits/types.h"
# "/usr/include/i386-linux-gnu/bits/typesizes.h"
# "/usr/include/i386-linux-gnu/bits/types.h" __extension__ typedef __u_quad_t __dev_t;
__extension__ typedef unsigned int __uid_t;
__extension__ typedef unsigned int __gid_t;
__extension__ typedef unsigned long int __ino_t;
__extension__ typedef __u_quad_t __ino64_t;
__extension__ typedef unsigned int __mode_t;
__extension__ typedef unsigned int __nlink_t;
__extension__ typedef long int __off_t;
__extension__ typedef __quad_t __off64_t;
__extension__ typedef int __pid_t;
__extension__ typedef struct { int __val[]; } __fsid_t;
__extension__ typedef long int __clock_t;
__extension__ typedef unsigned long int __rlim_t;
__extension__ typedef __u_quad_t __rlim64_t;
__extension__ typedef unsigned int __id_t;
__extension__ typedef long int __time_t;
__extension__ typedef unsigned int __useconds_t;
__extension__ typedef long int __suseconds_t; __extension__ typedef int __daddr_t;
__extension__ typedef int __key_t; __extension__ typedef int __clockid_t; __extension__ typedef void * __timer_t; __extension__ typedef long int __blksize_t; __extension__ typedef long int __blkcnt_t;
__extension__ typedef __quad_t __blkcnt64_t; __extension__ typedef unsigned long int __fsblkcnt_t;
__extension__ typedef __u_quad_t __fsblkcnt64_t; __extension__ typedef unsigned long int __fsfilcnt_t;
__extension__ typedef __u_quad_t __fsfilcnt64_t; __extension__ typedef int __fsword_t; __extension__ typedef int __ssize_t; __extension__ typedef long int __syscall_slong_t; __extension__ typedef unsigned long int __syscall_ulong_t; typedef __off64_t __loff_t;
typedef __quad_t *__qaddr_t;
typedef char *__caddr_t; __extension__ typedef int __intptr_t; __extension__ typedef unsigned int __socklen_t;
# "/usr/include/stdio.h"
# "/usr/include/stdio.h"
struct _IO_FILE; typedef struct _IO_FILE FILE; # "/usr/include/stdio.h"
typedef struct _IO_FILE __FILE;
# "/usr/include/stdio.h"
# "/usr/include/libio.h"
# "/usr/include/libio.h"
# "/usr/include/_G_config.h"
# "/usr/include/_G_config.h"
# "/usr/lib/gcc/i686-linux-gnu/4.8/include/stddef.h"
# "/usr/include/_G_config.h" # "/usr/include/wchar.h"
# "/usr/include/wchar.h"
typedef struct
{
int __count;
union
{ unsigned int __wch; char __wchb[];
} __value;
} __mbstate_t;
# "/usr/include/_G_config.h"
typedef struct
{
__off_t __pos;
__mbstate_t __state;
} _G_fpos_t;
typedef struct
{
__off64_t __pos;
__mbstate_t __state;
} _G_fpos64_t;
# "/usr/include/libio.h"
# "/usr/include/libio.h"
# "/usr/lib/gcc/i686-linux-gnu/4.8/include/stdarg.h"
# "/usr/lib/gcc/i686-linux-gnu/4.8/include/stdarg.h"
typedef __builtin_va_list __gnuc_va_list;
# "/usr/include/libio.h"
# "/usr/include/libio.h"
struct _IO_jump_t; struct _IO_FILE;
# "/usr/include/libio.h"
typedef void _IO_lock_t; struct _IO_marker {
struct _IO_marker *_next;
struct _IO_FILE *_sbuf; int _pos;
# "/usr/include/libio.h"
}; enum __codecvt_result
{
__codecvt_ok,
__codecvt_partial,
__codecvt_error,
__codecvt_noconv
};
# "/usr/include/libio.h"
struct _IO_FILE {
int _flags; char* _IO_read_ptr;
char* _IO_read_end;
char* _IO_read_base;
char* _IO_write_base;
char* _IO_write_ptr;
char* _IO_write_end;
char* _IO_buf_base;
char* _IO_buf_end; char *_IO_save_base;
char *_IO_backup_base;
char *_IO_save_end; struct _IO_marker *_markers; struct _IO_FILE *_chain; int _fileno; int _flags2; __off_t _old_offset; unsigned short _cur_column;
signed char _vtable_offset;
char _shortbuf[]; _IO_lock_t *_lock;
# "/usr/include/libio.h"
__off64_t _offset;
# "/usr/include/libio.h"
void *__pad1;
void *__pad2;
void *__pad3;
void *__pad4;
size_t __pad5; int _mode; char _unused2[ * sizeof (int) - * sizeof (void *) - sizeof (size_t)]; }; typedef struct _IO_FILE _IO_FILE; struct _IO_FILE_plus; extern struct _IO_FILE_plus _IO_2_1_stdin_;
extern struct _IO_FILE_plus _IO_2_1_stdout_;
extern struct _IO_FILE_plus _IO_2_1_stderr_;
# "/usr/include/libio.h"
typedef __ssize_t __io_read_fn (void *__cookie, char *__buf, size_t __nbytes); typedef __ssize_t __io_write_fn (void *__cookie, const char *__buf,
size_t __n); typedef int __io_seek_fn (void *__cookie, __off64_t *__pos, int __w); typedef int __io_close_fn (void *__cookie);
# "/usr/include/libio.h"
extern int __underflow (_IO_FILE *);
extern int __uflow (_IO_FILE *);
extern int __overflow (_IO_FILE *, int);
# "/usr/include/libio.h"
extern int _IO_getc (_IO_FILE *__fp);
extern int _IO_putc (int __c, _IO_FILE *__fp);
extern int _IO_feof (_IO_FILE *__fp) __attribute__ ((__nothrow__ , __leaf__));
extern int _IO_ferror (_IO_FILE *__fp) __attribute__ ((__nothrow__ , __leaf__)); extern int _IO_peekc_locked (_IO_FILE *__fp); extern void _IO_flockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));
extern void _IO_funlockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));
extern int _IO_ftrylockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));
# "/usr/include/libio.h"
extern int _IO_vfscanf (_IO_FILE * __restrict, const char * __restrict,
__gnuc_va_list, int *__restrict);
extern int _IO_vfprintf (_IO_FILE *__restrict, const char *__restrict,
__gnuc_va_list);
extern __ssize_t _IO_padn (_IO_FILE *, int, __ssize_t);
extern size_t _IO_sgetn (_IO_FILE *, void *, size_t); extern __off64_t _IO_seekoff (_IO_FILE *, __off64_t, int, int);
extern __off64_t _IO_seekpos (_IO_FILE *, __off64_t, int); extern void _IO_free_backup_area (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));
# "/usr/include/stdio.h" typedef __gnuc_va_list va_list;
# "/usr/include/stdio.h"
typedef __off_t off_t;
# "/usr/include/stdio.h"
typedef __ssize_t ssize_t; typedef _G_fpos_t fpos_t; # "/usr/include/stdio.h"
# "/usr/include/i386-linux-gnu/bits/stdio_lim.h"
# "/usr/include/stdio.h" extern struct _IO_FILE *stdin;
extern struct _IO_FILE *stdout;
extern struct _IO_FILE *stderr; extern int remove (const char *__filename) __attribute__ ((__nothrow__ , __leaf__)); extern int rename (const char *__old, const char *__new) __attribute__ ((__nothrow__ , __leaf__)); extern int renameat (int __oldfd, const char *__old, int __newfd,
const char *__new) __attribute__ ((__nothrow__ , __leaf__)); extern FILE *tmpfile (void) ;
# "/usr/include/stdio.h"
extern char *tmpnam (char *__s) __attribute__ ((__nothrow__ , __leaf__)) ; extern char *tmpnam_r (char *__s) __attribute__ ((__nothrow__ , __leaf__)) ;
# "/usr/include/stdio.h"
extern char *tempnam (const char *__dir, const char *__pfx)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) ; extern int fclose (FILE *__stream); extern int fflush (FILE *__stream); # "/usr/include/stdio.h"
extern int fflush_unlocked (FILE *__stream);
# "/usr/include/stdio.h" extern FILE *fopen (const char *__restrict __filename,
const char *__restrict __modes) ; extern FILE *freopen (const char *__restrict __filename,
const char *__restrict __modes,
FILE *__restrict __stream) ;
# "/usr/include/stdio.h" # "/usr/include/stdio.h"
extern FILE *fdopen (int __fd, const char *__modes) __attribute__ ((__nothrow__ , __leaf__)) ;
# "/usr/include/stdio.h"
extern FILE *fmemopen (void *__s, size_t __len, const char *__modes)
__attribute__ ((__nothrow__ , __leaf__)) ; extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) __attribute__ ((__nothrow__ , __leaf__)) ; extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) __attribute__ ((__nothrow__ , __leaf__)); extern int setvbuf (FILE *__restrict __stream, char *__restrict __buf,
int __modes, size_t __n) __attribute__ ((__nothrow__ , __leaf__)); extern void setbuffer (FILE *__restrict __stream, char *__restrict __buf,
size_t __size) __attribute__ ((__nothrow__ , __leaf__)); extern void setlinebuf (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)); extern int fprintf (FILE *__restrict __stream,
const char *__restrict __format, ...); extern int printf (const char *__restrict __format, ...); extern int sprintf (char *__restrict __s,
const char *__restrict __format, ...) __attribute__ ((__nothrow__)); extern int vfprintf (FILE *__restrict __s, const char *__restrict __format,
__gnuc_va_list __arg); extern int vprintf (const char *__restrict __format, __gnuc_va_list __arg); extern int vsprintf (char *__restrict __s, const char *__restrict __format,
__gnuc_va_list __arg) __attribute__ ((__nothrow__)); extern int snprintf (char *__restrict __s, size_t __maxlen,
const char *__restrict __format, ...)
__attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, , ))); extern int vsnprintf (char *__restrict __s, size_t __maxlen,
const char *__restrict __format, __gnuc_va_list __arg)
__attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, , ))); # "/usr/include/stdio.h"
extern int vdprintf (int __fd, const char *__restrict __fmt,
__gnuc_va_list __arg)
__attribute__ ((__format__ (__printf__, , )));
extern int dprintf (int __fd, const char *__restrict __fmt, ...)
__attribute__ ((__format__ (__printf__, , ))); extern int fscanf (FILE *__restrict __stream,
const char *__restrict __format, ...) ; extern int scanf (const char *__restrict __format, ...) ; extern int sscanf (const char *__restrict __s,
const char *__restrict __format, ...) __attribute__ ((__nothrow__ , __leaf__));
# "/usr/include/stdio.h"
extern int fscanf (FILE *__restrict __stream, const char *__restrict __format, ...) __asm__ ("" "__isoc99_fscanf") ;
extern int scanf (const char *__restrict __format, ...) __asm__ ("" "__isoc99_scanf")
;
extern int sscanf (const char *__restrict __s, const char *__restrict __format, ...) __asm__ ("" "__isoc99_sscanf") __attribute__ ((__nothrow__ , __leaf__)) ;
# "/usr/include/stdio.h" extern int vfscanf (FILE *__restrict __s, const char *__restrict __format,
__gnuc_va_list __arg)
__attribute__ ((__format__ (__scanf__, , ))) ; extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg)
__attribute__ ((__format__ (__scanf__, , ))) ; extern int vsscanf (const char *__restrict __s,
const char *__restrict __format, __gnuc_va_list __arg)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__format__ (__scanf__, , )));
# "/usr/include/stdio.h"
extern int vfscanf (FILE *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vfscanf") __attribute__ ((__format__ (__scanf__, , ))) ;
extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vscanf") __attribute__ ((__format__ (__scanf__, , ))) ;
extern int vsscanf (const char *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vsscanf") __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__format__ (__scanf__, , )));
# "/usr/include/stdio.h" extern int fgetc (FILE *__stream);
extern int getc (FILE *__stream); extern int getchar (void); # "/usr/include/stdio.h"
extern int getc_unlocked (FILE *__stream);
extern int getchar_unlocked (void);
# "/usr/include/stdio.h"
extern int fgetc_unlocked (FILE *__stream); extern int fputc (int __c, FILE *__stream);
extern int putc (int __c, FILE *__stream); extern int putchar (int __c); # "/usr/include/stdio.h"
extern int fputc_unlocked (int __c, FILE *__stream); extern int putc_unlocked (int __c, FILE *__stream);
extern int putchar_unlocked (int __c); extern int getw (FILE *__stream); extern int putw (int __w, FILE *__stream); extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
;
# "/usr/include/stdio.h"
extern char *gets (char *__s) __attribute__ ((__deprecated__)); # "/usr/include/stdio.h"
extern __ssize_t __getdelim (char **__restrict __lineptr,
size_t *__restrict __n, int __delimiter,
FILE *__restrict __stream) ;
extern __ssize_t getdelim (char **__restrict __lineptr,
size_t *__restrict __n, int __delimiter,
FILE *__restrict __stream) ; extern __ssize_t getline (char **__restrict __lineptr,
size_t *__restrict __n,
FILE *__restrict __stream) ; extern int fputs (const char *__restrict __s, FILE *__restrict __stream); extern int puts (const char *__s); extern int ungetc (int __c, FILE *__stream); extern size_t fread (void *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __stream) ; extern size_t fwrite (const void *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __s); # "/usr/include/stdio.h"
extern size_t fread_unlocked (void *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __stream) ;
extern size_t fwrite_unlocked (const void *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __stream); extern int fseek (FILE *__stream, long int __off, int __whence); extern long int ftell (FILE *__stream) ; extern void rewind (FILE *__stream); # "/usr/include/stdio.h"
extern int fseeko (FILE *__stream, __off_t __off, int __whence); extern __off_t ftello (FILE *__stream) ;
# "/usr/include/stdio.h" extern int fgetpos (FILE *__restrict __stream, fpos_t *__restrict __pos); extern int fsetpos (FILE *__stream, const fpos_t *__pos);
# "/usr/include/stdio.h" # "/usr/include/stdio.h" extern void clearerr (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)); extern int feof (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ; extern int ferror (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ; extern void clearerr_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
extern int feof_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
extern int ferror_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ; extern void perror (const char *__s); # "/usr/include/i386-linux-gnu/bits/sys_errlist.h"
# "/usr/include/i386-linux-gnu/bits/sys_errlist.h"
extern int sys_nerr;
extern const char *const sys_errlist[];
# "/usr/include/stdio.h" extern int fileno (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ; extern int fileno_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
# "/usr/include/stdio.h"
extern FILE *popen (const char *__command, const char *__modes) ; extern int pclose (FILE *__stream); extern char *ctermid (char *__s) __attribute__ ((__nothrow__ , __leaf__));
# "/usr/include/stdio.h"
extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)); extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ; extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
# "/usr/include/stdio.h" # "main.c" extern int add(int a, int b);
extern int mul(int a, int b); int main(void)
{
int a = , b = ;
int result; result = add(a, mul(a, b));
printf("result = %d\n", result);
return ;
}

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 =

还有另外一种方式,即-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 =

此外,此选项很多时候用作链接多个目标文件的时候,我们可能需要先对不同的源文件进行相应的操作来得到目标文件*.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 =

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 xiaomanon xiaomanon 12月 : app*
xiaomanon@xiaomanon-machine:~/Documents/c_code$ gcc -g *.c -o app
xiaomanon@xiaomanon-machine:~/Documents/c_code$ ll app
-rwxrwxr-x xiaomanon xiaomanon 8825 12月 : app*

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

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,910
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,435
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,250
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,061
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,693
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,731