Linux - Makefile & 庫文件

前言

Linux ->工程管理(目錄結構)c++

Object(目錄):
 DataBase(目錄):數據庫操做
 Core(目錄):項目核心代碼
 DateData(目錄):基礎的業務邏輯
 Inter(目錄):網絡部分的代碼
  .....
假設每一個目錄裏有100個.c文件

gcc -o main 全部.c文件
此時若要編譯,使用gcc就十分不方便了
並且,編譯了一大坨之後,若是要修改其中一個文件,得把這一坨拉回來從新編譯
引入了Makefile數據庫

Makefile文件

《跟我一塊兒寫Makefile》
makefile最直觀的好處:只須要一個make命令,徹底自動編譯vim

新建makefile文件並使用

至關於gcc的集合體,把gcc的操做寫在了makefile文件裏,更具備條理性windows

[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 <stdio.h> //printf
#include <stdlib.h> //存在結束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.cbash

/*run.c*/
#include "./my_math.h"
#include <stdio.h>
#include <stdlib.h>

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=gccspa

/*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"3d

CC=g++
file=main.o add.o mux.o div.o sub.o
VPATH=.:./Math 
main:$(file)
$(file):
clean:
    rm *.o  main

爲了防止生成過多的中間文件

執行完main之後執行cleanobjcode

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

圖片.png

庫文件

庫文件:將用戶寫好的程序打包成一個總體,當其餘模塊或用戶使用時,只須要有這個庫文件就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

圖片.png

共享庫(動態庫)

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

相關文章
相關標籤/搜索