gcc/g++命令使用及编译原理一

gcc/g++命令使用GNU推出的基于C/C++的编译器,是开放源代码领域应用最广泛的编译器,具有功能强大,编译代码支持性能优化等特点。现在很多程序员都应用GCC,怎样才能更好的应用GCC。目前,GCC可以用来编译C/C++、FORTRAN、JAVA、OBJC、ADA等语言的程序,可根据需要选择安装支持的语言。

0x1.什么是编译器?

    简单讲,编译器就是将“一种语言(通常为高级语言)”翻译为“另一种语言(通常为低级语言)”的程序。举个例子:当我们使用C语言写了一段程序,想被运算机器执行(电脑或其它嵌入式设备等等),编译器就是负责把这一段程序转换成可以指定机器上执行的指令。

0x2.工作流程

    gcc编译主要工作流程有四个部分:预处理(preprocessing),编译(compilation),汇编(assembly),链接(linking),当前网络上还有其它的表现形式,如:源代码 (source code) → 预处理器 (preprocessor) → 编译器 (compiler) → 目标代码 (object code) → 链接器 (Linker) → 可执行程序 (executables),其实原理都一样,只是后面的更方便理解。关于编译原理有详情说明。


0x3.gcc常用命令

语法:gcc (选项)(参数:文件)
    写一个hello.c的程序

#include

int main(){
	printf("hello world!");
	return 0;
}

1、无选项编译链接 

$ gcc hello.c

hello.c预处理、编译、汇编并链接形成可执行文件。这里未指定输出文件,在Linux上默认输出为a.out,在window环境中编译默认为a.exe。

 $ ls
 a.exe  hello.c

查看生成a.exe执行文件

$ ./a.exe
hello world!

执行a.exe,输出结果
    
2、选项 -o(理解成output),对生成的目标进行重命名,linux下为hello.out,windows下为hello.exe

$ gcc -o hello hello.c

$ ls
a.exe  hello.c  hello.exe

3、选项 -E,把源代码预处理输出为hello.i文件,详见下一篇

$ gcc -E hello.c -o hello.i

$ ls
a.exe  hello.c  hello.exe  hello.i

与cpp  hello.c  >  hello.i命令功能一致。

4、选项 -S,把预处理输出的文件hello.i汇编成hello.s文件

$ gcc -S hello.i
$ ls
a.exe  hello.c  hello.exe  hello.i  hello.s

查看汇编后hello.s的内容

	.file	"hello.c"
	.text
	.def	__main;	.scl	2;	.type	32;	.endef
	.section .rdata,"dr"
.LC0:
	.ascii "hello world!\0"
	.text
	.globl	main
	.def	main;	.scl	2;	.type	32;	.endef
	.seh_proc	main
main:
	pushq	%rbp
	.seh_pushreg	%rbp
	movq	%rsp, %rbp
	.seh_setframe	%rbp, 0
	subq	$32, %rsp
	.seh_stackalloc	32
	.seh_endprologue
	call	__main
	leaq	.LC0(%rip), %rcx
	call	printf
	movl	$0, %eax
	addq	$32, %rsp
	popq	%rbp
	ret
	.seh_endproc
	.ident	"GCC: (GNU) 7.3.0"
	.def	printf;	.scl	2;	.type	32;	.endef

5、选项 -c,把汇编成hello.s文件编译输出为hello.o文件,输出文件为二进制目标文件。

$ gcc -c hello.s
$ ls
a.exe  hello.c  hello.exe  hello.i  hello.o  hello.s

与as hello.s -o hello.o命令功能一致。

在IDA工具中查看hello.o文件

gcc/g++命令使用及编译原理一_第1张图片

6、无选项链接,把hello.o目标文件链接成最终可执行文件hello1.exe,其实是调用ld命令进行链接。

$ gcc hello.o -o hello1
$ ls -l
总用量 394
-rwxrwxr-x+ 1 Administrator  None 155707 八月  3 15:31 a.exe
-rwxrwx---+ 1 Administrators None     68 八月  3 15:21 hello.c
-rwxrwxr-x+ 1 Administrator  None  34373 八月  3 16:48 hello.exe
-rw-rw-r--+ 1 Administrator  None  34373 八月  3 16:48 hello.i
-rw-rw-r--+ 1 Administrator  None    866 八月  3 17:18 hello.o
-rw-rw-r--+ 1 Administrator  None    496 八月  3 17:05 hello.s
-rwxrwxr-x+ 1 Administrator  None 155707 八月  3 17:26 hello11.exe

$ ./hello1.exe
hello world!

7、选项 -O(大写的字母O),使用编译优化级别,1~3,级别越大优化效果越好,但编译的时候会长。

$ gcc -O3 hello.c -o hello2

8、选项 -M,查看生成文件关联信息,包含目标文件所依赖的所有源代码,该命令会在预处理阶段中执行。

$ gcc -M hello.c
hello.o: hello.c /usr/include/stdio.h /usr/include/_ansi.h \
 /usr/include/newlib.h /usr/include/_newlib_version.h \
 /usr/include/sys/config.h /usr/include/machine/ieeefp.h \
 /usr/include/sys/features.h /usr/include/cygwin/config.h \
 /usr/include/sys/cdefs.h /usr/include/machine/_default_types.h \
 /usr/lib/gcc/x86_64-pc-cygwin/7.3.0/include/stddef.h \
 /usr/lib/gcc/x86_64-pc-cygwin/7.3.0/include/stdarg.h \
 /usr/include/sys/reent.h /usr/include/_ansi.h /usr/include/sys/_types.h \
 /usr/include/machine/_types.h /usr/include/sys/lock.h \
 /usr/include/sys/types.h /usr/include/sys/_stdint.h \
 /usr/include/machine/endian.h /usr/include/machine/_endian.h \
 /usr/include/bits/endian.h /usr/include/sys/select.h \
 /usr/include/sys/_sigset.h /usr/include/sys/_timeval.h \
 /usr/include/sys/timespec.h /usr/include/sys/_timespec.h \
 /usr/include/sys/_pthreadtypes.h /usr/include/machine/types.h \
 /usr/include/endian.h /usr/include/bits/byteswap.h \
 /usr/include/bits/wordsize.h /usr/include/sys/sysmacros.h \
 /usr/include/sys/stdio.h

9、选项 -MM,与-M相比,会忽略#include文件的依赖关系

$ gcc -MM hello.c
hello.o: hello.c

10、多个文件一起编译,hello.c、multi.c分别编译后链接成multi.out或multi.exe的可执行文件。

$ gcc hello.c multi.c -o multi

11、多个.o二进制目标文件编译后链接成一个可执行文件

$ gcc multi.o hello.o -o multi1

12、选项 -include file :包含某个代码。相当于在文件中加入#include 

$ gcc hello.c -include multi.c -o include

生成include.out可执行文件

13、选项 -Idir:当你使用#include”file”的时候,会先到你定制的目录里面查找。

14、选项 -L(library):定制编译的时候使用的库,/home/hello/lib作为第一个寻找库文件的目录。

$ gcc -o hello hello.c -L/home/hello/lib

15、选项 -l:定制编译的时候使用的库,寻找动态链接库文件libtest.so,如果加上-static,表示寻找libtest.a静态链接库。

$ gcc -o hello hello.c -ltest

16、选项 -w,表示不生成任何警告的信息。

$ gcc -w multi.c hello.c -o multi

17、选项 -Wall:生成所有警告信息。

$ gcc -Wall multi.c hello.c -o multi

18、选项 -g:在编译的时候加入debug调试信息,用于gdb调试,文件会比一般大一点。

$ gcc -g hello.c -o hello5

19、选项 -share:此选项尽量的使用动态库,所以生成文件比较小,但是必须是系统有动态库。

20、选项 -shared:生成共享目标文件,通常用在建立共享库。

你可能感兴趣的:(tool)