日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Makefile、多Makefile编译静态库、动态库、SRC实例总结

發布時間:2025/3/15 编程问答 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Makefile、多Makefile编译静态库、动态库、SRC实例总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

靜態庫生成及使用

calc.h

#ifndef __MY_LIB_H__

#define __MY_LIB_H__

int add(int a, int b);

#endif

calc.c

#include "calc.h"

#include <stdio.h>

int sum(int i, int j)
{
? ? return (i+j);
}

編譯:

gcc -c calc.c -o calc.o

ar -cr?libcalc.a calc.o

gcc -o main main.c ./libcalc.a

?

動態庫生成及使用

show.h

#ifndef __SHOW_H__
#define __SHOW_H__

void show(int i, char* name);

#endif

show.c

#include "show.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void show(int i, char* name)
{
? ? printf("%s=%d\n", name, i);

}

編譯:

gcc -fPIC -Wall -c show.c -o show.o

gcc -shared -o libshow.so show.o

gcc -o main main.c ./libshow.so

主函數:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "../inc/calc.h"
#include "../inc/show.h"? ? ?//可替換makefile的 -I參數添加路徑inc

int main(void)
{
? ? int s;
? ? int i = 1;
? ? int j = 2;
? ? s = sum(i,j);
?? ?printf ("%d\n", s);
? ? show(s,"sum");
?? ?return 0;
}

?

注意:

因為gcc 或者g++時編譯會在前者加lib、后者添加.a或者.so,所以有了另一種主函數寫法

cd /etc

編輯 ld.so.conf?

sudo vim ld.so.conf

加入 libshow.so?的路徑? /lib

保存之后 再執行如下命令 ldconfig

?

gcc -o main main.c? -L. ./lshow?-I../inc

或者指定lib路徑

gcc -o main.o -c main.c -Wall -I../inc
gcc -o ../bin/main main.o -L../lib -lshow -lcalc

?

?

Makefile模板

#-------------------------配置區域-----------------------

#DIR指的是.o文件和.c文件所在的目錄
DIR=

#BIN指的是最終生成的目標對象名(包括路徑),它可以是可執行程序、動態鏈接庫或靜態鏈接庫
BIN=$(DIR)/

#SHARE特指鏈接生成動態鏈接庫對象時的編譯選項
SHARE=--share

#CFLAG即compile flag,表示在編譯時所加入的選項參數
#參數包括 ?
#-Wall ?: 編譯后顯示所有警告信息
#-g ? ? : 編譯時加入調試信息,以便之后可以用gdb調試
#-fPIC ?: 編譯動態鏈接庫時加入的選項
#-I./inc: -I選項指定從哪個目錄尋找頭文件,在這指定之后,在源文件中包含頭文件就可以使用<>,這里./inc即為指定的目錄
CFLAG=

#LFLAG即library flag,表示鏈接生成可執行程序時所要鏈接的所有庫的選項參數
#-L./lib : -L指示動態/靜態鏈接庫所在的目錄,這里./lib即所在的目錄
#-l ? ? ?: -l指示動態/靜態鏈接庫的名字,注意: 這里的庫名字并不包括前綴(lib)和后綴(.a或.so)
#$(SHARE) : 取SHARE變量對應的動態鏈接庫鏈接選項--share
LFLAG=

#CC即編譯鏈接命令gcc -o 用于編譯或者鏈接動態庫以及可執行程序
CC=gcc -o

#AR即ar -cr ,ar -cr是專門鏈接生成靜態庫的命令
#-c : 即create,創建靜態庫
#-r : 即replace,當靜態庫改變時,替代原有靜態庫
AR=ar -cr

#最終用的是哪個鏈接命令
#鏈接生成動態庫和可執行程序用CC
#鏈接生成靜態庫用AR
CO=$(CC)


#-------------------------以下為通用不變區域-----------------------

#SRC指的是指定目錄下的所有.c文件名,OBJ指的是指定目錄下的所有.o文件名
SRC=$(wildcard $(DIR)/*.c)
OBJ=$(patsubst %.c, %.o, $(SRC))

#鏈接命令
all:$(BIN)
$(BIN):$(OBJ)
?? ?$(CO) $@ $^ $(LFLAG)

#編譯命令
$(DIR)/%.o:$(DIR)/%.c
?? ?$(CC) $@ -c $< $(CFLAG)


#清除無用文件
.PHONY:clean
clean:
?? ?rm $(OBJ) $(BIN)

$@ --目標文件,$^?--所有的依賴文件,$<?--第一個依賴文件

.PHONY :是一個偽目標,可以防止在Makefile中定義的只執行命令的目標和工作目錄下的實際文件出現名字沖突,另一種是提交執行makefile時的效率。

wildcard : 擴展通配符

notdir : 去除路徑

patsubst :替換通配符

-I../inc :通用頭文件?

?

整個項目工程都包括什么?

一個工程目錄下一般有7個目錄,一個聯合編譯Makefile文件:

?????????<1>、bin目錄:一般存放可執行程序

?????????<2>、etc目錄:存放配置文件

?????????<3>、lib目錄 :存放所有的庫文件,包括動態庫和靜態庫

?????????<4>、inc目錄:存放所有的公共頭文件,一般是動態庫和靜態庫對應的頭文件

?????????<5>、src目錄:存放項目源碼文件和編譯它的Makefile文件

?????????<6>、static目錄:存放靜態庫源文件和編譯它的Makefile文件

?????????<7>、dynamic目錄:存放動態庫源文件和編譯它的Makefile文件

?

為src、static、dynamic目錄下的源文件編寫不同的Makefile文件

為static目錄,即靜態鏈接庫源代碼目錄。在此目錄下要生成靜態鏈接庫文件libstatic_test.a

#------------------------------配置區域----------------------------

DIR=.

#靜態庫名以lib為前綴,.a為后綴
BIN=../lib/libcalc.a

SHARE=--share

CFLAG=

LFLAG=

CC=gcc -o

AR=ar -cr

#編譯靜態庫用ar -cr命令
CO=$(AR)
#-------------------------以下為通用不變區域-----------------------

SRC=$(wildcard $(DIR)/*.c)
OBJ=$(patsubst %.c, %.o, $(SRC))
#$(info $(OBJ))

all:$(BIN)
$(BIN):$(OBJ)
?? ?$(CO) $@ $^ $(LFLAG)

$(DIR)/%.o:$(DIR)/%.c
?? ?$(CC) $@ -c $< $(CFLAG)

.PHONY:clean
clean:
?? ?rm $(OBJ) $(BIN)

?

為dynamic目錄,即動態鏈接庫源代碼目錄,在此目錄下生成動態鏈接庫?libshow.so

#------------------------------配置區域----------------------------

DIR=.

#動態庫名以lib為前綴,以.so為后綴
BIN=../lib/libshow.so

SHARE=--share

#動態鏈接庫編譯時需要-fPIC選項
CFLAG=-fPIC

#鏈接動態庫需要--share選項
LFLAG=$(SHARE)

CC=gcc -o

AR=ar -cr

#編譯動態鏈接庫用gcc -o命令
CO=$(CC)
#-------------------------以下為通用不變區域-----------------------

SRC=$(wildcard $(DIR)/*.c)
OBJ=$(patsubst %.c, %.o, $(SRC))

all:$(BIN)
$(BIN):$(OBJ)
?? ?$(CO) $@ $^ $(LFLAG)

$(DIR)/%.o:$(DIR)/%.c
?? ?$(CC) $@ -c $< $(CFLAG)

.PHONY:clean
clean:
?? ?rm $(OBJ) $(BIN)

?

為src目錄,即工程源代碼目錄。在此目錄下要通過鏈接動態鏈接庫libshow.so和靜態庫libcalc.a 來生成可執行文件main

#-------------------------配置區域-----------------------

#源碼所在的目錄
DIR=.

#在源碼所在目錄下生成可執行文件main
BIN=../bin/main

SHARE=--share

#顯示所有編譯警告,并指示公共頭文件(靜態庫和動態庫的頭文件)所在目錄
CFLAG= -Wall -I../inc

#在../lib目錄中鏈接兩個外部庫文件
LFLAG=-L../lib -lshow -lcalc

CC=gcc -o

AR=ar -cr

#使用gcc -o 鏈接命令
CO=$(CC)


#-------------------------以下為通用不變區域-----------------------

#SRC指的是指定目錄下的所有.c文件名,OBJ指的是指定目錄下的所有.o文件名
SRC=$(wildcard $(DIR)/*.c)
OBJ=$(patsubst %.c, %.o, $(SRC))

#鏈接命令
all:$(BIN)
$(BIN):$(OBJ)
?? ?$(CO) $@ $^ $(LFLAG)

#編譯命令
$(DIR)/%.o:$(DIR)/%.c
?? ?$(CC) $@ -c $< $(CFLAG)


#清除無用文件
.PHONY:clean
clean:
?? ?rm $(OBJ) $(BIN)

?

本程序tree

?

編寫聯合編譯Makefile文件

.PHONY:test
test:
?? ?make -C ./dynamic
?? ?#make -C:進入指定的目錄下執行make命令
?? ?make -C ./static
?? ?#將靜態、動態庫文件拷貝到lib目錄下
?? ?#cp ./static/libstatic_test.a ?./lib
?? ?#cp ./dynamic/libdynamic_test.so ?./lib
?? ?
?? ?make -C ./src

.PHONY:install
install:
?? ?#為lib目錄下的動態鏈接庫文件在/usr/lib目錄下創建軟連接,這里使用的必須是絕對路徑
?? ?sudo ln -s /mnt/test/lib/libshow.so ?/usr/lib/libshow.so?
?? ?#將最后生成的可執行文件main拷貝到./bin目錄下
?? ?#mv ./src/main ./bin

.PHONY:clean
clean:
?? ?make clean -C ./dynamic
?? ?#make clean -C: 進入指定目錄下執行make clean命令
?? ?make clean -C ./static
?? ?make clean -C ./src

?

最后得出:

總結

以上是生活随笔為你收集整理的Makefile、多Makefile编译静态库、动态库、SRC实例总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。