學習筆記:多個靜態庫連線成一個動態庫例子
阿新 • • 發佈:2019-02-02
目標:
將多個靜態庫連結為一個動態庫,提供統一的介面給外部使用。
看一下例子的目錄檔案:
編譯後將生成 libAdd.a libMutiply.a , 然後將這兩個.a靜態庫和apl_myApi.o 連結成為一個動態庫 libMyApi.so。提供這個動態庫給app.cpp使用。
(1)apl_add.cpp 及 apl_add.h 的內容
#include "apl_add.h"
int add(int a, int b)
{
return a + b;
}
int add(int, int);
(2) apl_mutiply.cpp 及 apl_mutiply.h的內容
(3) apl_myApi.cpp 及 apl_myApi.h的內容#include "apl_mutiply.h" int mutiply(int a, int b) { return a * b; } #include "apl_mutiply.h" int mutiply(int a, int b);
#include "apl_add.h"
#include "apl_mutiply.h"
#include "apl_myApi.h"
int my_add(int a, int b)
{
return add(a,b);
}
int my_mutiply(int a, int b)
{
return mutiply(a, b);
}
int my_add(int a, int b);
int my_mutiply(int, int);
(4)app.cpp內容
(5)allMake.sh 這個shell指令碼是編譯全部檔案,內容如下:#include <iostream> #include "apl_myApi.h" using namespace std; int main() { int a = 10, b = 15; int sum = my_add(a, b); cout << "sum = " << sum << endl; int mut = my_mutiply(a, b); cout << "mutiply = " << mut << endl; return 0; }
#!/bin/bash echo "start building libAdd.a libMutiply.a libMyApi_so.so app......" g++ -c -fPIC apl_add.cpp ar -rcs libAdd.a apl_add.o g++ -c -fPIC apl_mutiply.cpp ar -rcs libMutiply.a apl_mutiply.o # two static .a lib link to a dynamic .so lib g++ -c -fPIC apl_myApi.cpp g++ -shared -fPIC apl_myApi.o -o libMyApi_so.so -L. -lAdd -lMutiply g++ -c app.cpp g++ app.o -o app -L. -lMyApi_so sudo cp libMyApi_so.so /usr/lib echo "build done.........."
注意: 這往下是想把LibAdd.a 和 libMutiply.a 連結成LibMyApi_a.a, 發現不行在編譯app.cpp的時候還是需要將這兩個庫加上不然編譯不過。
或者直接將apl_add.o 和apl_mutiply.o 和 apl_myApi.o 一起編譯成 libMyApi.a。
echo "start building libAdd.a libMutiply.a libMyApi_a.a app_s......"
g++ -c apl_add.cpp
ar -rcs libAdd.a apl_add.o
g++ -c apl_mutiply.cpp
ar -rcs libMutiply.a apl_mutiply.o
# two static .a lib link to a static .a lib
g++ -c apl_myApi.cpp
ar -rcs libMyApi_a.a apl_myApi.o #apl_add.o apl_mutiply.o #`ar -x ./libAdd.a ./libMutiply.a`
g++ -c app.cpp
g++ app.o -o app_s -L. -lMyApi_a -lAdd -lMutiply
echo "end building................"
(6)clearAll.sh shell指令碼是清除目標檔案#!/bin/bash
sudo rm -rf *.a *.o *.so app *.bak
例子比較簡單,記錄下生成靜態庫和動態庫的套路。
補充:
問題描述:
假如apl_add.c,apl_add.h 用gcc 編譯為aplAdd.a靜態庫; apl_mutiply.cpp, apl_mutiply.h 用g++編譯為aplMutiply.a靜態庫。 這時候如果apl_myApi.cpp在包含標頭檔案 apl_add.h的時候如果沒有使用extern "C" {} ,編譯也不會報錯,但是生成的libMyApi.so 在被app.cpp連結的時候會報錯:apl_add.c中的函式add沒有定義。原因是因為
aplAdd.a是gcc編譯出來的,而編譯連結libMyApi.so使用的是g++編譯器。因此在apl_myApi.cpp中必須這樣:
extern "C"
{
#include "apl_add.h"
}