从所有依赖项复制源代码

请首先克隆源代码以重新创建此项目。您可以在 GitHub 的 examples2 仓库中找到它们。

$ git clone https://github.com/conan-io/examples2.git
$ cd examples2/examples/extensions/deployers/sources

在本示例中,我们将了解如何创建和使用自定义部署器。此部署器会将所有依赖项的源代码文件复制到指定的输出文件夹中。

注意

为了更好地理解本示例,强烈建议您预先阅读 部署器 参考文档。

定位部署器

在这种情况下,部署器与我们的示例 conanfile 位于同一目录中。但是,正如 部署器 参考文档中所述,Conan 会按顺序在几个额外位置查找指定的部署器,即:

  1. 绝对路径

  2. 相对于当前工作目录

  3. [CONAN_HOME]/extensions/deployers 文件夹中

  4. 内置部署器

运行它

在我们的示例中,我们有一个简单的配方,它将 zlibmcap 都列为要求。借助 tools.build:download_source=True 配置,我们可以强制调用其 source() 方法,这将确保即使不需要进行任何构建,源代码也可用。

现在,您应该能够在 conan installconan graph 命令以及任何给定配方中使用新的部署器。

$ conan graph info . -c tools.build:download_source=True --deployer=sources_deploy

检查命令输出,我们可以看到它已将我们的直接依赖项 zlibmcap 的源代码,以及我们的传递依赖项 zstdlz4 的源代码复制到了 dependencies_sources 文件夹。完成后,可以进行额外的预处理以满足更具体的需求。

请注意,您可以传递 --deployer-folder 参数来更改部署器的基础输出文件夹路径。

代码导览

source_deploy.py 文件具有以下代码

sources_deploy.py
from conan.errors import ConanException
from conan.tools.files import copy
import os


def deploy(graph, output_folder, **kwargs):
    # Note the kwargs argument is mandatory to be robust against future changes.
    for name, dep in graph.root.conanfile.dependencies.items():
        if dep.folders is None or dep.folders.source_folder is None:
            raise ConanException(f"Sources missing for {name} dependency.\n"
                                  "This deployer needs the sources of every dependency present to work, either building from source, "
                                  "or by using the 'tools.build:download_source' conf.")
        copy(graph.root.conanfile, "*", dep.folders.source_folder, os.path.join(output_folder, "dependency_sources", str(dep)))

deploy()

Conan 会调用 deploy() 方法,并将其作为参数接收依赖关系图和输出文件夹路径。它会遍历我们配方的所有依赖项,并使用 conan.tools.copy 将每个源代码文件复制到 dependencies_sources 下的相应文件夹中。

注意

如果您将此部署器作为自己部署器的示例,请记住 tools.build:download_source=True 是必需的,以便为依赖项定义 dep.folders.source_folder。没有此配置,对于那些不需要从源代码构建的依赖项,或者在不需要构建的命令(如 conan graph)中,该变量将未定义。

注意

如果您的自定义部署器需要访问完整的依赖关系图,包括可能被跳过的库,请使用 tools.graph:skip_binaries=False 配置。这对于例如收集图中的所有许可证非常有用。