Linux - Makefile & 库文件

前言

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

Linux - Makefile & 库文件_第1张图片

库文件

库文件:将用户写好的程序打包成一个整体,当其他模块或用户使用时,只需要有这个库文件就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

Linux - Makefile & 库文件_第2张图片

共享库(动态库)

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文件中

你可能感兴趣的:(makefile,linux)