Linux动静态库
gcc编译过程
- 预处理,
gcc -E
,.c
->.i
展开宏和头文件,替换条件编译,删除注释、空白和空行 - 编译,
gcc -S
,.i
->.s
检查语法规范 【消耗时间和系统资源最多】 - 汇编,
gcc -c
,.s
->.o
将汇编指令编译成汇编指令 - 链接,
gcc
,.o
->.out
,数据段合并,数据地址回填,连接成可执行文件
gcc -E aa.c -o aa.i
- -o 用来指定生产的文件名
编译参数
- 指定头文件
当头文件和主文件不在一个目录时。
# I 指定头文件的目录
$ gcc -I ./head/ aa.c -o aa
或者在引入头文件时,指定相对路径
#include "./head/bb.h"
- -I 头文件
- -c 只做预处理、编译、汇编。得到二进制文件
- -g 编译调试 ,gdb
gcc aa.c -o aa.out -g
gdb aa.out
- -v | --version 查看gcc版本号
- -On n=0-3 编译优化,n越大优化的越多
嵌入式开发一般不需要优化:
int a = 1; // 表示指示灯的开关过程
a = 0;
a = 1;
a = 0;
a = 1;
a = 0;
a = 1;
- -Wall 提示更多警告信息,如定义变量未使用
- -D
编译时定义宏,注意-D和 之间没有空格
下面这段程序将编译出错。
#include "./head/bb.h"
#ifdef HELLO
#define HI 20
#endif
int main()
{
printf("hello world. %d
", HI);
return 0;
}
$ gcc aa.c
但是可以这样编译:
gcc aa.c -D HELLO
- -E 生产预处理文件
- -M 生成.c文件与头文件以来关系用户makefile
静态库
制作
# 生成 add.o,汇编
$ gcc -c add.c
$ gcc -c sub.c
$ ar rcs libmymath.a sub.o add.o
使用
因为在链接时期,将程序复制到程序中。所以我们在编译时期应该会发出未定义警告,但是编译器会帮我们做隐式声明。
如何链接?
# 直接指定静态库
$ gcc test.c libmymath.a -o test -Wall
test.c:6:2: warning: implicit declaration of function ‘add’ [-Wimplicit-function-declaration]
add();
# 编译器会做隐式声明
解决警告:
- 方法一:在主文件中声明原型
#include <stdio.h>
// 声明原型
long add();
void sub();
int main()
{
printf("test...");
add();
sub();
}
不推荐使用
- 方式二:
在静态库源码中,添加mymath.h文件,必须要编译
#ifndef _MYMATH_H_
#define _MYMATH_H_
void add();
void sub();
#endif
包含头文件
#include <stdio.h>
#include "./resource/mymath.h"
int main()
{
printf("test...");
add();
sub();
return 0;
}
gcc test.c libmymath.a -o test -Wall
文件结构
├── inc
│ └── mymath.h
├── lib
│ └── libmymath.a
├── resource
│ ├── aa.c
│ ├── add.c
│ ├── add.o
│ ├── sub.c
│ └── sub.o
├── test.c