SO文件通常以“.so”為后綴,廣泛應用于C/C++等編程語言中
本文將深入探討如何在Linux環境下打包SO文件,包括從編寫代碼到生成可執行文件并打包SO文件的完整流程,同時介紹一些高級技巧,如使用Cython將Python文件打包成SO文件
一、編寫C/C++代碼并生成SO文件 首先,我們從編寫C/C++代碼開始
假設我們有一個簡單的C++項目,其中包含一個名為`mysocket`的庫,以及使用該庫的主程序`main`
1. 編寫庫代碼 創建一個名為`socketLib`的目錄,并在其中編寫我們的庫代碼
例如,我們有兩個文件:`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)
執行`make`命令后,會在當前目錄下生成`libmysocket.so`文件
3. 編寫主程序并使用SO文件
現在,我們編寫一個主程序`main`來使用這個SO文件 創建一個名為`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`選項用于指定頭文件搜索路徑,`-L`選項用于指定庫文件搜索路徑,`-l`選項用于指定鏈接的庫名(不需要加前綴`lib`和后綴`.so`)
執行`make`命令后,會在當前目錄下生成`main`可執行文件 但是,在運行`./main`時,可能會遇到以下錯誤:
./main: error while loading shared libraries: libmysocket.so: cannot open shared object file: No such file or directory
這是因為系統找不到`libmysocket.so`文件 可以通過以下幾種方法解決:
- 臨時修改環境變量:`export LD_LIBRARY_PATH=/path/to/socketLib`
- 修改用戶環境變量:將`export LD_LIBRARY_PATH=/path/to/socketLib`添加到`~/.bashrc`的末尾,然后執行`source ~/.bashrc`
- 將SO文件復制到系統默認的庫路徑中,如`/usr/lib`或`/usr/local/lib`,并運行`ldconfig`命令更新庫緩存
二、使用Cython將Python文件打包成SO文件
除了C/C++,Cython也提供了一種將Python代碼打包成SO文件的方法,從而可以在C/C++代碼中調用Python函數,或者提高Python代碼的執行效率
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
創建一個名為`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文件
執行以下命令來打包`hello.py`文件:
python setup.pybuild_ext --inplace
執行完該命令后,會在同級目錄下生成一個`hello.cpython- 可以重命名為`hello.so`以便使用
4. 測試SO文件
編寫一個測試文件`demo.py`來測試生成的SO文件
demo.py
from hello import greet
print(greet(tom))
運行`python demo.py`,輸出應為`hellotom` 此時,即使刪除`hello.py`文件,程序仍然可以正常運行,因為`hello`模塊已經來源于SO文件
三、將可執行文件依賴的SO文件打包
在部署Linux應用程序時,有時需要將可執行文件及其依賴的所有SO文件一起打包,以便在其他機器上運行 這可以通過以下步驟實現:
1.使用`ldd`命令查看可執行文件依賴的所有SO文件
2.使用`awk`命令提取SO文件的路徑
3.使用`xargs`命令將SO文件拷貝到一個目錄中
4.使用`tar`命令將SO文件打包成一個壓縮文件
例如:
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