C++_交叉编译和pybind11

编译

本地编译 和交叉编译

本地编译

当前平台编译

交叉编译

交叉编译是指在一个平台上编译另一个平台上运行的代码。在C++中,交叉编译通常涉及以下步骤:
    安装交叉编译工具链。   
    配置编译环境。   
    使用工具链编译代码。

首先,确保安装了交叉编译工具链,例如gcc-arm-linux-gnueabihf	 
    交叉编译链 toolchain
       方式一:下载已经做好的交叉编译链	
       方式二:使用工具定制交叉编译链	

Cmake交叉编译

 如果你使用的是 cmake 工具来进行编译,那么你需要指定如下内容:
  CMAKE_SYSTEM_NAME      目标系统:Linux   
  CMAKE_SYSTEM_PROCESSOR   目标架构:arm64  aarch64  X86_64               
  CMAKE_C_COMPILER         gcc编译器:arm-linux-gnueabihf-gcc       
  CMAKE_CXX_COMPILER       g++编译器:arm-linux-gnueabihf-g++  
  CMAKE_FIND_ROOT_PATH  :可以用于find_package,find_library和find_path。且只能是lib目录上层的目录	

## 对应交叉编译环境来说,一般通常会设置 CMAKE_FIND_ROOT_PATH_MODE_LIBRARY 为ONLY:
 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)

###说明
   在Linux平台上,一般都是采用aarch64命名,比如说Android。而在Apple平台,则一般使用arm64命名
    x86_64是基于冯诺依曼体系架构的  AArch64是一种ARMv8架构,也是一种计算机的体系架构
       aarch64-linux-gnu-gcc 是一个交叉编译工具链,可以在其他架构的系统中,编译安装 64 位 arm 架构的程序。
	      常用在嵌入式代码的移植中。aarch64-linux-gnu-gcc 是由 Linaro 公司基于 GCC 推出的的 ARM 交叉编译工具。可用于交叉编译 ARMv8 64 位目标中的裸机程序、u-boot、Linux kernel、filesystem 和 App 应用程序。aarch64-linux-gnu-gcc 交叉编译器必须安装在 64 位主机上,才能编译目标代码
       arm-linux-gnueabihf-gcc 是一款用于编译 ARM 架构的 C 语言编译器
	
    ABI:二进制应用程序接口(Application Binary Interface (ABI) for the ARM Architecture)
    EABI:嵌入式ABI。嵌入式应用二进制接口指定了文件格式、数据类型、寄存器使用、堆积组织优化和在一个嵌入式软件中的参数的标准约
    ,ABI是计算机上的,EABI是嵌入式平台上(如ARM,MIPS等)
	
   –sysroot的说明可以看出,其会对编译和链接过程中,查找头文件和链接库造成影响。

     例如:
     原本默认会从/usr/include目录中搜索头文件、从/usr/lib中搜索依赖库,
     当设置了–sysroot=dir 后则会从dir/usr/include搜索头文件、从dir/usr/lib中搜索依赖库。

混合编程

Cpython解释器
     CPython标准库中有两种类型,
	    一种是纯Python实现的,在Lib目录下;
		另一种是C和Python混合实现的,在Modules目录下	
      CPython允许使用C语言编写扩展模块

ctypes是Python的一个标准库 
    它提供了与C语言兼容的数据类型和函数来加载C语言动态链接库(DLL或so文件)。
	通过ctypes,我们可以直接在Python中调用C语言函数
	
pybind11是一个开源的 C++ 和Python之间的桥接工具
 
 
PyO3,它为 Python 提供了 Rust 绑定。
      PyO3 ,Python 可以轻松调用 Rust 代码,同时 Rust 也能执行 Python 代码 
	    Rust bindings for the Python interpreter
     https://github.com/PyO3/pyo3

pybind

Python 调用 C++ 的 库基本上有两种方法:
    一是使用 PyBind11 C++ 库生成 Python 模块,使用 Pybind11能够直接对c++代码进行导出,并且支持c++的许多数据类型如vector的自动转换
	二使用 cytpes Python 包访问已编译的共享库。
   		使用cytpes还需要额外对c++代码进行处理 


 pybind11 库中的CMakeLists.txt是针对tests目录下的例子编写的,
   运行上面的命令将编译和执行这些例子。因此这只是测试你的环境是否可以正常的编译和运行,至少应该保证能够编译通过
   
pybind11的三种方式:
       1)使用pip安装 
       pip install pybind11 -i https://pypi.tuna.tsinghua.edu.cn/simple/
	   
	   2)apt-get安装
	     sudo apt-get install python-pybind11
       3)源码编译(推荐这种,方便后续CmakeLists.txt中使用find_package(pybind11 REQUIRED))
        cmake ..
		make -j4
        make install
   
        安装后的可以使用 后续CmakeLists.txt中使用 find_package(pybind11 REQUIRED)

使用pybind

1.把c++编译成可供python调用的库 
   编译好的pybind11文件夹拷贝到了c++工程目录下 或者软链接到工程目录下 ln -s ./pybind /opt/pybind11-master

  源文件和cmakelists.txt文件
   01.需要注意CMakeLists.txt如果需要指定python版本,要放在pybind11之前,否则,有时候还是会直接连接到系统自带的python版本。	
       add_subdirectory 命令,可以将指定的文件夹加到build任务列表中
	   add_subdirectory(pybind11)
	   pybind11_add_module(Pypcc ${PROJECT_SOURCE_DIR}/src/pcc.cpp ${dso_SOURCE_FILES})
       ###等价于 c++的add_executable命令,

  02.源码中    
    #include <pybind11/pybind11.h>
  	   
  03.(进入到新建的build文件夹,执行cmake .. 再执行make)
       ,需要注意的是, linux 系统在使用 CMake 编译 c++ 动态链接库的时候,
	     会加一个前缀lib, 生成libmap_interface.so, 因此,这三个地方的命名应该修改如下:
2.python中使用
  import Pypcc #导入.so模块
  Pypcc.XXX() #调用模块的函数

参考

 https://blog.csdn.net/weixin_43376501/article/details/129786275
  aarch64-linux-gnu-gcc 14.1.0-1 https://archlinux.org/packages/extra/x86_64/aarch64-linux-gnu-gcc/
posted @ 2024-05-16 17:36  辰令  阅读(52)  评论(0编辑  收藏  举报