CMake和Visual Studio的不同版本

CMake and different versions of Visual Studio

本文关键字:版本 Studio Visual CMake      更新时间:2023-10-16

我实际上正在编写一个库,我愿意使它成为多平台的。我已经使用了多平台依赖关系(主要是boost),并且我已经开始使用CMake。

在过去的几个月里,我一直在使用CLion,虽然它是一个非常好的IDE,但在Windows上使用它非常复杂,因为它要么需要MinGW,要么需要Cygwin。在那之前,我一直在使用Cygwin,因为Unix的模拟让我满意,但自从上次更新以来,boost在它上完全不可用

我决定,对我来说最好的办法就是重新使用Visual Studio。但是如何将它与CMake一起使用呢?我的库需要部署在多个版本的VS下(从VS2013开始,直到2015)

到目前为止,我一直在做的是在每次添加文件时重新生成项目,但正如你所猜测的,我发现这个解决方案非常低效。我还需要能够编译到不同的位置,这取决于编译器。例如:

  • 包括
  • lib
    • VS2013-x64
      • 调试
      • Release
    • VS2013-x86
      • 调试
      • Release
    • VS2015-x64
      • 调试
      • Release
    • VS2015-x86
      • 调试
      • Release
  • src

可以用CMake处理吗?如果是,怎么做?

只要在运行cmake时指定,就可以生成不同版本的VS项目文件,例如:

cmake -G "Visual Studio 14 2015 Win64" ..

cmake -G "Visual Studio 12 2013 Win64" ..

您只需要为每个版本使用正确的生成器名称。

至于每次添加文件时都要重新生成,不幸的是,这是没有办法的。如果你愿意,你可以在工作时简单地将其添加到visual studio中的项目中?顺便说一句,当您重新生成时,您不必删除所有的构建工件,所以当您将文件添加到目录中时,运行该命令应该很简单,并且项目将在visualstudio中自动更新。这需要一点时间来适应,但与通过VS中的gui添加相比并不是什么大不了的事。

编辑:调试与发布不是生成器的一部分。你仍然可以像往常一样在visualstudio中设置这些。

这不是Visual Studio特有的问题。

通常,C++不能保证用一个版本的编译器构建的库将与同一编译器的不同版本或不同编译器构建的可执行文件一起工作。这是因为C++在如何生成其对象的二进制布局方面给了编译器一定的自由。

这是一个很老的问题,没有简单的解决办法。如果您不想接受对库接口的任何限制,则需要为每个受支持的编译器版本重新构建库,并对ABI进行突破性更改(这通常意味着编译器版本中的每个编译器主版本冲突都要单独构建)。

CMake不能为您做到这一点,因为每次CMake配置运行都只会为一个特定的编译器生成一个CMake configuration。在这里,您能做的最好的事情是编写一个shell脚本,从不同的二进制目录中重复调用cmakecmake --build,以便在所有支持的编译器上一个接一个地自动构建。由于手动操作仍然很繁琐,您可能需要设置一个连续集成系统来帮助实现这一点。

另一种选择是限制库接口,使其二进制接口定义良好。通常这意味着两件事之一:

  • 使用C API作为外部库接口。您的代码仍然可以是C++,但是想要与库交互的应用程序必须通过C API。这里明显的缺点是接口上不再有类,而是结构和自由函数。这种解决方案比你想象的更常见。Stefanus Du Toit在2014年CppCon上发表了关于这种方法的演讲(视频;幻灯片)
  • 使用像微软的COM这样的对象模型技术。缺乏标准化的ABI已经困扰了人们很长一段时间,该行业已经就如何在接口上获得类和对象提出了几种解决方案。不幸的是,了解这些技术是一项不小的壮举,所以如果你决定走这条路,请准备做一些认真的研究。这种方法在Windows世界中非常常见

您可以通过CMake预定义的变量和一些脚本来实现它。

到目前为止,我一直在做的是在每次添加文件时重新生成项目,但正如你所猜测的,我发现这个解决方案非常低效。

添加文件时,您正在更改项目配置,因此别无选择,只能重新生成它。但是,您可以使用一个简单的.bat文件来自动执行它。

mkdir build
cd build
SET VS_DIR=VS2013-x64
mkdir %VS_DIR%
cd %VS_DIR%
cmake ../.. -G "Visual Studio 12 2013 Win64"
cd ..
SET VS_DIR=VS2013-x86
mkdir %VS_DIR%
cd %VS_DIR%
cmake ../.. -G "Visual Studio 12 2013"
cd ..
SET VS_DIR=VS2015-x64
mkdir %VS_DIR%
cd %VS_DIR%
cmake ../.. -G "Visual Studio 14 2015 Win64"
cd ..
SET VS_DIR=VS2015-x86
mkdir %VS_DIR%
cd %VS_DIR%
cmake ../.. -G "Visual Studio 14 2015"

我还需要能够编译到不同的位置,具体取决于在编译器上。

CMakeLists.txt可以使用CMake预定义的${PROJECT_SOURCE_DIR}.bat文件中设置的环境变量VS_DIR来自动配置每个项目中的输出目录。

cmake_minimum_required(VERSION 3.8)
project (CppProject)
add_executable(app main.cpp)
set_target_properties(app PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/lib/$ENV{VS_DIR}/Debug
    RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/lib/$ENV{VS_DIR}/Release)