当我们有多个子项目时声明布局¶
请首先克隆源代码以重新创建此项目。您可以在 GitHub 的 examples2 仓库中找到它们。
$ git clone https://github.com/conan-io/examples2.git
$ cd examples2/examples/conanfile/layout/multiple_subprojects
假设我们有一个项目,其中包含两个子项目:hello 和 bye,它们需要访问位于同一层级(同级文件夹)的一些信息。每个子项目都将是一个 Conan 包。结构可能类似于这样:
.
├── bye
│ ├── CMakeLists.txt
│ ├── bye.cpp # contains an #include "../common/myheader.h"
│ └── conanfile.py # contains include(../common/myutils.cmake)
├── common
│ ├── myheader.h
│ └── myutils.cmake
└── hello
├── CMakeLists.txt # contains include(../common/myutils.cmake)
├── conanfile.py
└── hello.cpp # contains an #include "../common/myheader.h"
hello 和 bye 子项目都需要使用 common
文件夹内的一些文件(这些文件也可能被其他子项目使用和共享),并且它们通过相对位置引用这些文件。请注意,common
不打算成为一个 Conan 包。它只是一些将被复制到不同子项目包中的通用代码。
我们可以使用 self.folders.root = ".."
布局说明符来定位项目的根目录,然后使用 self.folders.subproject = "subprojectfolder"
将大部分布局重新定位到当前子项目文件夹,因为它将包含构建脚本、源代码等,这样其他辅助函数(如 cmake_layout()
)也能继续工作。我们来看看 hello 的 conanfile.py 可能会是什么样子:
import os
from conan import ConanFile
from conan.tools.cmake import cmake_layout, CMake
from conan.tools.files import copy
class hello(ConanFile):
name = "hello"
version = "1.0"
settings = "os", "compiler", "build_type", "arch"
generators = "CMakeToolchain"
def layout(self):
self.folders.root = ".."
self.folders.subproject = "hello"
cmake_layout(self)
def export_sources(self):
source_folder = os.path.join(self.recipe_folder, "..")
copy(self, "hello/conanfile.py", source_folder, self.export_sources_folder)
copy(self, "hello/CMakeLists.txt", source_folder, self.export_sources_folder)
copy(self, "hello/hello.cpp", source_folder, self.export_sources_folder)
copy(self, "common*", source_folder, self.export_sources_folder)
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
self.run(os.path.join(self.cpp.build.bindirs[0], "hello"))
让我们构建 hello 并检查它是否使用 common 文件夹的内容正确构建。
$ conan install hello
$ conan build hello
...
[100%] Built target hello
conanfile.py (hello/1.0): RUN: ./hello
hello WORLD
您也可以运行 conan create 并检查它是否也能正常工作
$ conan create hello
...
[100%] Built target hello
conanfile.py (hello/1.0): RUN: ./hello
hello WORLD
注意
请注意 export_sources()
方法的重要性,它能够在当前文件夹中的本地开发流程中保持 hello
和 common
文件夹的相同相对布局,同时当这些源文件被复制到 Conan 缓存中(以便使用 conan create
或 conan install --build=hello
在那里构建)时,也能保持相同布局。这是 layout()
的设计原则之一:事物在用户文件夹和缓存中的相对位置必须保持一致。