Makefile学习笔记06|编译动态链接库
希望看到这篇文章的朋友能在评论区留下宝贵的建议来让我们共同成长,谢谢。
这里是目录
静态链接与动态链接
链接分为两种:静态链接、动态链接。
- 静态链接
静态链接:由链接器在链接时讲库的内容加入到可执行文件中。
优点:
- 对环境的依赖性小,具有较好的兼容性。
缺点: - 生成的程序比较大,需要更多的系统资源,在装入内存时会消耗更多的时间。
- 库函数有了更新,必须重新编译应用程序。
- 动态链接
动态链接:链接器在链接时仅仅建立与所需库函数之间的链接关系,在程序运行时才将所需资源调入可执行程序。
优点:
- 在需要的时候才会调入对应的资源函数。
- 简化程序的升级;有着较小的程序体积。
- 实现进程之间的资源共享(避免重复拷贝)。
缺点: - 应用程序在运行时依赖动态库,不能独立运行。
- 动态库依赖版本问题严重。
- 动态、静态编译对比
系统默认采用动态链接的方式进行程序编译,若想采用静态编译,需加入参数-static。
编译选项
- -fPIC
- -shared
g++ -shared -fPIC mylib.cpp -o libmylib.so
g++ test.cpp -lmylib -L/root/cpp
#!/bin/sh
LD_LIBRARY_PATH=./;
export LD_LIBRARY_PATH
./test
静态库编译选项
编译静态库时有两个常用的可选参数和一个必选参数。
选项 | 描述 |
---|---|
[c] | 不显示创建 |
[v] | 显示过程 |
r | 创建静态库 |
s | 建立索引 |
项目结构
总项目下分三个子项目,分别为xserver、xthread、xcom。
项目名称 | 路径 | 文件 | 输出 |
---|---|---|---|
xserver | ~/make/src/xserver | xserver.cpp、makefile | xserver |
xthread | ~/make/src/xthread | xthread.h、xthread.cpp、makefile | libxthread.so |
xcom | ~/make/src/xcom | xcom.h、xcom.cpp、makefile | libxcom.a |
XThread
// xthread.h
#ifndef XTHREAD_H
#define XTHREAD_H
#include <thread>
class XThread
{
public:
virtual void Start();
virtual void Wait();
private:
virtual void Main()=0;
std::thread th_;
};
#endif
// xthread.cpp
#include "xthread.h"
#include <iostream>
using namespace std;
void XThread::Start()
{
cout<<"Start Thread"<<endl;
th_ = std::thread(&XThread::Main, this);
}
void XThread::Wait()
{
cout<<"begin Wait Thread"<<endl;
th_.join();
cout<<"end Wait Thread"<<endl;
}
# makefile
TARGET=libxthread.so
OBJS=xthread.o
LDFALGS=-shared
CXXFLAGS=-fPIC
$(TARGET):$(OBJS)
$(CXX) $(LDFLAGS) $^ -O $@
clean:
$(RM) $(TARGET) $(OBJS)
.PHONY: clean
make后可生成libxthread.so。
xesrver
#include <iostream>
#include "xthread.h"
using namespace std;
class XTask:public XThread
{
public:
void Main() override
{
cout<<"XTask main"<<endl;
}
};
int main(int argc, char *argv[])
{
cout<<"XServer"<<endl;
XTask task;
task.Start();
task.Wait();
return 0;
}
TARGET=xserver
OBJS=xserver.o
CXXFLAGS=-I../xthread
LDFLAGS=-L../xthread
LIBS=-lxthread -lpthread
$(TARGET):$(OBJS)
$(CXX) $^ -o $@ $(LDFLAGS) $(LIBS)
clean:
$(RM) $(TARGET) $(OBJS)
make一下,没有出错,因为在程序运行时才会去寻找动态链接库。接下来运行程序:./xserver。结果出错:./xserver: error while loading shared libraries: libxthread.so: cannot open shared object file: No such file or directory。原因是之前的makefile中虽然指明了动态链接库的路径,但那只是在编译时将动态链接库的路径告知了make。make按照路径找到了动态链接库,并将函数的地址编译进了可执行文件中。程序执行时只有函数的地址却不知道动态链接库文件也就是.so文件的路径,故而报错。简言之就是,makefile只管编译,不管运行。为了解决这一问题,暂且编写一个shell脚本run来应付一下,后面会优化的。
# run
# 手动设定一下路径
LD_LIBRARY_PATH=../xthread
export LD_LIBRARY_PATH
./xserver
# 加上可执行权限
sudo chmod +x run
./run
这样就可以正确运行了。
都看到这里了,可以给个点赞或者评论吗?达瓦里希( ̄^ ̄)ゞ