多项目配置 C++

Posted

技术标签:

【中文标题】多项目配置 C++【英文标题】:Multiple Project Configurations C++ 【发布时间】:2018-10-04 18:19:56 【问题描述】:

我使用 Visual Studio 2017(但适用于 2010+ 的任何版本)并且我一直在尝试想出一种方法来组织我的调试/发布库,以避免我们得到的所有这些链接错误, 混合不同版本的运行时库时。从概念上讲,我的目标似乎很简单,但我还没有找到实现我想要的一切的方法。

这是我拥有的,以及我想做的:


常用库: ComLib1 ComLib2 ...


Exe1: ComLib1 ComLib2 ... Exe1Lib1 Exe1Lib2 ... exe1


Exe2: ComLib1 ComLib2 ... Exe2Lib1 Exe2Lib2 ... exe2


所以 2 个不同的可执行文件,使用一组通用库和特定于 Exe 的库。

我想创建 4 种不同的构建配置。

Cfg1: 这将包含所有库(包括公共库)的调试信息/非优化代码。

Cfg2: 这将包含所有 Exe 特定库的调试信息/非优化代码,但不包含公共库。

Cfg3: 这将包含一些库的调试信息/非优化代码库和其余库的非调试信息/优化库的组合。

Cfg4: 你猜到了。这将包含所有非调试信息和优化代码。

我的第一次尝试基本上是为每个库创建 2 组二进制文件;一个在调试模式下编译(使用 /MTd /Od),另一个在发布模式下编译(/MT /O2)。然后在我的各种配置中选择一个或另一个版本。这对于 Cfg1 和 Cfg4 来说很好(因为所有运行时库自始至终都是一致的),但遇到了 Cfg2 和 Cfg3 的那些链接错误。

我明白为什么会出现这些错误。我只是不确定如何解决这些问题,我认为这是一种常见的情况。也许 Cfg3 并不常见,但我认为 Cfg1,2 & 4 是。

感谢您的意见。


编辑 我真的不认为我需要添加这些信息,因为我想让我的问题简短(呃)。但如果它可以帮助澄清我的目标,我会把它加起来。

这是一个实时模拟器。我无法在典型的 Debug 配置中运行每个库,因为我无法维护 Realtime。我很少需要调试公共库,因为它们主要与服务器/IO 任务相关。 Exe 库主要包含数学/热力学,是我最常花时间的地方。但是,1 Exe lib 包含反应堆中子学,这涉及大量计算。我们通常将其视为黑盒(神秘的供应商提供的代码),我几乎总是希望使用优化代码(典型的发布设置)来运行它。

【问题讨论】:

我必须阅读到底部才能获得关于您的工具链可能是什么的最轻微提示。稍后我将添加一个 Visual Studio 标记,但这是应该在此类问题的第一段左右出现的内容。 感谢您的建设性反馈。我同意人们拒绝投票。我只是讨厌他们没有解释就这样做。不管目标是谁。 有趣的是我没有也没有投反对票。我对 Visual Studio 的了解还不够深入,无法评价这个问题的好坏。 Cfg2 和 Cfg3 可能有效,但可能导致未定义的行为,并且支持极差(如您所见)。我强烈建议避免这些配置,除非在调试代码时绝对有必要获得可接受的性能。 见:***.com/questions/11658915/… 【参考方案1】:

如果没有一些特殊考虑(例如,在接口中使用没有 CRT 对象的 DLL 等以使它们完全分开),则不能在同一进程中使用不同的运行时库,而不会出现链接错误或运行时问题的风险,如果 CRT 对象是之间传递。

您可以在一个模块中混合使用大多数常规优化选项,但有一个明显的例外是链接时间代码生成必须对所有对象都相同。只要您自己的代码未优化,发布运行时库通常也可用于调试。

要轻松切换,您将需要针对您想要的每种情况的解决方案配置(所以 4)。如果您不希望某些配置重复但必须遵循前面提到的限制,并且可能会混淆诸如输出目录之类的内容,则可以将一个项目配置用于多个解决方案配置。您还可以使用属性表在多个项目和配置之间共享设置。

【讨论】:

我实际上已经使用了属性表。我已经剥离了大部分本地项目设置,而是从我的属性表中继承它们。这就是我想定义我的 4 个配置的地方,因为它们在 Exe1 和 Exe2 之间是相同的,如上例所示。我想我的问题是找出哪个配置应该使用哪个运行时。我倾向于将优化选项 (/O2) 与发布运行时相关联,将非优化选项 (/Od) 与调试运行时相关联,这就是我最初构建设置的方式。调用配置调试并让它使用发布运行时似乎很奇怪。 我只是认为调试 CRT 是额外的调试。不需要在一个模块中调试很多问题,仍然可以看到字符串、向量等的值,使整个程序非常快。【参考方案2】:

我在输出目录路径或目标文件名中使用了预定义宏。 例如,我使用$(Platform)_$(Configuration) 扩展为Win32_DebugWin32_Release

您也可以使用环境变量。我还没有尝试过使用预处理器宏。

在 Internet 上搜索“MSDN Visual Studio 预定义宏 $(Platform)”。

【讨论】:

感谢您的意见。我对那些 Visual Studio 宏很熟悉,因为我在属性表中经常使用它们。但我不确定这是否解决了我的问题。也许我的问题不够清楚,这就是为什么我得到所有这些反对票。【参考方案3】:

这就是我最终得到我想要的东西的方式。

假设我使用的是静态运行时库,我想我会为我的公共库保留典型的调试/发布(分别为 /MTd 和 /MT)库,并为我的 Exe 创建 3 组库:

Exe1Lib1Release:典型的发布配置 Exe1Lib1Debug:典型的调试配置 Exe1Lib1DebugMT:带有调试信息的非优化代码,但使用 MT 运行时库

Cfg1: 将使用典型的调试库

Cfg2 和 Cfg3: Common Libraries 将使用典型的 Release 库,Exe 的库使用 Exe1Lib1DebugMT

Cfg4: 将使用典型的发布库。


编辑 实际上,Cfg2 和 Cfg3 设置更准确地表示为:

Cfg2: Common Libraries 将使用典型的 Release 库,Exe 的库使用 Exe1Lib1DebugMT

Cfg3: 将典型的 Release 库用于 Common Libraries,并将 Release 和 Exe1Lib1DebugMT 的组合用于 Exe 的库

【讨论】:

这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review @Alex.K 我不知道你为什么这么说。我实际上最终做到了这一点,它满足了我在原始帖子中提到的所有要求。也许我没有足够清楚地表达这些要求或提供足够的细节让人们理解它们,但我所做的却给了我我想做的事情。 @Alex.K 好吧,更准确地说。我现在无需使用 /NODEFAULTLIB 即可在所有 4 种配置上进行干净的构建。 Realtime 程序似乎在所有 4 种配置上都可以正常工作。但是我还没有进行大量的测试,也没有尝试在这些不同的库中放置断点来查看是否获得了我希望的调试信息。

以上是关于多项目配置 C++的主要内容,如果未能解决你的问题,请参考以下文章

重用编译器前端的结果,加快多配置/平台的 C++ 代码编译

VS2017 将手动配置为 x86 的 C++ 项目加载为 VS2010 项目

从零开始实现一个C++高性能服务器框架----配置模块

如何在 Visual Studio (C++) 项目向导中添加/重命名配置?

vs设置多线程编译的数量

在 QtCreator 中配置 c++ 项目的问题