学习笔记:多个静态库连接成一个动态库例子

目标:

将多个静态库链接为一个动态库,提供统一的接口给外部使用。

看一下例子的目录文件:

学习笔记:多个静态库连接成一个动态库例子_第1张图片

编译后将生成 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的内容

#include "apl_mutiply.h"

int mutiply(int a, int b)
{
	return a * b;
}

#include "apl_mutiply.h"

int mutiply(int a, int b);
(3) apl_myApi.cpp 及 apl_myApi.h的内容

#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内容

#include 
#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;
}
(5)allMake.sh 这个shell脚本是编译全部文件,内容如下:

#!/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"

}

你可能感兴趣的:(编程语言)