创建conan包-打包方法

本文是基于对conan官方文档Packaging Approaches翻译而来, 更详细的信息可以去查阅conan官方文档。

Package recipes have three methods for controlling the package’s binary compatibility and for implementing different packaging approaches: package_id(), build_id() and package_info().
软件包配方有三种方法来控制软件包的二进制兼容性和实现不同的打包方法: package_id()build_id()package_info()`。

These methods let package creators select the method most suitable for each library.
这些方法可让软件包创建者选择最适合每个库的方法。

1 1 config (1 build) -> 1 package

A typical approach is to have one configuration for each package containing the artifacts. Using this approach, for example, the debug pre-compiled libraries will be in a different package than the release pre-compiled libraries.
一种典型的方法是为每个包含工件的软件包设置一个配置。例如,使用这种方法,debug预编译库与release预编译库将放在不同的软件包中。

So if there is a package recipe that builds a “hello” library, there will be one package containing the release version of the “hello.lib” library and a different package containing a debug version of that library (in the figure denoted as “hello_d.lib”, to make it clear, it is not necessary to use different names).
因此,如果有一个软件包配方可以构建一个 "hello "库,那么就会有一个软件包包含 "hello.lib "库的发布版本,另一个软件包包含该库的debug版本(在图中表示为 “hello_d.lib”,这只是为了更加清楚,其实是没有必要使用不同的名称)。
在这里插入图片描述
Using this approach, the package_info() method, allows you to set the appropriate values for consumers, letting them know about the package library names, necessary definitions and compile flags.
使用这种方法,package_info() 方法可以为用户设置适当的值,让他们了解包库名称、必要的定义和编译标志。

class HelloConan(ConanFile):

    settings = "os", "compiler", "build_type", "arch"

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

It is very important to note that it is declaring the build_type as a setting. This means that a different package will be generated for each different value of such setting.
需要注意的是,它将 build_type 声明为一个设置。这意味着不同的设置值将生成不同的软件包。

The values declared by the packages (the include, lib and bin subfolders are already defined by default, so they define the include and library path to the package) are translated to variables of the respective build system by the used generators. That is, running the cmake generator will translate the above definition in the conanbuildinfo.cmake to something like:
软件包声明的值(默认情况下已经定义了 includelibbin 子文件夹,因此它们定义了软件包的 includelibrary路径)会被使用的生成器转换为相应编译系统的变量。也就是说,运行 cmake 生成器后,conanbuildinfo.cmake 中的上述定义将被转换为类似内容:

set(CONAN_LIBS_MYPKG mylib)
# ...
set(CONAN_LIBS mylib ${
   CONAN_LIBS})

Those variables, will be used in the conan_basic_setup() macro to actually set the relevant cmake variables.
这些变量将用于 conan_basic_setup() 宏,以实际设置相关的 cmake 变量。

If the developer wants to switch configuration of the dependencies, they will usually switch with:
如果开发人员要切换依赖项的配置,通常会使用

$ conan install -s build_type=Release ...
# when need to debug
$ conan install -s build_type=Debug ...

These switches will be fast, since all the dependencies are already cached locally.
这些切换会很快,因为所有依赖项都已缓存在本地。

This process offers a number of advantages:
这种处理方式具有许多优点:

  • It is quite easy to implement and maintain.
  • 它非常容易实施和维护。
  • The packages are of minimal size, so disk space and transfers are faster, and builds from sources are also kept to the necessary minimum.
  • 软件包的大小极小,因此磁盘空间和传输速度更快,而且从源代码构建也保持在必要的最低限度。
  • The decoupling of configurations might help with isolating issues related to mixing different types of artifacts, and also protecting valuable information from deploy and distribution mistakes. For example, debug artifacts might contain symbols or source code, which could help or directly provide means for reverse engineering. So distributing debug artifacts by mistake could be a very risky issue.
  • 配置的解耦可能有助于隔离与混合不同类型工件相关的问题,并保护有价值的信息免受部署和分发错误的影响。例如,调试工件可能包含符号或源代码,这可能有助于或直接提供逆向工程的手段。因此,错误地分发调试工件可能是一个非常危险的问题。

Read more about this in package_info().
有关这方面的更多信息,请参阅 package_info()

2 N configs -> 1 package

2.1 Warning

This approach is discouraged. The support for defining multi-configuration packages (self.cpp_info.release, self.cpp_info.debug), will be removed in Conan 2.0, as discussed and approved by the Tribe in https://github.com/conan-io/tribe/pull/21. New generators and helpers in conan.tools.xxxx, like CMakeDeps or MSBuildDeps already ignore cpp_info multi-configuration definitions.
我们不鼓励采用这种方法。定义多重配置包(self.cpp_info.release, self.cpp_info.debug)的支持将在柯南 2.0 中被移除,这在 https://github.com/conan-io/tribe/pull/21 中得到了部落的讨论和批准。在 conan.tools.xxxx 中的新生成器和助手,如 CMakeDepsMSBuildDeps 已经忽略了 cpp_info 多重配置定义。

2.2 N configs -> 1 package

You may want to package both debug and release artifacts in the same package, so it can be consumed from IDEs like Visual Studio. This will change the debug/release configuration from the IDE, without having to specify it in the command line. This type of package can contain different artifacts for different configurations and can be used to include both the release and debug version of a library in the same package.
您可能希望将debug工件和release工件打包在同一个软件包中,以便从 Visual Studio 等集成开发环境中使用。这将从集成开发环境中更改debug/release配置,而无需在命令行中指定。这种类型的软件包可以包含不同配置的不同工件,并可用于在同一软件包中包含一个库的release版本和debug版本。
在这里插入图片描述

2.3 N - 1 示例代码

A complete working example of the following code can be found in the examples repo: https://github.com/conan-io/examples
以下代码的完整工作示例可在示例库中找到: https://github.com/conan-io/examples

$ git clone https://github.com/conan-io/examples.git
$ cd features/multi_config
$ conan create . user/channel

2.4 创建N - 1示例包

Creating a multi-configuration debug/release package is simple
创建多配置debug/release软件包非常简单

The first step will be to remove build_type from the settings. It will not be an input setting and the generated package will always contain both debug and release artifacts.
第一步是从设置中移除 build_type。它将不再是一个输入设置,生成的软件包将始终包含debug和release两部分。

The Visual Studio runtime is different for debug and release (MDd or MD) and is set using the default runtime (MD/MDd). If this meets your needs, we recommend removing the compiler.runtime subsetting in the configure() method:
Visual Studio 运行时对于debug和release(MDdMD)是不同的,并使用默认运行时(MD/MDd)进行设置。如果这符合您的需要,我们建议删除 configure() 方法中的 compiler.runtime 子设置:

class HelloConan(ConanFile):
    # build_type has been omitted. It is not an input setting.
    settings = "os", "compiler", "arch"
    generators = "cmake"

    # Remove runtime and use always default (MD/MDd)
    def configure(self):
        if self.settings.compiler == "Visual Studio":
            del self.settings.compiler.runtime

    def build(self):
        cmake_release = CMake(self, build_type="Release")
        cmake_release.configure()
        cmake_release.build()

        cmake_debug = CMake(self, build_type="Debug")
        cmake_debug.configure()
        cmake_debug.build()

In this example, the binaries will be differentiated with a suffix in the CMake syntax, so we have to add this information to the data provided to the consumers in the package_info function:
在本例中,二进制文件将通过 CMake 语法中的后缀加以区分,因此我们必须在 package_info 函数中向用户提供的数据中添加这一信息:

set_target_properties(mylibrary PROPERTIES DEBUG_POSTFIX _d)

Such a package can define its information for consumers as:
这样的软件包可以为用户提供以下信息

def package_info(self):
    self.cpp_info.release.libs = ["mylibrary"]
    self.cpp_info.debug.libs = ["mylibrary_d"]

This will translate to the CMake variables:
这会转化为 CMake 变量:

set(CONAN_LIBS_MYPKG_DEBUG mylibrary_d)
set(CONAN_LIBS_MYPKG_RELEASE mylibrary)
# ...
set(CONAN_LIBS_DEBUG mylibrary_d ${
   CONAN_LIBS_DEBUG})
set(CONAN_LIBS_RELEASE mylibrary ${
   CONAN_LIBS_RELEASE})

And these variables will be correctly applied to each configuration by conan_basic_setup() helper.
这些变量将被 conan_basic_setup() helper正确应用到每个配置中。

In this case you can still use the general and not config-specific variables. For example, the include directory when set by default to include remains the same for both debug and release. Those general variables will be applied to all configurations.
在这种情况下,你仍然可以使用通用变量,而不是特定于配置的变量。例如,默认设置为 include 时,"include "目录对于debug版本和release版本都是一样的。这些通用变量将应用于所有配置。

2.5 Important

The above code assumes that the package will always use the default Visual Studio runtime (MD/MDd). To keep the package configurable for supporting static(MT)/dynamic(MD) linking with the VS runtime library, you can do the following:
上述代码假定软件包将始终使用默认的 Visual Studio 运行库 (MD/MDd)。要保持软件包的可配置性,以支持与 VS 运行时库的静态(MT)/动态(MD)链接,可以执行以下操作:

  • Keep the compiler.runtime setting, e.g. do not implement the configure() method removing it.
  • 保留 compiler.runtime 设置,例如,在执行 configure() 方法时不要删除该设置。
  • Don’t let the CMake helper define the CONAN_LINK_RUNTIME variable to define the runtime and define CONAN_LINK_RUNTIME_MULTI instead.
  • 不要让 CMake helper定义 CONAN_LINK_RUNTIME 变量来定义运行时,而应定义 CONAN_LINK_RUNTIME_MULTI
  • In CMakeLists.txt, use the CONAN_LINK_RUNTIME_MULTI variable to correctly setup up the runtime for debug and release flags.
  • 在 CMakeLists.txt 中,使用 CONAN_LINK_RUNTIME_MULTI 变量来正确设置debug和release标志的运行时。
  • Write a separate package_id() methods for MD/MDd and for MT/MTd defining the packages to be built.
  • 为 MD/MDd 和 MT/MTd 分别编写 "package_id() "方法,定义要构建的软件包。

All these steps are already coded in the repo https://github.com/conan-io/examples/tree/master/features/multi_config and commented out as “Alternative 2”.
所有这些步骤都已在 repo https://github.com/conan-io/examples/tree/master/features/multi_config中编码,并注释为 “备选方案 2”。

The automatic conversion of multi-config variables to generators is currently implemented in the cmake, visual_studio, txt, and cmake_find_package generators (and also for their corresponding _multi implementations). If you want to have support for them in another build system, please open a GitHub issue.
多重配置变量到生成器的自动转换目前在 cmakevisual_studiotxtcmake_find_package 生成器(以及它们相应的 _multi 实现)中实现。如果您希望在其他联编系统中获得对它们的支持,请在 GitHub 上提交问题。

3 N configs (1 build) -> N packages

It’s possible that an existing build script is simultaneously building binaries for different configurations, like debug/release, or different architectures (32/64bits), or library types (shared/static). If such a build script is used in the previous “Single configuration packages” approach, it will definitely work without problems. However, we’ll be wasting precious build time, as we’ll be rebuilding the project for each package, then extracting the relevant artifacts for the relevant configuration, while ignoring the others.
现有的编译脚本有可能同时为不同的配置编译二进制文件,如debug/release,或不同的架构(32/64 位),或库类型(共享/静态)。如果在之前的 "单一配置包 "方法中使用这样的编译脚本,肯定会顺利运行。但是,我们将浪费宝贵的构建时间,因为我们将为每个软件包重建项目,然后提取相关配置的相关工件,而忽略其他配置。

It is more efficient to build the logic, whereby the same build can be reused to create different packages:
构建逻辑的效率更高,同样的构建可以重复用于创建不同的软件包:
在这里插入图片描述
This can be done by defining a build_id() method in the package recipe that will specify the logic.
这可以通过在软件包配方中定义一个 "build_id() "方法来实现,该方法将指定逻辑。

settings = "os", "compiler", "arch", "build_type"

def build_id(self):
    self.info_build.settings.build_type = "Any"

def package(self):
    if self.settings.build_type == "Debug":
        #package debug artifacts
    else:
        # package release

Note that the build_id() method uses the self.info_build object to alter the build hash. If the method doesn’t change it, the hash will match the package folder one. By setting build_type="Any", we are forcing that for both the Debug and Release values of build_type, the hash will be the same (the particular string is mostly irrelevant, as long as it is the same for both configurations). Note that the build hash sha3 will be different of both sha1 and sha2 package identifiers.
请注意,"build_id() "方法使用 "self.info_build "对象来更改构建哈希值。如果该方法没有更改,哈希值将与软件包文件夹的哈希值一致。通过设置 build_type="Any",我们将强制Debug和 Release 两种 build_type 值的哈希值相同(特定字符串并不重要,只要两种配置的哈希值相同即可)。请注意,编译哈希值 sha3 与软件包标识符 sha1sha2 不同。

This does not imply that there will be strictly one build folder. There will be a build folder for every configuration (architecture, compiler version, etc). So if we just have Debug/Release build types, and we’re producing N packages for N different configurations, we’ll have N/2 build folders, saving half of the build time.
这并不意味着只有一个构建文件夹。每种配置(架构、编译器版本等)都会有一个构建文件夹。因此,如果我们只有 Debug/Release 两种构建类型,并且要为 N 种不同的配置生成 N 个软件包,那么就会有 N/2 个构建文件夹,从而节省一半的构建时间。

Read more about this in build_id().
有关这方面的更多信息,请参阅 build_id()

相关推荐

  1. 创建conan-工具链

    2023-12-16 06:06:01       42 阅读
  2. C++ 类打包LIB方法创建 C 接口函数方法

    2023-12-16 06:06:01       41 阅读
  3. Spring Boot项目打包指定

    2023-12-16 06:06:01       43 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-16 06:06:01       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-16 06:06:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-16 06:06:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-16 06:06:01       18 阅读

热门阅读

  1. Apache Avro编程快速入门

    2023-12-16 06:06:01       30 阅读
  2. List当中的stream流使用

    2023-12-16 06:06:01       41 阅读
  3. 二进制to十六进制

    2023-12-16 06:06:01       42 阅读
  4. 密码管理器:方便与安全并存的选择

    2023-12-16 06:06:01       40 阅读
  5. 抓取网页姓和名,生成假数据

    2023-12-16 06:06:01       44 阅读
  6. Elasticsearch磁盘占用大于95%时将所有索引置为只读

    2023-12-16 06:06:01       42 阅读
  7. go-zero开发入门之gateway深入研究1

    2023-12-16 06:06:01       34 阅读
  8. lua安装

    lua安装

    2023-12-16 06:06:01      44 阅读
  9. Vue中实现分布式动态路由的基本实现步骤介绍

    2023-12-16 06:06:01       36 阅读