【问题标题】:Split a Visual Studio C++ project : how to do it (almost) automatically?拆分 Visual Studio C++ 项目:如何(几乎)自动执行?
【发布时间】:2016-06-23 05:39:30
【问题描述】:

我有一个 Visual Studio 2015 C++ 项目,其中引用了一些第 3 方免费库。

只是为了减少编译时间(目前为 5 - 90 秒),
我想将项目拆分为许多较小的项目。

在准备中,我已经在解决方案资源管理器中创建了过滤器
过滤器显示了我项目的顶级结构 - 分为 tier :-

Tier 1  - my core library, no reference to outside, rarely change
Tier 2a - my custom encapsulator for external library "A"
Tier 2b - my custom encapsulator for external library "B"
...
    note: all Tier2 #include Tier1 , rarely change
Tier 3  - business logic that rarely change, #include Tier1&2
Tier 4  - business logic that often change , #include Tier1&2&3

问题:如何轻松将这个项目拆分成多个项目?
例如几乎很简单,只需单击过滤器然后选择“提取到新项目”

我已经阅读了一些资料——它们的解释适用于如何从头开始创建,而不是现有项目。

似乎我还必须为某些单独的文件添加一些行。

#if defined DLL_EXPORT
#define DECLDIR __declspec(dllexport)
#else
#define DECLDIR __declspec(dllimport)
#endif

我有>100个文件,所以不太实用。
我用谷歌搜索了“split visual studio c++ project”,但没有找到很多结果。

相关问题:不解释“如何”
How do you split a Visual Studio Solution?

外部链接:都有#define DECLDIR __declspec(dllexport)
http://www.codeguru.com/cpp/cpp/cpp_mfc/tutorials/article.php/c9855/DLL-Tutorial-For-Beginners.htm
https://manski.net/2011/11/creating-a-dll-project/

【问题讨论】:

  • 我知道没有简单的方法。我通常复制整个项目文件夹,重命名 vcxproj 文件,将所有 refs 重命名为 vcxproj 文件中的项目名称(使用记事本++),然后将新项目添加到解决方案中并删除所有我不想要的文件在那里。习惯后大约需要 3 分钟...不太理想,但仍然...
  • @Baldrick 谢谢!最多3分钟是很少的! ....您能否解释一下“将所有引用重命名为 vcxproj 文件中的项目名称”?如果我有 pj1.vcxproj 并想创建库 pj2,粗略地说,我将不得不编辑 pj1.vcxproj 中的所有单词“pj1”,对吗?我只找到了 1 个地方 pj1,你是这个意思吗? ......我还需要手动对每个文件进行 DECLDIR declspec(dllexport) 吗?
  • 是的,基本上。有多少 refs 取决于项目中的内容,但重命名您找到的所有引用,并尝试将其添加回解决方案。如果你把它搞砸了,它将无法加载。这对“DECLDIR”部分没有帮助 - 因为您可能需要某种宏或脚本来处理您的文件并将其添加。

标签: c++ visual-studio projects-and-solutions


【解决方案1】:

我想首先指出,如果您的较低层很少更改,那么整个编译也很少发生。另请注意,没有一键统治他们所有的解决方案。

你快到了。如果您已经将项目分组到单独的库中,那么下一步就是将它们实际转换为动态库。只要不更改符号,这将大大加快编译速度(实现修改很好)。例如Tier 1 项目:

首先,创建一个动态库项目(DLL Project)。擦除所有由 VS 生成的源代码。将所有Tier 1 的源代码(头文件和cpp/实现文件)分组到项目目录。将它们添加到项目中。

我们可以为每个头文件拥有多个动态库,但 Visual Studio 并不是此类任务的最佳 IDE(使用 CMake 或 QBS 等技术)。为了安全起见,将声明合并到单个头文件中(或至少一些可管理的数字,不要忘记更改实现文件中的#include)。将动态库宏添加到标题中,例如tier1lib.h

#ifdef DLL_EXPORT
#define DECLDIR __declspec(dllexport)
#else
#define DECLDIR __declspec(dllimport)
#endif

这个宏会根据我们的构建命令判断我们是在导入还是导出符号。

现在在tier1lib.h,标记哪个符号将对其他项目可见。在每个函数中添加DECLDIR宏如

DECLDIR void foo();
// or, if you want to export/import whole class' public symbols
class DECLDIR Foo{};

构建它。

现在在主项目中,告诉 VS 在哪里可以找到动态库。添加包含路径(在哪里可以找到头文件)、库路径(在哪里可以找到*.lib 文件)和库文件名(例如tier1lib.lib)。将生成的*.dll 复制到主项目的输出文件夹,Tier 1 编译现在完全分离到主项目中。

【讨论】:

  • 谢谢。第 1 层有 30 个 .h 文件,我不应该将所有声明合并到单个头文件中,不是吗?恕我直言,仅前向声明 30 个文件可能很乏味并降低可维护性。 .... 或者它是现实商业世界的“道路”?
  • 不。只做适合您需要的事情。合并声明只是意味着更少的动态库宏,不会影响任何东西。
  • 我建议您将时间投入到可编写脚本的构建工具上,例如 CMakeQBS,它们有优化构建的方法。根据我的经验(构建 OpenCV),即使使用 MSBuild 也比在 VS 中构建要快得多。您可以清楚地看到 VS 经常在输出面板中多次构建东西,我不知道为什么会这样做。
  • CMake 不会构建任何东西。它实际上是一个生成器,所以你会得到一个 VS 解决方案。但是你可以用它轻松地制作花哨的多依赖项目。另一方面,Qbs 可以在您的系统中找到大多数编译器并实际构建您的项目。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-14
  • 2011-06-02
  • 2023-03-27
相关资源
最近更新 更多