Linux下程序的编译
gcc
常用的C语言编译器,也可以编译别的语言
GCC的编译方式
GCC指令的一般格式:
gcc [选项] 源文件名 [选项] 目标文件名
◆采用默认得方式编译源文件,系统会生成a.out可执行文件(gcc hello.c)
◆采用显式编译成目标文件,会编译成一个可执行文件
gcc hello.c
gcc -o hello hello.o
◆直接编译成可执行文件
gcc -o hello hello.c(最后会生成一个名字为hello的可执行文件)
gcc
-o 后边跟目标对象的名称
-c 只编译不链接,后边跟源文件
-g 开启gdb调试 ,gdb是一个调试工具
-Wall 提示所有的警告信息
-Werror 将所有的警告当作错误处理
(linux默认路径:头文件在/usr/include/下),不在这个路径下就要用-I指定。
gcc foo.cpp -I/home/include -o foo
后缀名 | 意义 |
---|---|
.c | C源文件 |
.C/.cpp/.cc/.cxx | C++源文件 |
.h | 头文件 |
.m | Object C源文件 |
.i | 已经预处理过的C源文件 |
.ii | 已经预处理过的C++源文件 |
.s | 汇编语言源文件 |
.o | 目标源文件 |
.a | 编译后得静态库文件 |
.so | 编译后得动态库文件 |
-I | 寻找头文件选项 |
-L 库依赖选项
(linux默认路径:库文件在/usr/lib/下),不在这个路径下就要用-L指定。
g++ foo.cpp -L/home/lib -lfoo -o foo
库就是将源文件编译之后生成的目标文件的集合。
库命名以lib开头。
库有静态库(通常以.a结尾)和动态库(通常以.so结尾)
默认情况下,g++以动态库形式连接。
如果要静态库连接则要用-static指定(g++ foo.cpp -L/home/lib -static -lfoo -o foo)
GCC编译流程
编译过程:预编译 编译 汇编 链接
预编译
命令:gcc -E 源文件 -o 目标文件
gcc -E helloworld.c -o helloworld.i
编译
编译的输入是.i文件,输出是.s文件(存放的是汇编的代码)
命令:gcc -S 源文件 -o 目标文件
gcc -S helloworld.c -o helloworld.s
汇编
本阶段是将汇编语言翻译成目标文件,汇编常用的选项是-c,它的作用是告诉编译器,当汇编阶段结束时停止编译
汇编的输入是.s文件,输出是.o文件
命令:gcc -c 源文件 -o 目标文件
gcc -c helloworld.c(这个也可以生成.o文件)
gcc -c helloworld.s -o helloworld.o
链接
本阶段是将所有的目标文件以及相应的库文件编译成可执行文件,链接并不需要选项,只需要制定生成的可执行文件名。
链接的输入是.o文件,输出是可执行文件
命令:gcc 源文件 -o 目标文件
gcc helloworld.o -o helloworld
案例:
helloworld.c
采用默认得方式编译,系统会生成a.out可执行文件
gcc helloworld.c
执行:
./a.out
#生成的可执行文件helloworld
gcc helloworld.c -o helloworld
#-g生成调试信息
gcc -g helloworld.c -o helloworld
编译C++
gcc helloworld.c -lstdc++ -o helloworld
g++
g++是GCC中的一个工具,专门来编译C++语言的。
编译选项和gcc的相同
g++ helloworld.c -o helloworld
如何编译C++11?
升级编译器
1:
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
2:安装gcc4.8和g++4.8
sudo apt-get update; sudo apt-get install gcc-4.8 g+±4.8
3:用gcc4.8和g++4.8替换旧的编译器版本
sudo update-alternatives --remove-all gcc
sudo update-alternatives --remove-all g++
注意:上面的两个命令的可能会执行失败,不会影响下面的安装。
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 20
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g+±4.8 20
sudo update-alternatives --config gcc
sudo update-alternatives --config g++
查看更新后编译器的版本:
gcc --version
案例:
g++ c11test.cpp -std=c++11 -o c11test
简化的方法,通过修改~/.bashrc文件
Linux g++开启C++11支持
1、使用vim打开.bashrc文件
sudo vim ~/.bashrc
2、 在some more ls aliases注释块的地方添加:
alias g++=‘g++ -std=c++11’
简化后的编译
g++ c11test.cpp -o c11test
为什么需要makefile?
当源代码文件数目较多,并且目录结构关系复杂时,需要通过
makefile来编写程序的编译规则,来编译代码
makefile
make命令
makefile的缩进用tab
编译:预编译 编译 汇编
链接: 链接
执行
规则:
目标对象:依赖对象
要生成目标对象所执行的命令
Makefile
$@ --代表目标文件(target)
$^ --代表所有的依赖文件(components)
$< --第一个依赖文件
静态库和动态库
库本身不能执行,必须被调用才有意义
库就是将源文件编译之后生成的目标文件的集合。
库命名以lib开头。
库有静态库(通常以.a结尾)和动态库(通常以.so结尾)
默认情况下,g++以动态库形式连接。
如果要静态库连接则要用-static指定(g++ foo.cpp -L/home/lib -static -lfoo -o foo)
Linux上的静态库,其实是目标文件的归档文件。
在Linux上创建静态库的步骤如下:
1.写源文件,通过 gcc -c xxx.c 生成目标文件。
2.用 ar 归档目标文件,生成静态库。
3.配合静态库,写一个使用静态库中函数的头文件。
gdb
程序调试器