【问题标题】:Visual Studio 2019: Pass include paths between chain-referenced projectsVisual Studio 2019:传递包含链引用项目之间的路径
【发布时间】:2021-05-22 09:31:14
【问题描述】:

假设我们有一个现有的 Visual Studio 2019 解决方案,该解决方案无法使用其他工具从头开始生成,例如CMake。

该解决方案包含三个项目:A、B 和 C,每个项目只包含一个文件,这是一个最小示例:

/// Project A, A.hpp
// content irrelevant

/// Project B, B.hpp
#include <A.hpp>  // B's public interface includes A's header

/// Project C.cpp
#include <B.hpp>  // C requires B's header, which includes A's header, to compile

习惯了 CMake 的“基于目标”的方法,我天真地认为我可以处理以下情况:

  • B 引用 A,
  • C 引用 B

然而,在这种情况下,C 只使用 B 的包含路径,但不使用 A 的包含路径。因此 C 不能编译。

“让它工作”的“解决方法”是显而易见的:将 A 的包含路径添加到 C,它会编译。但我们知道,随着项目数量的增长,这种规模会变得非常可怕:

> /// Project C2, C2.cpp 
> #include <B.hpp>  // requires B interface to compile

> /// Project C3, C3.cpp 
> #include <B.hpp>  // requires B interface to compile

> /// Project C4, C5, ... and on and on 

我不必在许多项目中指定 B 接口的需求,而是寻找 CMake 提供的功能:在 B 项目本身中定义 B 的需求(在我的情况下:包含路径),仅此而已。

我的问题是:如何完全在 Visual Studio 2019 IDE 中实现这一目标

【问题讨论】:

  • 您想要 CMake 解决方案还是纯 VS 解决方案?据我了解,您不想要 CMake - 那么它与 CMake 有什么关系?
  • 此外,似乎已经配置了链接(解决方案资源管理器中的参考节点)。所以基本上你想为你的项目调整包含路径,对吧?
  • @Bernd 感谢您指出这一点,我确实在寻找纯 VS 解决方案。我现在删除了 cmake 标签。至于其他问题,是的 - 包括路径。
  • 我不相信 VS 有任何这样的选择。此外,包含所有 A 的包含是不正确的。一般来说,A 可能包含一些完全不需要的包含 B。我管理它相当简单。我从不写#include "B.hpp",而是#include "B/B.hpp",所以项目需要包含但所有项目所在的文件夹。或者如果你有多个项目所在的文件夹,你甚至可以像#include "SolName/B/B.hpp"这样写,所以整个包括只是整个解决方案的一个文件夹(除了第三方包括...)
  • 通常的100% UI方式是定义#include你想要的方式,即:“a\a.hpp”或“a.hpp”等,然后“play”引用项目属性“配置属性”/“VC++ 目录”/“包含目录”并添加相对路径,即:“..”或“..\a”或其他任何内容。这样,您永远不会更改源代码,但可以创建无限变化的项目。否则你可以使用 MSBuild 的 .csproj 来做更强大的事情。

标签: c++ visual-studio visual-c++ visual-studio-2019


【解决方案1】:

正如一些人评论的那样,解决这个问题的最简单方法可能是添加一个上层文件夹作为包含路径,然后从这里相对包含文件。

如果你的代码是这样的结构:

your_code/
    A/
        a.hpp
        a.cpp
    B/
        b.hpp
        b.cpp
    C/
        c.hpp
        c.cpp

然后,不要在B 的包含路径中添加your_code/A 和在Cyour_code/B,而是将your_code 添加到每个人的路径中,然后从BB/b.hpp 中包含A/a.hpp来自C。我认为这种方法比 Kamen 建议的在您的包含中使用 .. 更干净。

代码可以以不同的方式组织(使用inc/src 文件夹来隔离标头/实现,在inc 文件夹下重复库名称,以便在其库路径中有any_libinc 的人会包括any_lib/...hpp 以避免在头文件查找中发生冲突...),但最后,方法保持不变,尝试让B 查找A 的相对包含来自@987654341 已知的位置@ 以便它也能找到它。

无论如何,好的解决方案(长期)可能是最终使用CMake(或任何构建系统)为您正确处理,但这显然不是目前的选择。


编辑:This post 展示了如何将一堆包含添加到项目中。你也可以使用它,有一个 IncludeDirsForB.txtB 路径所需的一切,并使用 B@IncludeDirsForB.txt 添加到每个项目的命令行...?

【讨论】:

    【解决方案2】:

    您可以通过右键单击项目、属性、“C++ 目录”来手动配置包含路径

    这可行,但性能不是很好/不是很好。您可以通过 MSBuild 配置它,例如也有一个共享的道具文件。但我也不喜欢这种方法。

    在我看来,这样做的最佳选择是使用具有共享元素的共享库/项目,不仅适用于多个部分(exe、dll...),还适用于交叉编译。

    这允许您将所有接口文件放在那里。我更进一步——我的项目不包含代码——它完全存储在共享项目中。 通过此设置,您可以创建例如使用 MSVC 的 Windows 项目和使用相同代码库使用 GCC 编译的 Linux 版本。或者创建一个静态或动态库 - 没有什么是固定的。

    要使用共享项目中的代码,您可以简单地将其添加为参考(就像您对其他项目所做的那样) - 非常简单。 如果您需要进一步的帮助 - 请询问。

    您可以在 github 上找到示例:https://github.com/bernd5/Stackoverflow-VS-Sample

    求帮助一些图片(我的 VS 是德文的 - 但我希望你能用它):


    如果您不喜欢共享库方法,您可以在此处找到不带“..”的替代方法: 首先,您需要将每个项目的 include-directories 属性调整为: (添加了 MSBuild-Variable SolutionDir

    那么你可以简单地写:

    #include "A/A.h"
    

    【讨论】:

    • 顺便说一句:如果你需要像 boost 或 openCV 这样的第三方库,我会向你推荐 vcpkg - 它有一个很好的 MSBuild 集成
    • 你还想念什么吗?请发表评论...
    【解决方案3】:

    根据https://docs.microsoft.com/en-us/cpp/build/adding-references-in-visual-cpp-projects?view=msvc-160#consuming-static-libraries,他们似乎建议使用以下方式访问标头:

    #include "../A/A.hpp"
    

    这只是利用解决方案结构并继续工作。

    我刚刚对此进行了测试,它确实有效... 我把例子放在https://github.com/kyotov/ABC

    【讨论】:

    • 它通常可以工作 - 但在我看来,“..”的使用是一个糟糕的设计并且容易出错。在这里您可以找到相同主题的主题:stackoverflow.com/questions/15120330/…
    • 最好将解决方案根路径添加到 ALX23z 描述的包含路径集
    • @Bernd 除非你有 C++/20 和模块,否则这是正确的答案。我同意这是一个糟糕的设计,但这个糟糕的设计是从 1972 年引入 C 的时候开始的。
    • 当然#include 是一种非常古老的机制——简单且难以正确执行(主要是:尽可能少地包含)。但这不是重点——我想说“..”是不好的风格。好的,在 Visual Studio 中这还不错,因为您通常不会在项目中创建子文件夹,只是称为“过滤器”的虚拟文件夹,但通常应该避免。
    • 完全同意,这很难避免。一种选择(更好一点,但并不理想,您已经提到过)是将解决方案的根包含到包含路径中。这样你可以跳过“..”,但你仍然需要做#include &lt;project&gt;/&lt;path&gt;/&lt;file&gt;。一个好的做法是在项目中创建一个带有公共标头的特殊目录 - 即您打算由项目客户使用的标头。然后确保你只包括从那里......例如#include "A/api/header.h"
    猜你喜欢
    • 1970-01-01
    • 2012-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-18
    • 2011-04-06
    • 2020-03-14
    相关资源
    最近更新 更多