💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤
📃個人主頁 :阿然成長日記 👈點擊可跳轉
📆 個人專欄: 🔹數據結構與算法🔹C語言進階🔹C++🔹Liunx
🚩 不能則學,不知則問,恥于問人,決無長進
🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍
文章目錄
- 一、庫的基礎知識
- 二、如何編寫靜態庫
- 1.原理簡述
- 2.實際操作
- 使用makefile文件自動化構建
- 靜態庫的使用
前言:
本篇博客講解兩個類型的庫:動態庫(.so) 和 靜態庫(.a).的制作。
一、庫的基礎知識
庫的作用:提升開發效率。隱藏源代碼
庫的本質:將所有的[.o
]結尾的可執行目標二進制文件打包形成一個文件夾。
二、如何編寫靜態庫
1.原理簡述
你編寫了好幾個文件,給別人使用,但是又不想讓使用者看到內部源代碼,此時有沒有什么辦法呢。
本質就是隱藏.c源文件。
-
第一步:將所有.c的文件形成.o文件
-
第二步:將所有的.o使用
ar
指令打包成一個庫文件。 -
具體流程如下圖:
這樣做的好出有:
(1)將所有的源文件打包好,防止使用者再拷貝時丟失原文件。提高了使用效率。
(2)使用者無法查看源碼,提高了安全性
2.實際操作
分別創建了4個文件:mymath.h mymath.c myprint.h myprint.c.
- 1.<mymath.h>:
#pragma once
#include<stdio.h> extern int addToTarget(int start, int end);//聲明函數
- 2.mymath.c
#include "mymath.h" # //這段函數的作用是計算start-end之間的和int addToTarget(int start, int end) { int sum = 0; int i = start; for(i; i <= end; i++){ sum += i; } return sum; }
- 3.myprint.h
#pragma once #include<stdio.h>
#include<time.h> extern void Print(const char* str);
- 4.myprint.c
#include "myprint.h" //這段函數功能是輸出傳入的字符串,后面加上時間戳
void Print(const char* str)
{printf("%s[%d]\n",str,(int)(time(NULL)));
}
有了上面四個文件后,還需要寫一個main方法使用這些函數。
#include "myprint.h"
#include "mymath.h" int main()
{ Print("hello,world"); int res = addToTarget(1,100); printf("res: %d\n",res); return 0;
}
開始制作靜態庫:
第一步:將所有的.c文件
–>.o文件
使用gcc的【-c
】選項,代碼如下:
gcc -o myprint.o -c myprint.c
gcc -o mymath.o -c mymath.c
注意:main函數不用參與,每個使用者都會有自己的main方法去調用庫文件。
第二步:o文件打包成名字叫hello的靜態庫
知識補充:
【ar】指令:
ar
-[選項]
+lib+庫文件名.a
+所有.o文件
選項這里只說r
(replace替換),c
(create創建)就可以了,就足以讓我們創建靜態庫了.
注意: 格式一定是lib+庫文件名
.a。也就是說要形成的靜態庫的名字 前綴必須是lib,后綴必須是.a,中間可以隨便起名字.
執行代碼:
ar -rc libhello.a main.o myprint.o mymath.o
可以發現,此時目錄下面就會存在剛打包好的庫文件了,但是,還需要結合對應的頭文件才能正確的使用庫文件中的函數。往下學!
使用makefile文件自動化構建
理清楚一個文件形成靜態庫的過程后 總結來說: .c文件 —> .o文件 —>
打包形成靜態庫
既然是這么一套固定的流程,那么我們完全可以用Makefile來完成這些工作。需要注意的是搞清各個文件的依賴關系,然后再進行編寫。
所以最后的Makefile編寫如下:
libhello.a: mymath.o myprint.o ar -rc libhello.a mymath.o myprint.o
mymath.o : mymath.c gcc -o mymath.o -c mymath.c
myprint.o: myprint.c gcc -o myprint.o -c myprint.c .PHONY:clean
clean: rm -rf *.o libhello.a
這樣還沒有結束:還有對應的許多頭文件呢。一般都是.h聲明,然后從.o打包形成的庫里面找。
-
所以我們還需要做一件工作:將.h和.a文件規整到一起.在Makefile加入以內容:就是將頭文件和庫文件規整在一起,邏輯如下
-
-
makefile代碼如下
.PHONY:hello
hello: mkdir -p hello/lib mkdir -p hello/include cp -rf *.h hello/include cp -rf *.a hello/lib
- 總結來說: .c文件 —> .o文件 —> 打包形成靜態庫–>最后將.h和.a文件規整到一起
這樣就制作好了一個靜態庫!如何去使用呢?
靜態庫的使用
方法一:直接拷貝到系統路徑
頭文件gcc系統默認搜索路徑是:
/usr/include
庫文件gcc系統默認搜索路徑是:/lib64 或者 /usr/lib64
- 可以將你編寫的靜態庫拷貝進/usr/lib64。頭文件拷貝進/usr/include ;但是這樣做會污染原來別人已經寫好的庫。不建議使用
方法二:指定路徑搜索
我們可以直接在編譯的時候加上頭文件和庫文件的路徑.
對于上面的代碼我們執行:
gcc main.c -I ./hello/include/ -L ./hello/lib/ -lhello
就可以指定路徑進行查找。
選項:
-I
(i的大寫)表示頭文件的搜索路徑
-L表示庫文件的搜索路徑
-l(小寫的L)表示在特定路徑下,要使用哪一個庫.