conan入门(三十):对腾讯ncnn进行Conan封装

ncnn是腾讯开源的一个为手机端极致优化的高性能神经网络前向计算框架。因为项目中需要用到它,所以我需要对它进行conan封装,以支持我们基于conan管理的项目的引用。
ncnn代码比较成熟,项目结构清晰,对于conan封装的主要工作量就是将CMakeLists.txt脚本的option命令定义的开关在conanfile.py的options中定义为对应的conan 选项开关.

conanfile.py for ncnn 20200916

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

from conan import ConanFile
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain
from conan.tools.env import VirtualBuildEnv
# from conan.tools.microsoft import is_msvc, is_msvc_static_runtime

class NcnnConan(ConanFile):
    name = "ncnn"
    version = "20200916"
    # Optional metadata
    url = "https://github.com/Tencent/ncnn"
    description = "a high-performance neural network inference computing framework optimized for mobile platforms"
    topics = ("deep learning","ai","ncnn")

    #requires = []
    tool_requires = "cmake/[>=3.15.7]"
    package_type = "static-library"
    # Binary configuration
    settings = "os", "compiler", "build_type", "arch"
    options = {
        "openmp": [True, False],
        "stdio": [True, False],
        "string": [True, False],
        "opencv": [True, False],
        "simplestl": [True, False],
        "threads": [True, False],
        "benchmark": [True, False],
        "pixel": [True, False],
        "pixel_rotate": [True, False],
        "vulkan": [True, False],
        "vulkan_online_spirv": [True, False],
        "system_glslang": [True, False],
        "requant": [True, False],
        "runtime_cpu": [True, False],
        "fPIC": [True, False],
        "build_tests": [True, False],
        "coverage": [True, False],
        "build_benchmark": [True, False],
        # "disable_rtti": [True, False],
        # "build_tools": [True, False],
        # "build_examples": [True, False],
        # "disable_exception": [True, False],
        # "arm82": [True, False],
        # "avx2": [True, False],
        # "build_external": [True, False],
        # "enable_spvremapper": [True, False],
        # "enable_glslang_binaries": [True, False],
        # "enable_hlsl": [True, False],
        # "enable_rtti": [True, False],
        # "enable_exceptions": [True, False],
        # "enable_opt": [True, False],
        # "enable_pch": [True, False],
        # "enable_ctest": [True, False],

        }
    default_options = {
        "openmp": True,
        "stdio": True,
        "string": True,
        "opencv": False,
        "simplestl": False,
        "threads": True,
        "benchmark": False,
        "pixel": True,
        "pixel_rotate": True,
        "vulkan": False,
        "vulkan_online_spirv": True,
        "system_glslang": False,
        "requant": False,
        "runtime_cpu": True,
        "fPIC": True,
        "build_tests": False,
        "coverage": False,
        "build_benchmark": True,
        # "disable_rtti": False,
        # "build_tools": False,
        # "build_examples": False,
        # "disable_exception": False,
        # "arm82": False,
        # "avx2": True,
        # "build_external": False,
        # "enable_spvremapper": False,
        # "enable_glslang_binaries": False,
        # "enable_hlsl": False,
        # "enable_rtti": False,
        # "enable_exceptions": False,
        # "enable_opt": False,
        # "enable_pch": False,
        # "enable_ctest": False,

        }
    # 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["NCNN_OPENMP"] = self.options.openmp
        tc.variables["NCNN_STDIO"] = self.options.stdio
        tc.variables["NCNN_STRING"] = self.options.string
        tc.variables["NCNN_INSTALL_SDK"] = True
        tc.variables["NCNN_OPENCV"] = self.options.opencv
        tc.variables["NCNN_SIMPLESTL"] = self.options.simplestl
        tc.variables["NCNN_THREADS"] = self.options.threads
        tc.variables["NCNN_BENCHMARK"] = self.options.benchmark
        tc.variables["NCNN_PIXEL"] = self.options.pixel
        tc.variables["NCNN_PIXEL_ROTATE"] = self.options.pixel_rotate
        tc.variables["NCNN_CMAKE_VERBOSE"] = False
        tc.variables["NCNN_VULKAN"] = self.options.vulkan
        tc.variables["NCNN_VULKAN_ONLINE_SPIRV"] = self.options.vulkan_online_spirv
        tc.variables["NCNN_SYSTEM_GLSLANG"] = self.options.system_glslang
        tc.variables["NCNN_REQUANT"] = self.options.requant
        tc.variables["NCNN_RUNTIME_CPU"] = self.options.runtime_cpu
        tc.variables["NCNN_DISABLE_PIC"] = not self.options.fPIC
        tc.variables["NCNN_BUILD_TESTS"] = self.options.build_tests
        tc.variables["NCNN_COVERAGE"] = self.options.coverage
        tc.variables["NCNN_BUILD_BENCHMARK"] = self.options.build_benchmark
        
        #tc.variables["NCNN_DISABLE_RTTI"] = self.options.disable_rtti
        tc.variables["NCNN_BUILD_TOOLS"] = False
        tc.variables["NCNN_BUILD_EXAMPLES"] = False
        # tc.variables["NCNN_DISABLE_EXCEPTION"] = self.options.disable_exception
        # tc.variables["NCNN_ARM82"] = self.options.arm82
        # tc.variables["NCNN_AVX2"] = self.options.avx2
        
        # tc.variables["BUILD_EXTERNAL"] = self.options.build_external
        # tc.variables["ENABLE_SPVREMAPPER"] = self.options.enable_spvremapper
        # tc.variables["ENABLE_GLSLANG_BINARIES"] = self.options.enable_glslang_binaries
        # tc.variables["ENABLE_HLSL"] = self.options.enable_hlsl
        # tc.variables["ENABLE_RTTI"] = self.options.enable_rtti
        # tc.variables["ENABLE_EXCEPTIONS"] = self.options.enable_exceptions
        # tc.variables["ENABLE_OPT"] = self.options.enable_opt
        # tc.variables["ENABLE_PCH"] = self.options.enable_pch
        # tc.variables["ENABLE_CTEST"] = self.options.enable_ctest
        # tc.variables["CMAKE_MODULE_PATH"] = self.build_folder
        # if is_msvc(self):
        #     tc.variables["NCNN_BUILD_WITH_STATIC_CRT"] = is_msvc_static_runtime(self)
        # This policy doesn't matter for us, but avoids a warning
        tc.cache_variables["CMAKE_POLICY_DEFAULT_CMP0074"] = "NEW"
        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 = ["ncnn"]


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/ncnn.git conan20200916分支

git clone https://gitee.com/l0km/ncnn.git -b conan20200916

本机编译示例

cd ncnn
conan create . 

交叉编译

cd ncnn
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入门(二十七):因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,deeplearning,conan,ncnn,腾讯,cmake)