在 VS2015 中构建和打包 C++ 模块
本文简要介绍了 C++ 模块(我们希望是 C++17,但我们必须等待)。模块已经在 CLang 的早期实现中进行了实验性提供,现在 Microsoft 也在 Visual Studio 2015 中提供了它们。我们将看到它们的语法以及如何构建它们,如 Visual Studio 博客 中所述,同时,我们将展示如何使用 conan C/C++ 包管理器创建和使用包含 C++ 模块的包。
一个数学 C++ 模块库和包
首先,我们将创建一个非常简单的数学库,其中包含加法和乘法函数,这些函数将在一个名为 MyMath
的模块中实现,文件名是 mymath.ixx。此扩展名将用于指示 C++ 模块语法
module MyMath;
export double addition(double a, double b){
return a + b;
}
export double multiplication(double y, int z){
return y * z;
}
目前,构建它需要使用命令行调用 MSVC 编译器 cl.exe。这应该在 Visual Studio 命令提示符中完成,或者在加载了 Visual Studio 环境变量的情况下完成。我通常在 Windows 的 cmder 控制台中工作,因此我更喜欢加载环境变量
$ call "%vs140comntools%../../VC/vcvarsall.bat"
$ cl /c /experimental:module mymath.ixx
构建此文件时,编译器将生成典型的目标代码,以及一个名为“MyMath.ifc”的 IFC 文件,它是模块接口描述元数据。如果我们想要构建一个真正的静态库,我们也可以在命令行中进行
$ lib mymath.obj -OUT:mymath.lib
从用户的角度来看,.ifc 文件可以像处理其他库一样进行处理和链接,因此我们只需为这段代码创建一个 conan 包配方,除了 *mymath.ixx 文件之外
from conans import ConanFile, CMake, tools
import os
class VSModulesConan(ConanFile):
name = "MyMath"
version = "0.1"
license = "MIT"
settings = "os", "compiler", "build_type", "arch"
exports = "mymath.ixx"
def build(self):
param = "x86" if self.settings.arch == "x86" else "amd64"
# Missing handling of build_type, but lets keep it simple
vcvars = 'call "%%vs140comntools%%../../VC/vcvarsall.bat" %s' % param
self.run('%s && cl /c /experimental:module mymath.ixx' % vcvars)
self.run('%s && lib mymath.obj -OUT:mymath.lib' % vcvars)
def package(self):
self.copy("*.lib", "lib")
self.copy("*.ifc", "lib")
def package_info(self):
self.cpp_info.libs = ["MyMath.ifc", "mymath.lib"]
现在我们可以将包导出到 conan 本地存储中,以便我们可以从那里使用它
$ conan export memsharded/testing
使用 C++ 模块库
现在,在另一个文件夹中,我们可以创建使用库的项目
#include <iostream>
import MyMath;
int main(){
std::cout<<"MyModules\n";
std::cout<<addition(5.1, 3.2)<<"\n";
std::cout<<multiplication(2.0, 3)<<"\n";
return 0;
}
从这段代码构建可执行文件,需要执行以下命令
$ cl /EHsc /experimental:module /module:reference <libpath>/MyMath.ifc <libpath>/mymath.lib main.cpp
我们需要库路径,如果我们手动构建了库,它将是我们生成库时的路径。对于 conan 包,使用配方声明对库包的依赖关系并自动执行构建非常方便,即使我们没有为使用者项目创建包。请记住,conan 配方基本上是方便的 Python 脚本
from conans import ConanFile, CMake, tools
import os
class VSModulesTestConan(ConanFile):
license = "MIT"
settings = "os", "compiler", "build_type", "arch"
requires = "MyMath/0.1@memsharded/testing"
def build(self):
param = "x86" if self.settings.arch == "x86" else "amd64"
vcvars = 'call "%%vs140comntools%%../../VC/vcvarsall.bat" %s' % param
lib_path = self.deps_cpp_info.lib_paths[0]
libs = " ".join("%s/%s" % (lib_path, lib) for lib in self.deps_cpp_info.libs)
command = ('%s && cl /EHsc /experimental:module /module:reference %s %s/main.cpp '
% (vcvars, libs, self.conanfile_directory, ))
self.run(command)
def test(self):
self.run("main")
使用此配方,安装所需的依赖项(在我们的例子中,使用 MyMath C++ 模块构建库)非常简单
$ conan install --build
然后,构建并执行应用程序
$ conan build
$ main
MyModules
8.3
6
结论
如果您想快速测试,您可以
$ git clone https://github.com/memsharded/vs_modules
$ cd vs_modules
$ conan export memsharded/testing
$ conan test_package
我们一直将 Windows 视为一等公民(以及 Linux 和 OSX),并在 conan 中设计、实现、测试和部署时考虑到 Windows 用户(我们也大约 50% 的时间在 Windows 上进行开发)。
我们希望这篇文章能证明这一点,尽管 Visual Studio C++ 模块构建基础设施处于早期阶段(仅限命令行),但 conan 包管理器能够非常轻松直观地创建和使用包。一旦 C++ 模块在 IDE 和构建系统中获得完全支持,通过改进现有的“Visual Studio”或“CMake”生成器可以进一步简化这一点。
我们也非常高兴能够在 Visual Studio 中测试这个令人惊叹的功能,毫无疑问,Microsoft 最近在 C++ 方面做了惊人的工作,并且非常期待看到 C++ 模块成为主流。