package()

package() 方法负责将文件从 source_folder 和临时 build_folder 复制到 package_folder,仅复制那些将成为最终包一部分的文件和工件,例如头文件、编译器静态库和共享库、可执行文件、许可证文件等。

package() 方法将为每个创建新包二进制的不同配置调用一次,这发生在 conan install --build=pkg*conan createconan export-pkg 命令中。

package() 方法可以通过两种主要方式进行此类复制。第一种是从源 source_folderbuild_folderpackage folder 的显式 copy()

from conan import ConanFile
from conan.tools.files import copy

class Pkg(ConanFile):

    def package(self):
        # copying headers from source_folder
        copy(self, "*.h", join(self.source_folder, "include"), join(self.package_folder, "include"))
        # copying compiled .lib from build folder
        copy(self, "*.lib", self.build_folder, join(self.package_folder, "lib"), keep_path=False)

第二种方式是使用某些构建系统的 install 功能,前提是构建脚本实现了此功能。例如,如果包的 CMakeLists.txt 实现了正确的 CMake INSTALL 指令,则可以执行。

def package(self):
    cmake = CMake(self)
    cmake.install()

此外,也可以结合这两种方法,既执行 cmake.install(),也添加一些 copy() 调用,例如确保打包了 CMakeLists.txt 脚本未考虑到的“License.txt”文件。

也可以在 package() 方法中使用条件语句,因为不同的平台可能在不同位置有不同的工件。

def package(self):
    if self.settings.os == "Windows":
        copy(self, "*.lib", src=os.path.join(self.build_folder, "libs"), ...)
        copy(self, "*.dll", ....)
    else:
        copy(self, "*.lib", src=os.path.join(self.build_folder, "build", "libs"), ...)

尽管在大多数情况下这可能不是必需的,因为基于模式的复制不太可能在非 Windows 构建中找到错误的工件,例如 *.dll

使用 conan export-pkg 打包预编译二进制文件时,也会调用 package() 方法。在这种情况下,self.source_folderself.build_folder 指的是用户空间文件夹,如 layout() 方法所定义,Conan 缓存中唯一的文件夹将是 self.package_folder

注意

最佳实践

cmake.install() 功能应在 package() 方法中调用,而不是在 build() 方法中调用。无需重复使用 CMake(self) 对象,它不应在方法之间重复使用。在每个方法中创建新实例是推荐的方法。

另请参阅

有关更多信息,请参阅 package() 方法教程