链接静态库 Vs。 Linux 中的共享库
Posted
技术标签:
【中文标题】链接静态库 Vs。 Linux 中的共享库【英文标题】:Linking static library Vs. shared library in Linux 【发布时间】:2020-07-15 20:54:34 【问题描述】:我正在阅读一本关于 Raspberry Pi 的书以了解 Raspberry Pi。
书中的一个项目展示了一个 C++ 类,它提供了访问 Raspberry Pi 上的 GPIO 的方法;类名是“gpio”。
书中讲述了使用这个类的两种方法:
编写 C++ 代码,simple.cpp:在 simple.cpp 中,main 方法实例化 gpio 类并调用其公共方法。
要编写 Python 代码:gpio.so 必须使用 Boost.python 创建。然后写simple.py,在里面导入gpio,调用它的public方法。
第一种方法很简单:将simple.cpp和gpio.cpp链接在一起,创建一个单独的exe。
对于后者,本书推荐使用 Boost.Python。
我下载了Boost包,调用bootstrap.sh和b2如下:
$ sudo ./bootstrap.sh --with-libraries=python --with-python-version=3.7
$ sudo ./b2 cxxflags=-fPIC -link=shared install
这些创建了 libboost_python37.so.1.73.0。
我尝试按如下方式构建 gpio.so:
PROG = gpio.so
CC = g++
CPPFLAGS = -c -fPIC -I/usr/include/python3.7m/ -I/usr/local/boost_1_73_0
LDFLAGS = -shared -pthread -L/usr/local/boost_1_73_0/bin.v2/libs/python/build/gcc-
8/release/python-3.7/threading-multi/visibility-hidden
LLIBS = -lboost_python37
OBJS = gpio.o
$(PROG) : $(OBJS)
$(CC) $(LDFLAGS) -o $(PROG) $(OBJS) $(LLIBS)
gpio.o : gpio.h
$(CC) $(CPPFLAGS) -c gpio.cpp
上面创建的 gpio.so 没有任何致命错误。
但如果我执行 'ldd gpio.so',它的输出会显示“libboost_python37.so.1.73.0 => not found”。
如果我运行 simple.py,它的输出显示“ImportError: libboost_python37.so.1.73.0: cannot 打开共享对象文件:没有这样的文件或目录”。
当我使用静态boost python库时,我可以完成上面的第二种方法:从python代码调用C++方法。
我的开发环境是在具有 4GB 内存的 Raspberry Pi 4 型号 B 上。操作系统是 Raspbian GNU/Linux 10 (buster)。开发软件包括:
-
自 2020 年 7 月 15 日起的 Boost 包:修订版 1.73.0。
Python 3.7.3(32 位)
g++ (Raspbian 8.3.0-6+rpi1) 8.3.0
【问题讨论】:
【参考方案1】:我尝试按如下方式构建 gpio.so:
您的命令行告诉链接器如何在链接时找到libboost_python3.7.so
。但它没有告诉运行时加载器如何在运行时找到那个库。
要告诉运行时加载器,请使用-rpath /path/to/library
链接器标志。那就是:
BOOST_LIB_PATH = /usr/local/boost_1_73_0/bin.v2/libs/python/build/gcc-8/release/python-3.7/threading-multi/visibility-hidden
LDFLAGS = ... -L $BOOST_LIB_PATH -Wl,-rpath,$BOOST_LIB_PATH ...
安装 libbost...
到系统目录实际上可能会更好,而不是从构建树中加载它。
【讨论】:
非常感谢您的回答。我尝试了 -rpath 但我没有将其识别为选项的 g++。在命令提示符处输入 'g++ -rpath' 会返回,“g++: error: unrecognized command line option '-rpath'”。 @JunBo 我已经编辑了答案:试试-Wl,-rpath,$BOOSR_LIB_PATH
。
不,它不起作用:在“-rpath”之后放置一个逗号。 g++ 不知道 '-rpath' 是什么。
@JunBo 你一定做错了什么。 -Wl,-rpath,/path/to/lib
应该是单个参数,没有空格。从那时起,所有版本的 GCC 都支持这一点。编辑您的问题以显示您尝试的 实际 命令,以及产生的错误是什么。
@Empployed 俄语 非常感谢。您的最后一条评论解决了这个问题。我在“Wl”和“-rpath”之间有一个空格,“-rpath”和“/path/to/lib”之间有一个空格。我没有意识到整个事情是一个“单一参数”。以上是关于链接静态库 Vs。 Linux 中的共享库的主要内容,如果未能解决你的问题,请参考以下文章