0.linux编译工具链
![](https://i-blog.csdnimg.cn/blog_migrate/82809690e31828ffc2a2787a0cdbfe9b.jpeg)
gcc -E hello.c -o hello.i(预处理)
gcc -S hello.c -o hello.s(汇编)
gcc -c hello.c -o hello.o(目标代码)
gcc hello.c -o hello (可执行二进制)
gcc -g (生成调试信息)
![](https://i-blog.csdnimg.cn/blog_migrate/cd816a8d23db3de4b5a1bb261017228a.png)
头文件只提供函数声明,库文件提供实现的代码。
静态函数库:用.a作为文件的后缀,生成目标代码时会被加入到其中,生成代码体积大,速度快。
共享(动态)函数库:存放可执行程序在运行的时候才会被加载的函数,生成代码可以共享,便于升级(.so)
![](https://i-blog.csdnimg.cn/blog_migrate/546570be253254b8b74109269be14a11.png)
1.测试代码(gcc 静态库 共享动态库)
/*****starfun.h*****/
#ifndef STARFUN_H
#define STARFUN_H
#define NUM 4
#define NUMBER 3
int star1() {
int i,j,k;
for(k=1;k<=NUM;++k) {
for(i=1;i<=(NUM-k);++i)
printf(" ");
for(j=1;j<=(2*k-1);++j)
printf("*");
printf("\n");
}
return 0;
}
int star2() {
int i,j,k;
for(k=NUMBER;k>=0;--k) {
for(i=1;i<=(NUMBER-k+1);++i)
printf(" ");
for(j=1;j<=(2*k-1);++j)
printf("*");
printf("\n");
}
return 0;
}
#endif
/*hello.h*/
#ifndef HELLO_H
#define HELLO_H
void hello() {
star1();
printf("hello,my friends\n");
}
#endif
/*hello.c*/
void showhello() {
hello();
}
/*star.c*/
#include "starfun.h"
#include "hello.h"
#include <stdio.h>
int main() {
star1();
star2();
showhello();
return 0;
}
1.直接编译二进制文件
gcc star.c hello.c -o test
![](https://i-blog.csdnimg.cn/blog_migrate/5c79a959946606607960cfab0480421b.png)
因为在hello.c文件没声明调用的hello.c文件
在前加 void hello.c();声明即可
![](https://i-blog.csdnimg.cn/blog_migrate/db82eadeb6fccfedbac103d0d93ff2cd.png)
这个报错是因为star.c中,声明顺序有问题,应该先声明#include <stdio.h>
#include "starfun.h"
#include "hello.h"
#include <stdio.h>
运行下面代码警告消失
gcc -w star.c hello.c -o test
2.使用共享函数库
/*-fpic:生成的目标码使用相对地址
-shared:生成可被链接的共享可执行代码
-s:生成的可执行代码不含gdb调试信息*/
gcc -fpic -shared hello.o -o libhello.so
//执行文件的时候需要在这里找到
cp libhello.so /usr/lib
//-l:指定要链接的库 -L:指定库所在位置(编译的时候需要)
gcc -w star.c -L. -lhello -o mystar
//列出动态库依赖关系
ldd mystar
3.使用静态函数库
gcc -c hello.c -o hello.o
//r:插入库文件 c:建立库文件
ar -rc libhello.a hello.o //生成静态库
gcc star.c libhello.a -o mystar
2.gdb调试器
![](https://i-blog.csdnimg.cn/blog_migrate/3ea4cccc04960812641cce5abb782416.png)
3.makefile
1.直接调用.c文件编译生成
test: hello.c star.c
gcc -o test hello.c star.c
2.生成.o文件的
CC = gcc
CFLAGS = -Wall -g
all: test
test: star.o hello.o
$(CC) $(CFLAGS) star.o hello.o -o test
star.o: star.c starfun.h
$(CC) $(CFLAGS) -c star.c
hello.o: hello.c hello.h
$(CC) $(CFLAGS) -c hello.c
clean:
rm -f test *.o
3.静态库
# Makefile
CC = gcc
CFLAGS = -Wall -g
test2:star.c libhello.a //顺序有讲究从左到右,先源代码后代码库。代码库的要求,先高层的扩展库,后底层的基础库。多个源代码文件之间倒反没有顺序要求。这种顺序要求是链接器的要求。
${CC} -o $@ $^
libhello.a: hello.o
ar rcs libhello.a hello.o
hello.o: hello.c hello.h
${CC} ${CFLAGS} -c hello.c
clean:
rm -f libhello.a hello.o
4.共享动态库
# Makefile
CC = gcc
CFLAGS = -Wall -g
LDFLAGS = -L. -lhello
test3: star.c libhello.so
${CC} -o $@ $< ${LDFLAGS}
libhello.so: hello.o
${CC} -fpic -shared $< -o $@
clean:
rm -f libhello.so hello.o
1.变量 CC = gcc 调用$(CC) ${CC}也行
2.环境(全局变量)
Makefile文件中还可以使用环境变量,以及预定义变量,如$@(目标名)、$^(所有的依赖文件)、$<(第一个依赖文件),例如:
demo.o : demo.c demo.h
gcc -c $< -o $@
3.make -f makefile2