conan入门(二十九):对阿里mnn进行Conan封装塈conans.CMake和conan.tools.cmake.CMake的区别

去年写过一篇博客《conan入门(十九):封装第三方开源库cpp_redis示例》,当时通过自己写conanfile.py,实现了对第三方库cpp_redis的conan封装。当时使用的conan 1.45.0
时过一年多,conan版本也经过了很多次升级,最新的版本是2.x,不过为了保持兼容现在我使用的版本是1.60.0

conans.CMake VS conan.tools.cmake.CMake

当时使用的是conans.CMake来实现cmake编译,而conan.tools.cmake.CMake还在实验阶段。现在conans.CMake已经被官方放弃(在2.0中已经不存在),conan.tools.cmake.CMake转正成了官方推荐的cmake编译实现类,在1.60.0中conans.CMake还继续支持,但也不再维护。
所以如果你之前的conanfile.py中是用conans.CMake实现的,那么现在要转向使用conan.tools.cmake.CMakeconan.tools.cmake.CMakeToolchain

如下是一个基于conans.CMake的简单的conanfile.py示例

from conans import ConanFile, CMake

class ExampleConan(ConanFile):
    settings = "os", "arch", "compiler", "build_type"
    requires = "hello/0.1"
    options = {"shared": [True, False], "fPIC": [True, False]}
    default_options = {"shared": False, "fPIC": True}

    def build(self):
        cmake = CMake(self)
        cmake.definitions["MY_VAR"] = "HELLO"
        cmake.configure()
        cmake.build()

    def package(self):
        cmake = CMake(self)
        cmake.install()

如下是一个基于conan.tools.cmake.CMake的简单的conanfile.py示例,效果与上面的示例等价

from conan import ConanFile
from conan.tools.cmake import CMake, CMakeToolchain, CMakeDeps

class App(ConanFile):
    settings = "os", "arch", "compiler", "build_type"
    requires = "hello/0.1"
    options = {"shared": [True, False], "fPIC": [True, False]}
    default_options = {"shared": False, "fPIC": True}

    def generate(self):
    	# 通过 CMake交叉工具链文件定义传递给CMakeLists.txt的变量
        tc = CMakeToolchain(self)
        tc.variables["MY_VAR"] = "HELLO"
        tc.generate()
        deps = CMakeDeps(self)
        deps.generate()

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()
        
    def package(self):
        cmake = CMake(self)
        cmake.install()

conans.CMake相比conan.tools.cmake.CMake没有definitions成员,定义传递给CMakeLists.txt的变量改为使用CMakeToolchain.variables成员。
所以如果你要从conans.CMake迁移到conan.tools.cmake.CMake,基本上只要修改这部分代码就可以了。

是否要迁移?

如果你不想修改conanfile.py,仍然可以在conan 1.x下使用。但肯定不能使用conan 2.x。
既使conan 1.x下仍然支持conans.CMake,但仍然可能会存在问题。
我是发现我去年写的基于conans.CMake的conanfile.py脚本,基于conan 1.60.0本机编译仍然可以正常执行,但交叉编译就不正常了。直接的原因是像CONAN_CMAKE_TOOLCHAIN_FILE这样的CONAN_XXX环境变量不再有效。

conanfile.py for mnn 1.2.7

mnn是阿里开源的一个轻量级的深度神经网络引擎,支持深度学习的推理与训练。因为项目中需要用到它,所以我需要对它进行conan封装,以支持我们基于conan管理的项目的引用。

mnn代码比较成熟,项目结构清晰,对于conan封装的主要工作量就是将CMakeLists.txt脚本的option开关在conanfile.py的options中定义为对应的conan option,其他部分与前面conan.tools.cmake.CMake的没有什么不同,以下为python代码

conanfile.py – 基于 mnn的1.2.7版本实现,由于mnn不同的版本,CMakeLists.txt中定义的option会有所不同,所以,如果你需要实现其他mnn版本的conan封装,可以在此文件基础上对照对应版本的CMakeLists.txt的option定义对python代码进行增减

from conan import ConanFile
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain
from conan.tools.env import VirtualBuildEnv

class MnnConan(ConanFile):
    name = "mnn"
    version = "1.2.7"
    # Optional metadata
    url = "https://github.com/alibaba/MNN"
    description = "a highly efficient and lightweight deep learning framework"
    topics = ("deep learning","ai","mnn")

    tool_requires = "cmake/[>=3.15.7]"
    package_type = "library"
    # Binary configuration
    settings = "os", "compiler", "build_type", "arch"
    options = {
        "use_system_lib": [True, False],
        "build_hard": [True, False],
        "shared": [True, False],
        "win_runtime_mt": [True, False],
        "orbid_multi_thread": [True, False],
        "openmp": [True, False],
        "use_thread_pool": [True, False],
        "build_train": [True, False],
        "build_demo": [True, False],
        "build_tools": [True, False],
        "build_quantools": [True, False],
        "evaluation": [True, False],
        "build_converter": [True, False],
        "support_tflite_quan": [True, False],
        "debug_memory": [True, False],
        "debug_tensor_size": [True, False],
        "gpu_trace": [True, False],
        "portable_build": [True, False],
        "sep_build": [True, False],
        "aapl_fmwk": [True, False],
        "with_plugin": [True, False],
        "build_mini": [True, False],
        "use_sse": [True, False],
        "build_codegen": [True, False],
        "enable_coverage": [True, False],
        "build_protobuffer": [True, False],
        "build_opencv": [True, False],
        "internal_features": [True, False],
        "metal": [True, False],
        "opencl": [True, False],
        "opengl": [True, False],
        "vulkan": [True, False],
        "arm82": [True, False],
        "onednn": [True, False],
        "avx512": [True, False],
        "cuda": [True, False],
        "tensorrt": [True, False],
        "coreml": [True, False],
        "build_benchmark": [True, False],
        "build_test": [True, False],
        "build_for_android_command": [True, False],
        "use_logcat": [True, False],
        "use_cpp11": [True, False],
        }
    default_options = {
        "use_system_lib": False,
        "build_hard": False,
        "shared": False, 
        "win_runtime_mt": False, 
        "orbid_multi_thread": False, 
        "openmp": False, 
        "use_thread_pool": True, 
        "build_train": False, 
        "build_demo": False, 
        "build_tools": True,
        "build_quantools": False,
        "evaluation": False,
        "build_converter": False,
        "support_tflite_quan": True,
        "debug_memory": False,
        "debug_tensor_size": False,
        "gpu_trace": False,
        "portable_build": False,
        "sep_build": False,
        "aapl_fmwk": False,
        "with_plugin": False,
        "build_mini": False,
        "use_sse": True,
        "build_codegen": False,
        "enable_coverage": False,
        "build_protobuffer": True,
        "build_opencv": False,
        "internal_features": False,
        "metal": False,
        "opencl": False,
        "opengl": False,
        "vulkan": False,
        "arm82": False,
        "onednn": False,
        "avx512": False,
        "cuda": False,
        "tensorrt": False,
        "coreml": False,
        "build_benchmark": False,
        "build_test": False,
        "build_for_android_command": False,
        "use_logcat": True,
        "use_cpp11": True,
        }
    # Sources are located in the same place as this recipe, copy them to the recipe
    exports_sources = "CMakeLists.txt",  "*/*"

    def generate(self):
        tc = CMakeToolchain(self)
        tc.variables["MNN_USE_SYSTEM_LIB"] = self.options.use_system_lib
        tc.variables["MNN_BUILD_HARD"] = self.options.build_hard
        tc.variables["MNN_BUILD_SHARED_LIBS"] = self.options.shared
        tc.variables["MNN_WIN_RUNTIME_MT"] = self.options.win_runtime_mt
        tc.variables["MNN_FORBID_MULTI_THREAD"] = self.options.orbid_multi_thread
        tc.variables["MNN_OPENMP"] = self.options.openmp
        tc.variables["MNN_USE_THREAD_POOL"] = self.options.use_thread_pool
        tc.variables["MNN_BUILD_TRAIN"] = self.options.build_train
        tc.variables["MNN_BUILD_DEMO"] = self.options.build_demo
        tc.variables["MNN_BUILD_TOOLS"] = self.options.build_tools
        tc.variables["MNN_BUILD_QUANTOOLS"] = self.options.build_quantools
        tc.variables["MNN_EVALUATION"] = self.options.evaluation
        tc.variables["MNN_BUILD_CONVERTER"] = self.options.build_converter
        tc.variables["MNN_SUPPORT_TFLITE_QUAN"] = self.options.support_tflite_quan
        tc.variables["MNN_DEBUG_MEMORY"] = self.options.debug_memory
        tc.variables["MNN_DEBUG_TENSOR_SIZE"] = self.options.debug_tensor_size
        tc.variables["MNN_GPU_TRACE"] = self.options.gpu_trace
        tc.variables["MNN_PORTABLE_BUILD"] = self.options.portable_build
        tc.variables["MNN_SEP_BUILD"] = self.options.sep_build
        tc.variables["MNN_AAPL_FMWK"] = self.options.aapl_fmwk
        tc.variables["MNN_WITH_PLUGIN"] = self.options.with_plugin
        tc.variables["MNN_BUILD_MINI"] = self.options.build_mini
        tc.variables["MNN_USE_SSE"] = self.options.use_sse
        tc.variables["MNN_BUILD_CODEGEN"] = self.options.build_codegen
        tc.variables["MNN_ENABLE_COVERAGE"] = self.options.enable_coverage
        tc.variables["MNN_BUILD_PROTOBUFFER"] = self.options.build_protobuffer
        tc.variables["MNN_BUILD_OPENCV"] = self.options.build_opencv
        tc.variables["MNN_INTERNAL"] = self.options.internal_features
        # backend options
        tc.variables["MNN_METAL"] = self.options.metal
        tc.variables["MNN_OPENCL"] = self.options.opencl
        tc.variables["MNN_OPENGL"] = self.options.opengl
        tc.variables["MNN_VULKAN"] = self.options.vulkan
        tc.variables["MNN_ARM82"] = self.options.arm82
        tc.variables["MNN_ONEDNN"] = self.options.onednn
        tc.variables["MNN_AVX512"] = self.options.avx512
        tc.variables["MNN_CUDA"] = self.options.cuda
        tc.variables["MNN_TENSORRT"] = self.options.tensorrt
        tc.variables["MNN_COREML"] = self.options.coreml
        # target options
        tc.variables["MNN_BUILD_BENCHMARK"] = self.options.build_benchmark
        tc.variables["MNN_BUILD_TEST"] = self.options.build_test
        tc.variables["MNN_BUILD_FOR_ANDROID_COMMAND"] = self.options.build_for_android_command
        tc.variables["MNN_USE_LOGCAT"] = self.options.use_logcat

        tc.variables["MNN_USE_CPP11"] = self.options.use_cpp11

        tc.generate()

        cd = CMakeDeps(self)
        cd.generate()

        env = VirtualBuildEnv(self)
        env.generate()

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

    def package(self):
        cmake = CMake(self)
        cmake.install()

    def package_info(self):
        self.cpp_info.libs = ["mnn"]

armv8交叉编译profile

~/.conan/profiles/aarch64-linux-gnu

include(default)
{% set target_host = "aarch64-linux-gnu" %}
# 指定交叉编译器安装位置
{% set compiler_install_prefix = "/opt/gcc-arm-8.2-2018.08-x86_64-aarch64-linux-gnu" %}
# 指定交叉编译器bin位置
{% set compiler_prefix = compiler_install_prefix + "/bin/" %}
# 使用添加在PATH的编译器
[settings]
arch=armv8
build_type=Release
compiler=gcc
compiler.libcxx=libstdc++11
compiler.version=8
os=Linux
#[tool_requires]
[options]
opencv/*:with_ffmpeg=False
opencv/*:with_gtk=False
opencv/*:openexr=False
[conf]
tools.cmake.cmaketoolchain:system_processor=aarch64
tools.build:compiler_executables={"c":"{{ compiler_prefix + target_host + "-gcc" }}","cpp":"{{ compiler_prefix + target_host + "-g++" }}","asm":"{{ compiler_prefix + target_host + "-gcc" }}"}
tools.build:sysroot={{ compiler_install_prefix + "/aarch64-linux-gnu/libc" }}
#tools.build:sysroot=/
tools.system.package_manager:mode=install
tools.system.package_manager:sudo=True
[buildenv]
CHOST={{ target_host }}
AR={{ compiler_prefix + target_host + "-ar" }}
AS={{ compiler_prefix + target_host + "-gcc" }}
RANLIB={{ compiler_prefix + target_host + "-ranlib" }}
CC={{ compiler_prefix + target_host + "-gcc" }}
CXX={{ compiler_prefix + target_host + "-g++" }}
FC={{ compiler_prefix + target_host + "-gfortran" }}
LD={{ compiler_prefix + target_host + "-ld" }}
STRIP={{ compiler_prefix + target_host + "-strip" }}

代码仓库

上面的conanfile.py代码我保存在码云仓库:
https://gitee.com/l0km/mnn.git conan1.2.7分支

git clone https://gitee.com/l0km/mnn.git -b conan1.2.7

本机编译示例

cd mnn
conan create . 

交叉编译

cd mnn
conan create . -pr:h aarch64-linux-gnu.jinja -pr:b default

conan系列文章

《conan入门(一):conan 及 JFrog Artifactory 安装》
《conan入门(二):conan 服务配置-密码管理及策略》
《conan入门(三):上传预编译的库(artifact)》
《conan入门(四):conan 引用第三方库示例》
《conan入门(五):conan 交叉编译引用第三方库示例》
《conan入门(六):conanfile.txt conanfile.py的区别》
《conan入门(七):将自己的项目生成conan包》
《conan入门(八):交叉编译自己的conan包项目》
《conan入门(九):NDK交叉编译自己的conan包项目塈profile的定义》
《conan入门(十):Windows下Android NDK交叉编译Boost》
《conan入门(十一):Linux下Android NDK交叉编译Boost》
《conan入门(十二):Windows NDK 编译 boost报错:CMake was unable to find a build program … MinGW Makefile》
《conan入门(十三):conan info 命令的基本用法》
《conan入门(十四):conan new 命令的新特性–模板功能(–template)》
《conan入门(十五):AttributeError: ‘CMake‘ object has no attribute ‘definitions‘》
《conan入门(十六):profile template功能实现不同平台下profile的统一》
《conan入门(十七):支持android NDK (armv7,armv8,x86,x86_64)交叉编译的统一profile jinja2模板》
《conan入门(十八):Cannot recognize the Windows subsystem, install MSYS2/cygwin or specify a build_require》
《conan入门(十九):封装第三方开源库cpp_redis示例》
《conan入门(二十):封装只包含头文件(header_only)的库示例》
《conan入门(二十一):解决MinGW编译Openssl的编译错误:crypto/dso/dso_win32.c》
《conan入门(二十二):编译 openssl要求python 3.7以上版本》
《conan入门(二十三):Windows下MinGW编译libcurl》
《conan入门(二十四):通过CONAN_DISABLE_CHECK_COMPILER禁用编译器检查》
《conan入门(二十五):imports将包安装到本地项目或其他指定位置》
《conan入门(二十六):使用make编译makefile》
《conan入门(二十七):因profile [env]字段废弃导致的boost/1.81.0 在aarch64-linux-gnu下交叉编译失败》
《conan入门(二十八):解决conan 1.60.0下 arch64-linux-gnu交叉编译openssl/3.1.2报错问题》
《conan入门(二十九):对第三方库mnn进行Conan封装塈conans.CMake和conan.tools.cmake.CMake的区别》
《conan入门(三十):对腾讯ncnn进行Conan封装》
《conan入门(三十一):在命令行(shell)中从profile中读取配置参数》
《conan 入门(三十二):package_info中配置禁用CMakeDeps生成使用项目自己生成的config.cmake》
《conan 入门(三十三):requirements()指定header的可见性(transitive_headers)》
《conan 入门(三十四):conan 2.x实现对只有Makefile的项目(erpcgen)的封装示例》
《conan 入门(三十五):在conanfile.py中获取C++编译器完整路径的方法》
《conan入门(三十六):在set_version方法中从pom.xml中读取版本号实现动态版本定义》
《conan 入门(三十七):conan 2.x通过定义环境变量(environment)执行make编译只有Makefile的项目(erpcgen)》
《conan 入门(三十八):conan二进制包的兼容性及自定义package_id的方式》
《conan入门(三十九):conan 2.x 引用第三方库示例》

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
引用\[1\]:对于Python版本升级后终端打不开的问题,可以尝试以下解决办法。首先,使用键盘 Ctrl+Alt+F1进入命令行模式,并输入账号密码登录终端。然后,下载缺少的模块,可以使用命令 sudo apt-get install python3.6-gdbm来安装缺少的模块。接下来,进入路径 /usr/lib/python3/dist-packages/gi/,使用命令 cd /usr/lib/python3/dist-packages/gi/。使用命令 ls 查看文件,会看到两个文件 (python3.5版本) _gi_cairo.cpython-35m-x86_64-linux-g 和 _gi.cpython-35m-x86_64-linux-gnu.so。复制这两个文件并修改文件名,将文件名中的35m改为36m,可以使用命令 sudo cp _gi_cairo.cpython-35m-x86_64-linux-g _gi_cairo.cpython-36m-x86_64-linux-g和 sudo cp _gi.cpython-35m-x86_64-linux-gnu.so _gi.cpython-36m-x86_64-linux-gnu.so来完成。最后,使用键盘快捷键 Ctrl+Alt+F7回到桌面,尝试打开终端(桌面下使用Ctrl+Alt+T快速打开终端)。\[1\] 对于pip无法使用的问题,出现ModuleNotFoundError: No module named 'conans'的错误。这个错误通常是因为缺少conans模块导致的。解决这个问题的方法是使用pip来安装conans模块。可以使用命令pip install conans来安装conans模块。如果pip无法使用,可以尝试使用pip3来安装,即使用命令pip3 install conans。安装完成后,再次尝试运行相关的代码或程序,应该就不会再出现ModuleNotFoundError: No module named 'conans'的错误了。 #### 引用[.reference_title] - *1* [Python版本升级后出现的一些问题及解决方案](https://blog.csdn.net/weixin_44623010/article/details/103677401)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10km

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值