目录
gcc/g++是linux系统中的编译器,是一款软件。该软件只负责编译,与Windows下的vs系列的差别就是:vs系列是一种集成开发环境(IDE)而Linux下的gcc/g++,只是用来编译的。gcc与g++的区别只有一点gcc用来编译C语言代码,g++用来编译C++代码,这两个工具在用法上完全类似,所以以下的叙述就用gcc来举例展开说明。
gcc生成的可执行程序有两个默认行为:
1.默认链接到动态库2.默认发布为release版本
gcc [选项] [要编译的文件] [选项] [目标文件]
例如:从一个test.c文件直接生成可执行程序mytest
gcc test.c -o mytest 或者 gcc -o mytest test.c
从一个文件直接生成一个可执行程序需要经过4个步骤,gcc编译器可以将4步拆分开
-预处理(头文件展开,宏替换,去注释,条件编译)
gcc -E test.c -o test.i
-编译(代码转汇编)
gcc -S test.i -o test.s
-汇编(汇编转二进制)
gcc -e test.s -o test.o
-链接(将多个目标文件与动/静态库链接生成.exe)
gcc test.o -o mytest
总结:
-E只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面
-S 编译到汇编语言不进行汇编和链接
-c 编译到目标代码
-o文件输出到文件
动/静态库都统称为函数库。我们知道在C语言中调用printf函数时,是需要包含stdio.h这个头文件的。我现在需要调用printf这个函数,但是我并没有自己写这个函数的实现,而是通过包含头文件,也就是有了这个头文件声明之后,直接就可以使用了。那么这个操作背后的原理就是,例如,在Windows中的vs系列,安装vs时就会把对应的动/静态库安装好了,而Linux下的gcc会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到libc.so.6库函数中去,我们包含的头文件是函数的声明,而函数的实现就在这些库中,编译器编译好代码生成可执行程序,在链接这一步,会自动的帮我们链接到这些库。
在编译链接时的区别:
静态库:把代码中所用到的函数实现,全部都拷贝到可执行文件中,Linux下后缀名为.a,Windows下后缀名为.lib
优点:运行时,不再依靠库,可以独立运行
缺点:生成的文件比较大
动态库:不会拷贝到可执行文件中,而是在程序执行时由运行时的链接文件加载库,Linux下后缀名为.so,Windows下后缀名为.dll
优点:节省系统开销
缺点:运行时,依赖库,如果库被删或被损毁,则程序无法运行
gcc编译器默认链接动态库
那么如何链接到静态库呢?
答:gcc test.c -o mytest -static
可以看出链接静态库的可执行程序大小是远远大于链接动态库的!
千万要注意,我们都知道在Linux下,文件类型是不以文件名后缀作区分的。那我们在写程序的时候,文件名是不是就可以随便写了呢?
最好不要乱写!!C语言代码,后缀就用.c,C++代码,后缀就用.cpp,因为gcc是Linux下的一款软件,这款软件要区分这个文件要链接对应的哪个语言的库,是自动依靠文件名后缀做区分的!