如何交叉编译C++并构建成python库

如何交叉编译C++并构建成python库

1. 交叉编译python

  • python版本要和目标平台一致, 本文以python3.10为例
bash 复制代码
python3 --version
# Python 3.10.12

下载python安装包

bash 复制代码
wget https://www.python.org/ftp/python/3.10.0/Python-3.10.0.tgz
ls -lh Python-3.10.0.tgz # 查看完整性
tar -xzf Python-3.10.0.tgz
  • 编译
bash 复制代码
mkdir -p /workspace/python3.10-aarch64
cd /workspace/python3.10-aarch64

echo "ac_cv_file__dev_ptmx=yes" > /workspace/config.site
echo "ac_cv_file__dev_ptc=yes" >> /workspace/config.site
export CONFIG_SITE=/workspace/config.site

/workspace/Python-3.10.0/configure --host=aarch64-linux-gnu --build=x86_64-linux-gnu --prefix=/workspace/python3.10-aarch64/install --enable-shared --enable-ipv6 --disable-static --with-ensurepip=yes

make
make install

2. 交叉编译pybind11

编写交叉编译工具链

aarch64-toolchain.cmake

cmake 复制代码
# aarch64-toolchain.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)

# 设置交叉编译器
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)

# 设置路径(根据实际安装路径调整)
# set(CMAKE_FIND_ROOT_PATH /usr/aarch64-linux-gnu)
set(CMAKE_FIND_ROOT_PATH /workspace/python3.10-aarch64/install)

# 只在目标平台上查找库和头文件
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
bash 复制代码
git clone https://github.com/pybind/pybind11.git
cd pybind11/
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=aarch64-toolchain.cmake -DCMAKE_INSTALL_PREFIX=/workspace/python3.10-aarch64/install ..

make
make install

3. 交叉编译demo

demo 组成

bash 复制代码
.
├── CMakeLists.txt
├── aarch64-toolchain.cmake
├── bindings
│   └── python_bindings.cpp
├── build
├── include
│   └── my_math_lib
│       └── math_operations.h
├── src
│   └── math_operations.cpp
└── test.py

math_operations.h

cpp 复制代码
// include/my_math_lib/math_operations.h

#ifndef MY_MATH_LIB_MATH_OPERATIONS_H
#define MY_MATH_LIB_MATH_OPERATIONS_H

namespace my_math_lib {

class MathOperations {
public:
    int add(int a, int b);
    int subtract(int a, int b);
    int multiply(int a, int b);
    double divide(int a, int b);
};

} // namespace my_math_lib

#endif // MY_MATH_LIB_MATH_OPERATIONS_H

math_operations.cpp

cpp 复制代码
// src/math_operations.cpp

#include "my_math_lib/math_operations.h"
#include <stdexcept>

namespace my_math_lib {

int MathOperations::add(int a, int b) {
    return a + b;
}

int MathOperations::subtract(int a, int b) {
    return a - b;
}

int MathOperations::multiply(int a, int b) {
    return a * b;
}

double MathOperations::divide(int a, int b) {
    if (b == 0) {
        throw std::invalid_argument("Division by zero");
    }
    return static_cast<double>(a) / b;
}

} // namespace my_math_lib

python_bindings.cpp

cpp 复制代码
// bindings/python_bindings.cpp

#include <pybind11/pybind11.h>
#include "my_math_lib/math_operations.h"

namespace py = pybind11;

PYBIND11_MODULE(my_math_lib, m) {
    py::class_<my_math_lib::MathOperations>(m, "MathOperations")
        .def(py::init<>())
        .def("add", &my_math_lib::MathOperations::add)
        .def("subtract", &my_math_lib::MathOperations::subtract)
        .def("multiply", &my_math_lib::MathOperations::multiply)
        .def("divide", &my_math_lib::MathOperations::divide);
}

CMakeLists.txt

cmake 复制代码
cmake_minimum_required(VERSION 3.12)
project(MyMathLib)

# 设置C++标准
set(CMAKE_CXX_STANDARD 14)

# 设置Python路径
set(Python3_ROOT_DIR /workspace/python3.10-aarch64/install)
set(Python3_INCLUDE_DIR /workspace/python3.10-aarch64/install/include/python3.10)
set(Python3_LIBRARY /workspace/python3.10-aarch64/install/lib/libpython3.10.so)

# 查找Python3
find_package(Python3 3.10 REQUIRED COMPONENTS Interpreter Development)

# 查找pybind11
find_package(pybind11 REQUIRED)

# 包含头文件
include_directories(${Python3_INCLUDE_DIRS} /workspace/example/libtest/include)

# 添加pybind11模块
pybind11_add_module(my_math_lib MODULE bindings/python_bindings.cpp src/math_operations.cpp)

# 链接Python库
target_link_libraries(my_math_lib PRIVATE ${Python3_LIBRARIES})

编译

bash 复制代码
cmake -DCMAKE_TOOLCHAIN_FILE=../aarch64-toolchain.cmake -DPYTHON_EXECUTABLE=$(which python3.10) ..

make

4. python 调用

test.py

python 复制代码
import my_math_lib
def main():
    math_ops = my_math_lib.MathOperations()
    print(f"Add: 3 + 4 = {math_ops.add(3, 4)}")
    print(f"Subtract: 10 - 6 = {math_ops.subtract(10, 6)}")
    print(f"Multiply: 2 * 5 = {math_ops.multiply(2, 5)}")
    try:
        print(f"Divide: 8 / 2 = {math_ops.divide(8, 2)}")
        print(f"Divide: 8 / 0 = {math_ops.divide(8, 0)}")
    except ValueError as e:
        print(f"Error: {e}")


if __name__ == "__main__":
    main()
bash 复制代码
cp my_math_lib.cpython-310-aarch64-linux-gnu.so path/to/lib/
export PYTHONPATH=$PYTHONPATH:path/to/lib
python test.py
相关推荐
Chef_Chen3 分钟前
从0开始机器学习--Day17--神经网络反向传播作业
python·神经网络·机器学习
百事老饼干7 分钟前
Java[面试题]-真实面试
java·开发语言·面试
千澜空23 分钟前
celery在django项目中实现并发任务和定时任务
python·django·celery·定时任务·异步任务
可均可可29 分钟前
C++之OpenCV入门到提高004:Mat 对象的使用
c++·opencv·mat·imread·imwrite
斯凯利.瑞恩30 分钟前
Python决策树、随机森林、朴素贝叶斯、KNN(K-最近邻居)分类分析银行拉新活动挖掘潜在贷款客户附数据代码
python·决策树·随机森林
杨荧1 小时前
【JAVA毕业设计】基于Vue和SpringBoot的服装商城系统学科竞赛管理系统
java·开发语言·vue.js·spring boot·spring cloud·java-ee·kafka
白子寰1 小时前
【C++打怪之路Lv14】- “多态“篇
开发语言·c++
yannan201903131 小时前
【算法】(Python)动态规划
python·算法·动态规划
小芒果_011 小时前
P11229 [CSP-J 2024] 小木棍
c++·算法·信息学奥赛
蒙娜丽宁1 小时前
《Python OpenCV从菜鸟到高手》——零基础进阶,开启图像处理与计算机视觉的大门!
python·opencv·计算机视觉