前言
Linux ->工程管理(目录结构)
Object(目录):
DataBase(目录):数据库操作
Core(目录):项目核心代码
DateData(目录):基础的业务逻辑
Inter(目录):网络部分的代码
.....
假设每个目录里有100个.c文件
gcc -o main 所有.c文件
此时若要编译,使用gcc就十分不方便了
而且,编译了一大坨以后,如果要修改其中一个文件,得把这一坨拉回来重新编译
引入了Makefile
Makefile文件
《跟我一起写Makefile》
makefile最直观的好处:只需要一个make命令,完全自动编译
新建makefile文件并使用
相当于gcc的集合体,把gcc的操作写在了makefile文件里,更具有条理性
[root@localhost 2020-03-09]# vim makefile
[root@localhost 2020-03-09]# ls
add.c div.c main.c makefile mux.c my_math.h sub.c
[root@localhost 2020-03-09]# make
[root@localhost 2020-03-09]# ls
add.c div.c main main.o mux.c my_math.h sub.o
add.o div.o main.c makefile mux.o sub.c
[root@localhost 2020-03-09]# ./main
a+b=32
a-b=8
a*b=240
a/b=1.666667
[root@localhost 2020-03-09]# make clean
rm *.o main
[root@localhost 2020-03-09]# ls
add.c div.c main.c makefile mux.c my_math.h sub.c
/*makefile内部*/
main:main.o add.o div.o sub.o mux.o
gcc -o main main.o add.o div.o sub.o mux.o
main.o:main.c
gcc -c main.c
add.o:add.c
gcc -c add.c
mux.o:mux.c
gcc -c mux.c
sub.o:sub.c
gcc -c sub.c
div.o:div.c
gcc -c div.c
clean:
rm *.o main
其余部分代码
/*add.c*/
#include "./my_math.h"
int my_add(int a,int b)
{
return a+b;
}
/*div.c*/
#include "./my_math.h"
#include //printf
#include //存在结束exit(0)
double my_div(int a,int b)
{
if(b==0)
{
printf("error");
exit(0);
}
return (a*1.0)/b;
}
/*my_math.h*/
#ifndef _MY_MATH_H
#define _MY_MATH_H
int my_add(int,int);
int my_sub(int,int);
int my_mux(int,int);
double my_div(int,int);
#endif
假设两个main函数共用部分文件
新建一个.c文件 run.c
/*run.c*/
#include "./my_math.h"
#include
#include
int main(){
printf("helloL%d",my_div(100,34)-my_add(1,20));
}
/*makefile文件*/
all:main run
run:run.o add.o div.o
gcc -o run run.o add.o div.o
main:main.o add.o div.o sub.o mux.o
gcc -o main main.o add.o div.o sub.o mux.o
add.o:add.c
gcc -c add.c
mux.o:mux.c
gcc -c mux.c
sub.o:sub.c
gcc -c sub.c
div.o:div.c
gcc -c div.c
main.o:main.c
gcc -c main.c
run.o:run.c
gcc -c run.c
clean:
rm *.o main
makefile简化写法
编译语句,编译器会自动推导
/*makefile*/
main:main.o add.o div.o sub.o mux.o
add.o:add.c
mux.o:mux.c
sub.o:sub.c
div.o:div.c
main.o:main.c
clean:
rm *.o main
默认cc编译器
[root@localhost 2020-03-09]# make
cc -c -o main.o main.c
cc -c -o add.o add.c
cc -c -o div.o div.c
cc -c -o sub.o sub.c
cc -c -o mux.o mux.c
cc main.o add.o div.o sub.o mux.o -o main
强制使用gcc/g++编译器
首部加上CC=gcc
/*makefile*/
CC=g++
main:main.o add.o div.o sub.o mux.o
add.o:add.c
mux.o:mux.c
sub.o:sub.c
div.o:div.c
main.o:main.c
clean:
rm *.o main
进一步简化makefile
CC=g++
main:main.o add.o div.o sub.o mux.o
main.o add.o mux.o div.o sub.o:
clean:
rm *.o main
极简makefile写法⭐
CC=g++
file=main.o add.o mux.o div.o sub.o
main:$(file)
$(file):
clean:
rm *.o main
在不同目录下
[root@localhost 2020-03-09]# tree
.
├── main.c
├── makefile
├── Math
│ ├── add.c
│ ├── div.c
│ ├── mux.c
│ └── sub.c
└── my_math.h
VPATH:./Math
先在当前目录下搜索,再去Math目录下搜索
此时的main.c 的头文件"./Math my_math.h"
CC=g++
file=main.o add.o mux.o div.o sub.o
VPATH=.:./Math
main:$(file)
$(file):
clean:
rm *.o main
为了防止生成过多的中间文件
执行完main以后执行cleanobj
CC=g++
file=main.o add.o mux.o div.o sub.o
VPATH=.:./Math
all:main cleanobj
main:$(file)
$(file):
clean:
rm *.o main
cleanobj:
rm *.o
库文件
库文件:将用户写好的程序打包成一个整体,当其他模块或用户使用时,只需要有这个库文件就OK
libc.so -->stdio.h string.h math.h rand.h time.h
libstdc++.so -->STL
静态库
windows : .lib
Linux : .a
生成-使用步骤
生成:
1.将所有源代码(不含有main)文件编译成中间文件(.o)
2.使用命令 ar crv libxxx.a *.o
gcc -c *.c
ar crv libxxxxx.a *.o
//注意 *.o 会把所有的.o文件打包到库里
//请确保当前文件夹.o文件都是你需要的
使用:
gcc -o main main.c -L库的路径 -l库的名称
//如果没有给出库的路径,则会去默认路径下查找 /lib 或 /usr/lib
gcc -o main main.c -L./Math -lMyMathName
参考代码
[root@izm5eb8f6yfdzvy9a9acbfz 2020-03-09]# ls
main main.c makefile Math
[root@izm5eb8f6yfdzvy9a9acbfz 2020-03-09]# cd Math
[root@izm5eb8f6yfdzvy9a9acbfz Math]# ls
add.c div.c mux.c my_math.h sub.c
[root@izm5eb8f6yfdzvy9a9acbfz Math]# gcc -c *.c
[root@izm5eb8f6yfdzvy9a9acbfz Math]# ls
add.c div.c mux.c my_math.h sub.o
add.o div.o mux.o sub.c
[root@izm5eb8f6yfdzvy9a9acbfz Math]# ar crv libMyMathName.a *.o
a - add.o
a - div.o
a - mux.o
a - sub.o
[root@localhost Math]# ls
add.c div.c libMyMathName.a mux.o sub.c
add.o div.o mux.c my_math.h sub.o
[root@localhost Math]# cd ..
[root@localhost 2020-03-09]# ls
main.c makefile Math
[root@localhost 2020-03-09]# gcc -o main main.c
/tmp/ccmTewMT.o: In function `main':
main.c:(.text+0x21): undefined reference to `my_add'
main.c:(.text+0x41): undefined reference to `my_sub'
main.c:(.text+0x61): undefined reference to `my_mux'
main.c:(.text+0x81): undefined reference to `my_div'
collect2: error: ld returned 1 exit status
[root@localhost 2020-03-09]# gcc -o main main.c -L./Math -lMyMathName
[root@localhost 2020-03-09]# ls
main main.c makefile Math
[root@localhost 2020-03-09]# ./main
a+b=32
a-b=8
a*b=240
a/b=1.666667
共享库(动态库)
windows: .dll
Linux : .so
生成-使用-执行步骤
生成
gcc -shared -fPIC -o libxxxxxx.so 所有功能代码的源代码
[root@localhost Math]# ls
add.c div.c libMyMathName.a mux.c my_math.h sub.c
[root@localhost Math]# gcc -shared -fPIC -o libActiveMathName.so *.c
[root@localhost Math]# ls
add.c libActiveMathName.so mux.c sub.c
div.c libMyMathName.a my_math.h
使用
gcc -o main main.c -L库的路径 -l库的名称
gcc -o main main.c -L./Math -lActiveMathName
[root@izm5eb8f6yfdzvy9a9acbf
执行
动态库在使用后,就已经在main里了,但是执行的时候,必须指明库所在路径
默认路径: /lib /usr/lib
通过环境变量来设置系统加载动态库的搜索路径:LD_LIBRARY_PATH
export LD_LIBRARY_PATH=.os所在路径
[root@locaohost 2020-03-09]# ./main
./main: error while loading shared libraries: libActiveMathName.so: cannot open shared object file: No such file or directory
[root@locaohost 2020-03-09]# ls
main main.c makefile Math
[root@locaohost 2020-03-09]# cd Math
[root@locaohost Math]# pwd
/home/Akuaner/2020-03-09/Math
[root@locaohost Math]# export LD_LIBRARY_PATH=/home/Akuaner/2020-03-09/Math
[root@locaohost Math]# echo $LD_LIBRARY_PATH
/home/Akuaner/2020-03-09/Math
[root@locaohost Math]# cd ..
[root@locaohost 2020-03-09]# ./main
a+b=32
a-b=8
a*b=240
a/b=1.666667
export LD_LIBRARY_PATH=
这个指令是临时性的,要想永久的修改该路径,可以添加到家目录(~)下的.bashrc文件中