conan.tools.files 基本操作

conan.tools.files.copy()

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

将 src 文件夹中与模式 (fnmatch) 匹配的文件复制到 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):指定输入和输出文件文本编码。

用法

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.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)解压到给定的目标文件夹中。

它还接受扩展名为 .gz 的 gzip 文件(不匹配上述任何格式),并将其解压缩为同名但没有扩展名的文件,或者解压缩为由 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 的重大更改做准备,其中提取 tar 存档的 data 过滤器将成为默认设置。建议尽快开始使用 data 过滤器(该配置可以在 global.conf 中定义,或者可以显式地作为参数添加到配方 unzip()get() 助手)因为这是目前从互联网下载源代码时的安全建议。

unzip(conanfile, filename, destination='.', keep_permissions=False, pattern=None, strip_root=False, extract_filter=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 提取过滤器。

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)

从位于 conanfile.cpp_info.libdirs(默认)或相对于包文件夹的 folder 目录内的库(扩展名为 .so.lib.a.dylib 的文件)返回已排序的库名称列表。这对于收集非相互依赖的库或具有复杂名称的库(例如 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