conan.tools.files 基本操作

conan.tools.files.copy()

copy(conanfile, pattern, src, dst, keep_path=True, excludes=None, ignore_case=True, overwrite_equal=False)

将 src 文件夹中与 pattern 匹配的文件复制到 dst 文件夹。

参数:
  • conanfile – 当前的配方对象。始终使用 self

  • pattern – (必需) 要复制的文件的 fnmatch 文件模式。它不能以 .. 相对路径开头,否则将引发异常。

  • src – (必需) 将在其中搜索这些文件的源文件夹。此文件夹将从 dst 参数中剥离。例如:lib/Debug/x86。

  • dst – (必需) 目标本地文件夹。它必须与 src 值不同,否则将引发异常。

  • keep_path – (可选,默认为 True) 表示您是否希望在将文件从 src 文件夹复制到 dst 文件夹时保留相对路径。

  • excludes – (可选,默认为 None) 一个 fnmatch 模式的元组/列表,甚至是一个要从复制中排除的单个模式。

  • ignore_case – (可选,默认为 True) 如果启用,它将执行不区分大小写的模式匹配。当 True 时,将执行不区分大小写的模式匹配。

  • overwrite_equal – (可选,默认为 False)。如果目标文件夹中已存在要复制的文件,则仅当文件似乎不同(大小不同、修改时间不同)时才实际复制。

返回:

复制的文件列表

用法

def package(self):
    copy(self, "*.h", self.source_folder, os.path.join(self.package_folder, "include"))
    copy(self, "*.lib", self.build_folder, os.path.join(self.package_folder, "lib"))

注意

指向文件的符号链接指向文件夹的符号链接将被视为其他文件,因此只有在指定模式与文件匹配时才会复制它们。

在目标文件夹中,符号链接将指向完全相同的文件或文件夹,无论是绝对路径还是相对路径。用户有责任操作符号链接,例如在复制它之前将其转换为相对路径,以便它指向目标文件夹。

请参阅 此处 的管理符号链接工具的参考。

conan.tools.files.load()

load(conanfile, path, encoding='utf-8')

用于单行加载文件的实用函数。它将管理文件的打开和关闭,以及二进制编码的加载。返回文件内容。

参数:
  • conanfile – 当前的配方对象。始终使用 self

  • path – 要读取的文件的路径

  • encoding – (可选,默认为 utf-8):指定输入文件的文本编码。

返回:

文件的内容

用法

from conan.tools.files import load

content = load(self, "myfile.txt")

conan.tools.files.save()

save(conanfile, path, content, append=False, encoding='utf-8')

用于单行保存文件的实用函数。它将管理文件的打开和关闭,以及创建目录(如果需要)。

参数:
  • conanfile – 当前的配方对象。始终使用 self

  • path – 要创建的文件的路径。

  • content – 要写入文件的内容(字符串或字节)。

  • append – (可选,默认为 False):如果为 True,则会将内容追加到现有内容中。

  • encoding – (可选,默认为 utf-8):指定输出文件的文本编码。

用法

from conan.tools.files import save

save(self, "path/to/otherfile.txt", "contents of the file")

conan.tools.files.rename()

rename(conanfile, src, dst)

用于重命名文件或文件夹 src 到 dst 的实用函数,并带有重试机制。os.rename() 在 Windows 上经常会引发“拒绝访问”异常。此函数使用 robocopy 重命名文件或文件夹,以避免在 Windows 上出现此异常。

参数:
  • conanfile – 当前的配方对象。始终使用 self

  • src – 要重命名的路径。

  • dst – 要重命名到的路径。

用法

from conan.tools.files import rename

def source(self):
    rename(self, "lib-sources-abe2h9fe", "sources")  # renaming a folder

conan.tools.files.replace_in_file()

replace_in_file(conanfile, file_path, search, replace, strict=True, encoding='utf-8')

file_path 文件的内容中将字符串 search 替换为字符串 replace。

参数:
  • conanfile – 当前的配方对象。始终使用 self

  • file_path – 要执行替换操作的文件的路径。

  • search – 您想要被替换的字符串。

  • replace – 用于替换搜索字符串的字符串。

  • strict – (可选,默认为 True) 如果为 True,如果未找到搜索字符串,则会引发错误,因此实际上不会进行任何替换。

  • encoding – (可选,默认为 utf-8):指定输入和输出文件的文本编码。

返回:

如果找到模式,则返回 True,如果 strictFalse 且未找到模式,则返回 False

用法

from conan.tools.files import replace_in_file

replace_in_file(self, os.path.join(self.source_folder, "folder", "file.txt"), "foo", "bar")

conan.tools.files.chmod()

chmod(conanfile, path: str, read: bool | None = None, write: bool | None = None, execute: bool | None = None, recursive: bool = False)

跨平台更改文件或目录权限。

版本 2.15 新增。

此函数是 Unix chmod 命令的简单包装器,但支持跨平台。建议使用它而不是 os.stat + os.chmod,因为它仅更改所有者对目录或文件的权限,并避免 umask 问题。在 Windows 上,它仅限于更改写入权限。

参数

conanfile对象

当前配方对象。始终使用 self

path字符串

要更改权限的文件或目录的路径。

read布尔值,可选

如果为 True,则文件或目录将获得所有者用户的读取权限。如果为 False,则将删除读取权限。如果为 None,则读取权限将保持不变。默认为 None。

write布尔值,可选

如果为 True,则文件或目录将获得所有者用户的写入权限。如果为 False,则将删除写入权限。如果为 None,则文件或目录不会更改。默认为 None。

execute布尔值,可选

如果为 True,则文件或目录将获得所有者用户的执行权限。如果为 False,则将删除执行权限。如果为 None,则文件或目录不会更改。默认为 None。

recursive布尔值

如果为 True,则权限将递归应用于指定目录内的所有文件和目录。如果为 False,则仅更改指定的文件或目录。默认为 False。

返回值

示例

为打包的 bash 脚本添加执行权限
from conan.tools.files import chmod
chmod(self, os.path.join(self.package_folder, "bin", "script.sh"), execute=True)

conan.tools.files.rm()

此函数从文件系统中删除文件。它可用于删除单个文件或基于 fnmatch 的模式。建议使用它而不是 os.remove,因为它支持跨平台,并可能避免权限问题。

递归删除 build_folder 中所有以 .tmp 结尾的文件
from conan.tools.files import rm

rm(self, "*.tmp", self.build_folder, recursive=True)
删除 bin_folder 中的所有文件,除了以 .dll 结尾的任何文件
from conan.tools.files import rm

rm(self, "*", self.bin_folder, recursive=False, excludes="*.dll")
rm(conanfile, pattern, folder, recursive=False, excludes=None)

用于删除 folder 中与 pattern 匹配的文件的实用函数。

参数:
  • conanfile – 当前的配方对象。始终使用 self

  • pattern – 要删除的文件必须匹配的模式 (fnmatch)。

  • folder – 搜索/删除文件的文件夹。

  • recursive – 如果指定了 recursive,则将在子文件夹中进行搜索。

  • excludes – (可选,默认为 None) 一个 fnmatch 模式的元组/列表,甚至是一个要从删除模式中排除的单个模式。

conan.tools.files.mkdir()

mkdir(conanfile, path)

用于创建目录的实用函数。会检查指定目录是否存在,因此如果目录已存在,mkdir() 将不起作用。

参数:
  • conanfile – 当前的配方对象。始终使用 self

  • path – 要创建的文件夹的路径。

用法

from conan.tools.files import mkdir

mkdir(self, "mydir") # Creates mydir if it does not already exist
mkdir(self, "mydir") # Does nothing

conan.tools.files.rmdir()

rmdir(conanfile, path)

用法

from conan.tools.files import rmdir

rmdir(self, "mydir") # Remove mydir if it exist
rmdir(self, "mydir") # Does nothing

conan.tools.files.chdir()

chdir(conanfile, newdir)

这是一个上下文管理器,允许在您的 conanfile 中临时更改当前目录。

参数:
  • conanfile – 当前的配方对象。始终使用 self

  • newdir – 要更改当前目录的目录路径名。

用法

from conan.tools.files import chdir

def build(self):
    with chdir(self, "./subdir"):
        do_something()

conan.tools.files.unzip()

此函数将各种压缩格式(.tar.tar.gz.tgz.tar.bz2.tbz2.tar.xz.txz.zip)解压到指定的目录。

它还接受 gzip 压缩的文件,扩展名为 .gz(不匹配上述任何一种),它会将它们解压到一个同名但没有扩展名的文件中,或者解压到由 destination 参数定义的文件名。

from conan.tools.files import unzip

unzip(self, "myfile.zip")
# or to extract in "myfolder" sub-folder
unzip(self, "myfile.zip", "myfolder")

您可以使用 keep_permissions=True 参数来保留文件的权限。

from conan.tools.files import unzip

unzip(self, "myfile.zip", "myfolder", keep_permissions=True)

如果想解压归档文件中的特定文件和路径,可以使用 pattern 参数。

from conan.tools.files import unzip

# Extract only files inside relative folder "small"
unzip(self, "bigfile.zip", pattern="small/*")
# Extract only txt files
unzip(self, "bigfile.zip", pattern="*.txt")

重要

在 Conan 2.8 中,unzip() 提供了一个新的 extract_filter=None 参数,并添加了一个新的 tools.files.unzip:filter 配置,以准备应对未来 Python 3.14 的重大更改,届时 data 过滤器将成为解压 tar 存档的默认过滤器。建议尽快开始使用 data 过滤器(配置可以在 global.conf 中定义,也可以在配方 unzip()get() 帮助函数中显式添加),因为这是当前在从互联网下载源代码时的安全建议。

unzip(conanfile, filename, destination='.', keep_permissions=False, pattern=None, strip_root=False, extract_filter=None, excludes=None)

解压各种压缩格式

参数:
  • conanfile – 当前的配方对象。始终使用 self

  • filename – 压缩文件的路径。

  • destination – (可选,默认为 .) 目标文件夹(或 .gz 文件的文件名)。

  • keep_permissions – (可选,默认为 False) 保留 zip 文件的权限。警告:这可能很危险,如果 zip 文件不是在 NIX 系统中创建的,权限位可能会导致未定义的权限方案。只有在您确定 zip 文件已正确创建时才使用此选项。

  • pattern – (可选,默认为 None) 仅解压匹配模式的路径。这应该是 Unix shell 风格的通配符,有关更多详细信息,请参阅 fnmatch 文档。

  • strip_root – (可选,默认为 False) 如果为 True,并且所有解压的内容都在一个文件夹中,它将扁平化该文件夹,将所有内容移动到父文件夹。

  • extract_filter – (可选,默认为 None)。解压 tar 文件时,使用 Python 在 https://docs.pythonlang.cn/3/library/tarfile.html 中定义的 tar 解压过滤器。

  • excludes – (可选,默认为 None)。解压文件时,排除匹配任何模式的路径。这应该是 Unix shell 风格的通配符,有关更多详细信息,请参阅 fnmatch 文档。

conan.tools.files.update_conandata()

此函数读取 conan 缓存中导出文件夹内的 conandata.yml 文件(如果存在)。如果 conandata.yml 不存在,它将创建它。然后,它使用提供的 data 字典更新 conandata,该字典会递归更新,优先使用 data 的值,但保留其他现有值。最后,conandata.yml 会保存在同一个位置。

此助手只能在 export() 方法中使用,否则可能会引发错误。一个应用场景是将在 conandata.yml 中捕获 scm 坐标(如 Git 远程 URL 和 commit),以便稍后在 source() 方法中恢复它,从而拥有可重现的配方,无需在配方中实际存储源代码即可从源代码构建。

update_conandata(conanfile, data)

导出 conandata.yml 后修改它的工具。例如,可用于

  • 添加 scm 的额外数据,如“commit”和“url”。

  • 修改内容,清除属于其他版本(与导出的版本不同)的数据,以避免在更改的数据不属于当前版本时更改配方版本。

参数:
  • conanfile – 当前的配方对象。始终使用 self

  • data – (必需) 要更新的值的字典(可以是嵌套的)。

conan.tools.files.trim_conandata()

trim_conandata(conanfile, raise_if_missing=True)

导出 conandata.yml 后修改它的工具,只限制为当前版本。

警告

conan.tools.files.trim_conandata() 函数处于**预览**状态。有关更多信息,请参阅 Conan 稳定性 部分。

此函数修改 conan 缓存中导出文件夹内的 conandata.yml 文件(如果存在),并仅保留与当前构建版本相关的信息。

此助手只能在 export() 方法或 post_export() hook 中使用,否则将来可能会引发错误。一个应用是确保 conandata.yml 文件中与某些版本相关的更改不会影响其他版本的已生成配方版本。

用法

from conan import ConanFile
from conan.tools.files import trim_conandata

class Pkg(ConanFile):
    name = "pkg"

    def export(self):
        # any change to other versions in the conandata.yml
        # won't affect the revision of the version that is built
        trim_conandata(self)

conan.tools.files.collect_libs()

collect_libs(conanfile, folder=None)

返回一个排序的库名列表,这些库(扩展名为 * .so*、* .lib*、* .a* 和 * .dylib* 的文件)位于 conanfile.cpp_info.libdirs(默认)或相对于包文件夹的 **folder** 目录内。这对于收集不相互依赖的库或名称复杂的库(如 libmylib-x86-debug-en.lib)非常有用。

对于以 **lib** 开头的 UNIX 库,例如 *libmath.a*,此工具将收集库名 **math**。

参数:
  • conanfile – 当前的配方对象。始终使用 self

  • folder – (可选,默认为 None):字符串,指示 conanfile.package_folder 内库文件的子文件夹名称。

返回:

包含库名的列表

警告

此工具直接在包文件夹内搜索库,并按任意顺序返回它们。如果库相互依赖,则 package_info() 方法应对其进行排序以实现正确的链接顺序。

用法

from conan.tools.files import collect_libs

def package_info(self):
    self.cpp_info.libdirs = ["lib", "other_libdir"]  # Default value is 'lib'
    self.cpp_info.libs = collect_libs(self)

对于以 **lib** 开头的 UNIX 库,例如 *libmath.a*,此工具将收集库名 **math**。关于符号链接,此工具将仅保留解析后的真实文件以及指向此真实文件的所有符号链接中“最通用”的文件。例如,在下面的文件中,此工具将选择 *libmath.dylib* 文件,因此只在返回的列表中追加 *math*。

-rwxr-xr-x libmath.1.0.0.dylib lrwxr-xr-x libmath.1.dylib -> libmath.1.0.0.dylib
lrwxr-xr-x libmath.dylib -> libmath.1.dylib