程序编译的大体流程:预处理——编译——汇编——链接
预处理
主要动作:宏的替换,还有注释的消除,还有找到相关的库文件
gcc/g++ -E Test.cpp
编译
主要动作:将预处理后的文件转换为汇编文件,里面为汇编指令
gcc/g++ -S Test.cpp
汇编
主要动作:将汇编文件转换为目标文件, 生成.o文件,即目标文件
gcc/g++ -c Test.cpp
主要动作:将目标文件和库文件整合为可执行文件
链接
主要动作:将目标文件和库文件整合为可执行文件
g++ Test.o -L usr/include/iostream
使用-o可以为可执行文件命名
常用命令
-c 生成.o目标文件
-o可执行文件命名
-shared 指定生成动态链接库
-static 指定生成静态链接库
-L 要链接的库所在目录
-l 指定链接时需要的动态库,隐含命名规则,即在前加lib,在后加.a或.so确定库文件名
静态库
静态库是在可执行文件中包含库代码的一份完整拷贝,
这种方式有个很严重的缺点就是会造成多份冗余拷贝。
静态库会在程序的链接阶段被复制到程序中,所以程序在运行后是不会调用静态库的
动态库
动态库在链接阶段并没有被复制到程序中
是程序运行的时候由系统动态的加载到内存中供程序调用,所以这里解决了静态库早晨多份冗余拷贝的缺点,系统只需要载入一次动态库
不同的程序可以得到内存中相同的动态库副本,因此可以节省大量的内存
相同点
静态库和动态库都是由.o文件生成
示例
先创建三个文件,分别为hello.c、hello.h、main.c
“hello.h" 如下
#ifndef __HELLO_H__
#define __HELLO_H__
void Hello();
#endif
“hello.c”:
#include "hello.h"
#include <stdio.h>
void Hello()
{
printf("Hello World!!!\n");
}
“main.c”
#include "hello.h"
int main(void)
{
Hello();
return 0;
}
静态库编译
1 先将hello.c编译成hello.o
g++ -c hello.c
2 生成静态库文件
ar cr libhello.a hello.o
3 主程序链接静态库文件生成可执行文件
g++ -o main main.c -static -lhello -L.
动态库编译
1 先将hello.c编译成hello.o
g++ -c -fPIC hello.c -o hello.o
2 生成动态库文件
g++ -shared hello.o -o libhello.so
3 主程序链接动态库文件生成可执行文件
g++ -o main main.c libhello.so
4 执行
1、将该动态库文件所在路径添加到环境变量
export LD_LIBRARY_PATH=./
2、运行该可执行文件
./main