conan.tools.files 基本操作

conan.tools.files.copy()

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

将与模式 (fnmatch) 匹配的文件从 src 文件夹复制到 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 – 要写入文件的内容(str 或 bytes)。

  • 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.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)

用于删除与 folderpattern 匹配的文件的实用函数。

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

它还接受 gzipped 文件,扩展名为 .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 破坏性更改做准备,其中用于提取 tar 存档的 data 过滤器将被设为默认值。建议尽快开始使用 data 过滤器(conf 可以在 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 和提交),以便稍后在 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