當(dāng)前位置 主頁(yè) > 技術(shù)大全 >
SO文件通常以“.so”為后綴,廣泛應(yīng)用于C/C++等編程語(yǔ)言中
本文將深入探討如何在Linux環(huán)境下打包SO文件,包括從編寫代碼到生成可執(zhí)行文件并打包SO文件的完整流程,同時(shí)介紹一些高級(jí)技巧,如使用Cython將Python文件打包成SO文件
一、編寫C/C++代碼并生成SO文件 首先,我們從編寫C/C++代碼開始
假設(shè)我們有一個(gè)簡(jiǎn)單的C++項(xiàng)目,其中包含一個(gè)名為`mysocket`的庫(kù),以及使用該庫(kù)的主程序`main`
1. 編寫庫(kù)代碼 創(chuàng)建一個(gè)名為`socketLib`的目錄,并在其中編寫我們的庫(kù)代碼
例如,我們有兩個(gè)文件:`XTcp.cpp`和`XTcp.h`
// XTcp.h
ifndef XTCP_H
define XTCP_H
class XTcp {
public:
voidconnect();
};
endif
// XTcp.cpp
include XTcp.h
include
Makefile for socketLib
CC = g++
CFLAGS = -fPIC -shared -std=c++11
TARGET = libmysocket.so
SRCS = XTcp.cpp
OBJS =$(SRCS:.cpp=.o)
all:$(TARGET)
$(TARGET): $(OBJS)
$(CC)$(CFLAGS) -o $@ $^
clean:
rm -f$(OBJS) $(TARGET)
執(zhí)行`make`命令后,會(huì)在當(dāng)前目錄下生成`libmysocket.so`文件
3. 編寫主程序并使用SO文件
現(xiàn)在,我們編寫一個(gè)主程序`main`來(lái)使用這個(gè)SO文件 創(chuàng)建一個(gè)名為`mainApp`的目錄,并在其中編寫代碼
// main.cpp
include
Makefile for mainApp
CC = g++
CFLAGS = -I/path/to/socketLib -L/path/to/socketLib -lmysocket
TARGET = main
SRCS = main.cpp
OBJS =$(SRCS:.cpp=.o)
all:$(TARGET)
$(TARGET): $(OBJS)
$(CC)$(CFLAGS) -o $@ $^
clean:
rm -f$(OBJS) $(TARGET)
注意,`-I`選項(xiàng)用于指定頭文件搜索路徑,`-L`選項(xiàng)用于指定庫(kù)文件搜索路徑,`-l`選項(xiàng)用于指定鏈接的庫(kù)名(不需要加前綴`lib`和后綴`.so`)
執(zhí)行`make`命令后,會(huì)在當(dāng)前目錄下生成`main`可執(zhí)行文件 但是,在運(yùn)行`./main`時(shí),可能會(huì)遇到以下錯(cuò)誤:
./main: error while loading shared libraries: libmysocket.so: cannot open shared object file: No such file or directory
這是因?yàn)橄到y(tǒng)找不到`libmysocket.so`文件 可以通過(guò)以下幾種方法解決:
- 臨時(shí)修改環(huán)境變量:`export LD_LIBRARY_PATH=/path/to/socketLib`
- 修改用戶環(huán)境變量:將`export LD_LIBRARY_PATH=/path/to/socketLib`添加到`~/.bashrc`的末尾,然后執(zhí)行`source ~/.bashrc`
- 將SO文件復(fù)制到系統(tǒng)默認(rèn)的庫(kù)路徑中,如`/usr/lib`或`/usr/local/lib`,并運(yùn)行`ldconfig`命令更新庫(kù)緩存
二、使用Cython將Python文件打包成SO文件
除了C/C++,Cython也提供了一種將Python代碼打包成SO文件的方法,從而可以在C/C++代碼中調(diào)用Python函數(shù),或者提高Python代碼的執(zhí)行效率
1. 安裝Cython
首先,確保已安裝Cython和編譯工具鏈
pip install cython
sudo yum install python-devel gcc CentOS
sudo apt-get install python-dev gcc Ubuntu
2. 編寫Python代碼和setup.py
創(chuàng)建一個(gè)名為`hello`的目錄,并在其中編寫`hello.py`和`setup.py`
hello.py
def greet(name):
return hello + name
setup.py
from setuptools import setup
from Cython.Build import cythonize
setup(
ext_modules = cythonize(【hello.py】)
)
3. 打包成SO文件
執(zhí)行以下命令來(lái)打包`hello.py`文件:
python setup.pybuild_ext --inplace
執(zhí)行完該命令后,會(huì)在同級(jí)目錄下生成一個(gè)`hello.cpython- 可以重命名為`hello.so`以便使用
4. 測(cè)試SO文件
編寫一個(gè)測(cè)試文件`demo.py`來(lái)測(cè)試生成的SO文件
demo.py
from hello import greet
print(greet(tom))
運(yùn)行`python demo.py`,輸出應(yīng)為`hellotom` 此時(shí),即使刪除`hello.py`文件,程序仍然可以正常運(yùn)行,因?yàn)閌hello`模塊已經(jīng)來(lái)源于SO文件
三、將可執(zhí)行文件依賴的SO文件打包
在部署Linux應(yīng)用程序時(shí),有時(shí)需要將可執(zhí)行文件及其依賴的所有SO文件一起打包,以便在其他機(jī)器上運(yùn)行 這可以通過(guò)以下步驟實(shí)現(xiàn):
1.使用`ldd`命令查看可執(zhí)行文件依賴的所有SO文件
2.使用`awk`命令提取SO文件的路徑
3.使用`xargs`命令將SO文件拷貝到一個(gè)目錄中
4.使用`tar`命令將SO文件打包成一個(gè)壓縮文件
例如:
ldd /path/to/executable | awk{print $3} | xargs -I{} cp -v {} /path/to/copy/so/files/dir/ && tar -czvf /path/to/so/files.tar.gz /path/to/copy