前言:當我們寫了一段代碼實現了一個方法,如果我們不想把方法的實現過程暴露給別人看,可以把代碼打包成一個庫,其中形成后綴為.a的是靜態庫,后綴為.so的為動態庫;當別人想使用你的方法時,把打包好的庫跟頭文件一起扔給他就行。
一、靜態庫
1.1生成一個簡單的靜態庫
①首先創建兩個文件,一個.c方法的實現,一個.h方法的聲明;
②簡單實現一下
//mymath.h文件
#pragma once int add(int x,int y);int sub(int x,int y);
//mymath.c文件1 #include "mymath.h" 2 int add(int x,int y) 3 { 4 return x+y; 5 } 6 int sub(int x,int y) 7 { 8 return x-y; 9 }
③makefile怎么寫?
首先要把所有.c文件生成.o文件,然后把.o文件打包生成庫(如果是靜態庫就是.a;如果是動態庫就是.o)
//makefile文件1 lib=libmymath.a 2 $(lib):mymath.o 3 ar -rc $@ $^ ## ar :生成靜態庫命令; rc:把所有.o文件打包生成.a文件,如果.a里面已存在則覆蓋; $@ :依賴目標 $^:依賴文件;4 mymath.o:mymath.c5 gcc -c mymath.c ##-c 默認生成.o文件6 .PHONY:clean ##清理7 clean:8 rm -rf *.o *.a mylib 10 .PHONY:output ##庫發布 11 output: 12 mkdir -p mylib/lib #創建一串路徑 13 mkdir -p mylib/include 14 cp *.h mylib/include #把頭文件拷貝到include15 cp *.a mylib/lib #把.a 庫文件拷貝到lib
~
④make一下
當前目錄下已寫好.c .h和makefile文件:
make后可以看到生成了mymath的.o文件,然后由.o文件生成靜態庫 libmymath.a:
⑤發布一下
查看一下當前目錄:
可以看到生成的mylib文件就是我們制作的庫文件,查看里面的內容:
可以看到其中include文件中包含了方法的頭文件,lib文件中包含的就是靜態庫文件!
既然生成好了就來使用以下吧!
1.2 靜態庫的使用
①創建一個test文件然后把mylib文件拿過來用
②創建一個.c文件里面包含main函數來使用這個庫
//main.c文件
1 #include "mymath.h"
2 int main()
3 {
4 printf("1+1= %d\n",add(1,1));
5 return 0;
6 }~
③靜態庫的編譯鏈接
注意:庫的編譯鏈接:gcc + 帶main函數的.c文件 + -I + 頭文件所在的目錄 +?-L?+?庫所在的目錄?+?-l跟庫真實的名字(去掉前綴去掉后綴)
編譯后查看當前目錄:
運行:
這樣就成功的完成了靜態庫的制作到使用!接下來我們來實現下動態庫吧!
二、動態庫
2.1 生成一個簡單的動態庫
我們回到lesson16,然后makeclean,然后再創建兩個.c文件分別存放兩個方法,和其對應的.h方法使用聲明(這兩個方法用來生成動態庫)
隨便實現一下這兩個方法(主要為了展示動態庫的生成和使用):
//mylog.h文件1 #pragma once 2 void log(char* message);
//mylog.c文件1 #include "mylog.h"2 void log(char* message)3 {4 printf("%s\n",message); 5 }
//myprint.h文件1 #pragma once 2 void print();
//myprint.c文件1 #include "myprint.h"2 void print()3 {4 printf("hello linux!!!\n"); 5 }
2.2 makefile怎么寫
首先makefile 一次生成兩個庫,一個靜態庫、一個動態庫,生成之后發布為mylib(動、靜態庫、頭文件都在里面):
//makefile文件1 static_lib=libmymath.a ##靜態庫2 dynamic_lib=libmymethod.so ##靜態庫3 .PHONY:all4 all:$(static_lib) $(dynamic_lib)5 $(static_lib):mymath.o6 ar -rc $@ $^ ## ar :生成靜態庫命令; rc:把所有.o文件打包生成.a文件,如果.a里面已存在則覆蓋; $@ :依賴目標 $^:依賴文件;7 mymath.o:mymath.c8 gcc -c mymath.c ##-c 默認生成.o文件9 10 $(dynamic_lib):myprint.o mylog.o11 gcc -shared -o $@ $^ ##shared: 生成動態庫12 myprint.o:myprint.c13 gcc -fPIC -c $^ ##fpic :產生位置無關碼14 mylog.o:mylog.c15 gcc -fPIC -c $^16 .PHONY:clean ##清理17 clean:18 rm -rf *.o *.a mylib *.so 19 .PHONY:output ##庫發布20 output: 21 mkdir -p mylib/lib #創建一串路徑22 mkdir -p mylib/include 23 cp *.h mylib/include #把頭文件拷貝到include24 cp *.a mylib/lib #把.a 庫文件拷貝到lib25 cp *.so mylib/lib
make一下:
mymath生成的靜態庫libmumatg.a ; mylog和myprint生成的libmymethod.so動態庫;
發布一下:
拿到test文件夾里用一下:
2.3 動態庫的使用
創建一個main函數調用它:
//main.c文件
1 #include "mylog.h"
2 #include "myprint.h"
3 #include "mymath.h"
4 #include <stdio.h>
5 int main()
6 {
7 printf("1-1=%d\n",sub(1,1));
8 log("hello linux!!!\n");
9 print();
10 print();
11 return 0;
12 }
編譯鏈接:
運行:
報錯因為加載的時候找不到動態庫,解決方法:
①、把庫拷貝到系統默認的路徑下 /lib64/usr/lib64/
②、在系統文件下創建軟連接? /lib64/usr/lib64/
③、LD-LIBRARY_PATH 導入環境變量
④、進入/etc/ld.so.conf.d創建.conf文件并把庫路徑加進去,然后重新加載 ldconfig
這里我隨便用一個,導入環境變量的方法:
導入前:
導入后:
再運行:
動態庫使用成功!!