使用 Visual Studio/MSBuild 创建您的第一个 Conan 包¶
在 创建您的第一个 Conan 包教程 中,CMake 被用作构建系统。如果您尚未阅读该部分,请先阅读它以熟悉 conanfile.py
和 test_package
概念,然后再回来阅读 Visual Studio
包创建的具体内容。
使用 conan new 命令创建一个“Hello World”C++ 库示例项目
$ conan new msbuild_lib -d name=hello -d version=1.0
这将创建一个具有以下结构的 Conan 包项目。
.
├── conanfile.py
├── hello.sln
├── hello.vcxproj
├── include
│ └── hello.h
├── src
│ └── hello.cpp
└── test_package
├── conanfile.py
├── test_hello.sln
├── test_hello.vcxproj
└── src
└── test_hello.cpp
其结构和文件与之前的 CMake 示例非常相似
conanfile.py: 在根文件夹中,有一个 conanfile.py,它是主要的 Recipe 文件,负责定义包的构建和消费方式。
hello.sln: 一个可以使用 IDE 打开的 Visual Studio 解决方案文件。
hello.vcxproj: 一个 Visual Studio C/C++ 项目,是上述解决方案的一部分。
src 和 include 文件夹:包含简单的 C++ “hello” 库的文件夹。
test_package 文件夹:包含一个示例应用程序,它将依赖并链接到创建的包。在这种情况下,
test_package
也包含一个 Visual Studio 解决方案和项目,但如果需要,也可以让test_package
使用其他构建系统,例如 CMake。test_package 不强制使用与包相同的构建系统。
让我们看看包的 Recipe 文件 conanfile.py(仅相关新部分)
# Sources are located in the same place as this recipe, copy them to the recipe
exports_sources = "hello.sln", "hello.vcxproj", "src/*", "include/*"
def layout(self):
vs_layout(self)
def generate(self):
tc = MSBuildToolchain(self)
tc.generate()
def build(self):
msbuild = MSBuild(self)
msbuild.build("hello.sln")
def package(self):
copy(self, "*.h", os.path.join(self.source_folder, "include"),
dst=os.path.join(self.package_folder, "include"))
copy(self, "*.lib", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"),
keep_path=False)
让我们简要解释一下 Recipe 的不同部分
请注意,此 Recipe 中没有诸如
options
之类的shared
选项。当前项目总是构建一个静态库,因此它是非可选的。layout()
定义了一个典型的 VS 布局,这比 CMake 的布局灵活性较差,因此它不允许任何参数化。generate()
方法调用MSBuildToolchain
来生成一个conantoolchain.props
文件,项目必须将其添加到其属性中。如果项目有 Conanrequires
依赖项,它也应该添加MSBuildDeps
,并添加相关的生成文件属性表。build()
方法使用MSBuild()
辅助工具来驱动解决方案的构建由于项目在构建脚本中没有任何“安装”功能,
package()
方法可以手动定义必须复制哪些文件。
hello.vcxproj
项目文件将生成的属性表(例如 conantoolchain.props
)添加到项目中,因此构建可以接收 Conan 输入 settings
并据此执行。
<ImportGroup Label="PropertySheets">
<Import Project="conan\conantoolchain.props" />
</ImportGroup>
如果项目有依赖项,它也应该添加依赖项生成的 .props
文件。
test_package 文件夹也包含一个 test_hello.vcxproj
文件,该文件包括工具链和依赖项属性表
<ImportGroup Label="PropertySheets">
<Import Project="conan\conantoolchain.props" />
<Import Project="conan\conandeps.props" />
</ImportGroup>
请注意,test_package/conanfile.py
也包含一个 generators="MSBuildDeps"
。
让我们使用当前默认配置从源代码构建包,然后让 test_package
文件夹测试该包
$ conan create .
...
======== Testing the package: Executing test ========
hello/1.0 (test package): Running test()
hello/1.0 (test package): RUN: x64\Release\test_hello
hello/1.0: Hello World Release!
hello/1.0: _M_X64 defined
hello/1.0: MSVC runtime: MultiThreadedDLL
hello/1.0: _MSC_VER1939
hello/1.0: _MSVC_LANG201402
hello/1.0: __cplusplus199711
hello/1.0 test_package
我们现在可以验证 Recipe 和包二进制文件是否在缓存中
$ conan list hello/1.0:*
Local Cache:
hello
hello/1.0
revisions
856c535669f78da11502a119b7d8a6c9 (2024-03-04 17:52:39 UTC)
packages
c13a22a41ecd72caf9e556f68b406569547e0861
info
settings
arch: x86_64
build_type: Release
compiler: msvc
compiler.cppstd: 14
compiler.runtime: dynamic
compiler.runtime_type: Release
compiler.version: 193
os: Windows
另请参阅