• conan包管理工具(1)


    conan包管理工具

    Conan 是一个开源的、跨平台的、去中心化的 C++ 包管理器。通过它可以安装、解决构建依赖,更重要的是可以直接集成到 Build System 中使用。同时它也允许你搭建自己的私有仓库,供私有项目使用。具体到细节,当向 Conan 请求安装依赖时,Conan 会拿着编译相关的配置信息去服务器请求是否有对应平台的预构建二进制包,如果有,则直接下载并解压到本地的缓存仓库中,否则,会执行对应的构建脚本,构建出符合当前平台的二进制包。
    请添加图片描述

    安装

    Conan 基于 Python 编写,故需要在开始前安装好 Python3。然后使用标准的 pip 安装即可

    pip install conan
    
    
    • 1
    • 2

    配置

    在Linux下Conan 会在第一次启动时自动配置好默认的 Profile 和 Remote 设置。它的配置以及本地的二进制仓库均存储在用户目录下~/.conan/中。
    Profile 则存储在profiles文件夹中,用于设定各种编译环境和选项。默认会创建一个名为 default 的 Profile

    软件包

    Conan 使用这样的格式来描述一个软件包:名称/版本@用户/渠道。其中渠道(Channel)用来描述是稳定版(Stable)还是测试版(Testing)等信息

    boost/1.64.0@conan/stable
    boost/1.65.1@conan/stable
    boost/1.66.0@conan/stable
    
    • 1
    • 2
    • 3

    软件包仓库

    在conan安装路径下,存在一个本地缓存,在编译的时候首先会先在缓存中进行查找,当缓存中不存在的时候,再去源端下载并编译二进制代码。
    用户目录的软件包仓库被称为本地缓存(Local Cache);那么同样的,服务器上也有一个软件包的仓库,文档中称为远端(Remote)
    其中,目录结构为:

    drwxr-xr-x  1 root root   4096 Aug 27 16:18 ./
    drwx------  1 root root   4096 Aug 27 16:18 ../
    -rw-r--r--  1 root root  12288 Aug 10 18:44 .conan.db
    -rw-r--r--  1 root root      0 Aug 10 18:44 artifacts.properties
    -rw-r--r--  1 root root 351649 Aug 10 18:44 cacert.pem
    -rw-r--r--  1 root root   1002 Aug 10 18:44 conan.conf
    -rw-r--r--  1 root root    185 Aug 10 18:44 config_install.json
    drwxrwxr-x 13 1007 1007   4096 Aug 27 15:31 data/
    drwxr-xr-x  2 root root   4096 Aug 27 15:28 hooks/
    drwxr-xr-x  2 root root   4096 Aug 10 18:44 profiles/
    -rw-r--r--  1 root root    303 Aug 10 18:44 remotes.json
    -rw-r--r--  1 root root   5979 Aug 10 18:44 settings.yml
    -rw-r--r--  1 root root      6 Aug 10 18:44 version.txt
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    基本操作

    通过Conan help来查找

    安装依赖与构建

    conan使用类似cmake的方式,通过conanfile.txt来描述工程相关的依赖和相关的文件,或者可以直接通过conanfile.py来控制,在通过conanfile.txt过程中,编写的方式为:

    [requires]//依赖
    Poco/1.7.8p3@pocoproject/stable
    
    [generators]//构建工具
    cmake
    
    • 1
    • 2
    • 3
    • 4
    • 5

    如果有包 A 依赖包 C 的 1.0 版本,包 B 依赖包 C 的 1.2 版本,此时就会出现冲突。通过手动在 Requires 中写入C/1.2@xxx/yyy这样的依赖可以强制提升 C 的版本号为最新

    工程对应的cmakefile.txt

    project(FoundationTimer)
    cmake_minimum_required(VERSION 2.8.12)
    add_definitions("-std=c++11")
    
    include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
    conan_basic_setup()
    
    add_executable(timer timer.cpp)
    target_link_libraries(timer ${CONAN_LIBS})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    自建软件包

    请添加图片描述

    conanfile.py,其中conanfile.py用来描述构建软件包的编译打包过程,默认的,Conan 以lib、include、bin等文件夹标识头文件库文件目录,也可以在package_info函数中进行修改。此外,Conan 提供了一系列的驱动包装函数来执行各种第三方工具,以及定制版本号规则、设定依赖等等。

    from conans import ConanFile, CMake
    from distutils.dir_util import copy_tree
    
    class BgfxConan(ConanFile):
        name            = "bgfx"
        version         = "20190604.018bbc4"  # 这个地方我乱填的,请遵照SemVer的规范制定版本号
        description     = "Conan package for bgfx."
        url             = "https://github.com/9chu/bgfx-conan"
        license         = "BSD"
        settings        = "arch", "build_type", "compiler", "os"  # 这些选项会被作为包的标识,区分不同的ABI
        generators      = "cmake"
        options         = {"shared": [True, False]}
        default_options = "shared=False"
    
        def source(self):
            self.run("git clone https://github.com/JoshuaBrookover/bgfx.cmake")
            copy_tree("bgfx.cmake", ".")
            self.run("git reset --hard 018bbc4")
            self.run("git submodule update --init --recursive")
    
        def build(self):
            cmake          = CMake(self)
            shared_options = "-DBUILD_SHARED_LIBS=ON" if self.options.shared else "-DBUILD_SHARED_LIBS=OFF"
            fixed_options  = "-DBGFX_BUILD_EXAMPLES=OFF"
            tool_options   = "-DBGFX_BUILD_TOOLS=OFF" if self.settings.os == "Emscripten" else ""
            opengl_version = "-DBGFX_OPENGL_VERSION=33"
            self.run("cmake %s %s %s %s %s" % (cmake.command_line, shared_options, fixed_options, tool_options, opengl_version))
            self.run("cmake --build . %s -j8" % cmake.build_config)
    
        def collect_headers(self, include_folder):
            self.copy("*.h"  , dst="include", src=include_folder)
            self.copy("*.hpp", dst="include", src=include_folder)
            self.copy("*.inl", dst="include", src=include_folder)
    
        def package(self):
            self.collect_headers("bgfx/include")
            self.collect_headers("bimg/include")
            self.collect_headers("bx/include"  )
            self.copy("*.a"  , dst="lib", keep_path=False)
            self.copy("*.so" , dst="lib", keep_path=False)
            self.copy("*.lib", dst="lib", keep_path=False)
            self.copy("*.dll", dst="bin", keep_path=False)
    
        def package_info(self):
            self.cpp_info.libs = ["bgfxd", "bimgd", "bxd"] if self.settings.build_type == "Debug" else ["bgfx", "bimg", "bx"]
            self.cpp_info.libs.extend(["astc-codec", "astc", "edtaa3", "etc1", "etc2", "iqa", "squish", "nvtt", "pvrtc"])
            if self.settings.os == "Macos":
                self.cpp_info.exelinkflags = ["-framework Cocoa", "-framework QuartzCore", "-framework OpenGL", "-weak_framework Metal"]
            if self.settings.os == "Linux":
                self.cpp_info.libs.extend(["GL", "X11", "pthread", "dl"])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    整个脚本分为若干个函数。其中,source函数,用于源代码拉取和准备,比如对源码进行一些修改;build函数,调用 CMake 进行构建;package函数,用于执行打包操作;package_info则用于输出构建相关的信息,比如需要链接包中的哪些库文件

    配合 CMake

    cmake_minimum_required(VERSION 3.1)
    project(test CXX)
    
    ######################################## conan package manager ########################################
    
    # Download automatically, you can also just copy the conan.cmake file
    if(NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake")
        message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan")
        file(DOWNLOAD "https://github.com/conan-io/cmake-conan/raw/v0.14/conan.cmake"
            "${CMAKE_BINARY_DIR}/conan.cmake")
    endif()
    
    include(${CMAKE_BINARY_DIR}/conan.cmake)
    
    ######################################## dependencies ########################################
    
    conan_cmake_run(
        REQUIRES
            bgfx/20190604.018bbc4@9chu/stable
        BASIC_SETUP CMAKE_TARGETS
        BUILD missing)
    
    ######################################## compiler flags ########################################
    
    set(CMAKE_CXX_STANDARD 11)
    
    if(MSVC)
        add_definitions(-D_WIN32_WINNT=0x0600 -D_GNU_SOURCE -D_CRT_SECURE_NO_WARNINGS)
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8")
        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /utf-8")
    else()
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -Wno-implicit-fallthrough")
        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -Wextra -Wno-implicit-fallthrough")
    endif()
    
    ######################################## targets ########################################
    
    file(GLOB_RECURSE TEST_SRC ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
    
    add_executable(test ${TEST_SRC})
    target_include_directories(test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
    target_link_libraries(test CONAN_PKG::bgfx)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
  • 相关阅读:
    LeetCode0076.最小覆盖子串 Go语言AC笔记
    有被惊艳到!阿里达摩院面向开发者公布的Java全体系成长路线,从P5-P8职级全系
    java开发之个微机器人的二次开发
    vscode中使用指定路径下的cmake
    LeetCode 48题: 旋转图像
    阿里云容蓓:DCDN 助力云原生时代的应用构建及最佳实践
    【工程实践】Docker使用记录
    shell编程基础
    前缀和题型总结 II :leetcode 1402、1310、1371、1171
    微信 商家转账到零钱 二
  • 原文地址:https://blog.csdn.net/neuzhangno/article/details/126559339