Vs2008 C ++:如何制作递归包含目录?

时间:2009-10-19 17:56:54

标签: c++ visual-studio-2008 include

我使用Visual Studio 2008将一个复杂的项目作为C ++库包含在内。

我有一组包含在非常复杂的目录树结构中的包含文件。树的根有大约十个目录,然后每个目录可以有多个子目录,子目录等。

我知道该结构中的所有头文件都是必需的,并且它们无可救药地相互关联;我不能只包含一个目录,因为那时另一个目录中的依赖关系会被遗漏,并导致编译器因未被邀请参加聚会而烦恼。所以,每个人都必须被包括在内。

我可以通过向项目添加一个目录(右键单击> properties->其他包含目录)来实现这一点,但这可能会让人感到痛苦,特别是当其中一个依赖项具有子项时制作一个全新的subsubsubdirectory。

有没有办法在头文件本身中指定一个include目录,这样每当我需要使用它包含的函数时我就可以包含那个头?这样,我可以更轻松地编辑包含文件,而且我不必确保调试版本和发布版本彼此一致(因为属性右键单击默认为当前版本,而不是所有版本,从调试切换到发布时导致严重崩溃的功能)。更好的是,有没有办法指向目录根并强制所有内容以递归方式包含?

编辑所有这些答复到目前为止:

无法编辑此项目的结构。我只能链接到它。我不喜欢代码的组织方式,而不是其他人似乎,但我必须在这个约束下工作。不是花费时间在容易发现错误的过程中找到所有相互依赖关系并将它们放在项目文件中,有没有办法以编程方式执行此操作?

3 个答案:

答案 0 :(得分:5)

这显然不是一个好主意,真的。

这些目录是一种在逻辑组中组织代码的方法。

 /web
   /include
     /web
       /stackoverflow
         /language-agnostic
         /algorithm
         /database
       /meta
         /bug
         /feature-request
   /src

 /local/
   /include
     /local
       /my-favorites
   /src

现在如果我输入

#include "exception.h"

我想包括什么?那个文件在哪里?我怎样才能看到它的内容?

另一方面,如果我输入

#include "local/my-favorites/exception.h"

然后它非常清楚。 (我只有两个包含-Iweb / include -Ilocal / include)

通过这种方式,我可以拥有多个具有完全相同名称的文件,并且没有歧义,当您希望集成两个具有“exception.h”的不同第三方库时,这是非常好的。

另请注意,为清楚起见,命名空间嵌套应反映目录组织。那么

file: "web/include/web/meta/bug/exception.h"
namespace web { namespace meta { namespace bug {
  struct exception: std::runtime_error {};
} } } // namespace bug, namespace meta, namespace web

通过这种方式,您可以轻松地想到在需要课程时必须包含哪些标题。

另请注意,例如,如果你看看boost,他们会在每个目录中为“懒惰”程序员添加标题,其中包括所有子目录的标题

file: "web/include/web/meta/bug.h"
#include "web/meta/bug/file1.h"
#include "web/meta/bug/file2.h"
#include "web/meta/bug/file3.h"
#include "web/meta/bug/file4.h"
#include "web/meta/bug/file5.h"

file: "web/include/web/meta.h"
#include "web/meta/bug.h"
#include "web/meta/feature-request.h"

这些包含也可能使用using指令将名称“拉”到更通用的命名空间中:

namespace web { namespace meta {
  using ::web::meta::bug::bug;
} } // namespace meta, namespace web

让开发人员减少痛苦。

正如您所看到的,该语言已经为您提供了一种干净利落地组织代码的非常好的方法,如果您使用“所有包含”选项,您将最终得到一个难以维护的混乱:

#include "exception.h"
#include "bug.h"
#include "myString.h"
#include "database_connect.h"
#include "helper.h" // really love this one...
#include "file.h" // not bad either eh ?

我已经有一些这样的工作...想想20个不合格的包括当你依赖25个以上的组件时...现在,你认为可以删除对组件X的依赖吗? ;)

编辑:如何处理第三方图书馆?

有时第三方图书馆不符合您的期望,无论是:

  • 不是自给自足的标题(即你需要包含3个文件来使用1个对象)
  • 汇编时的警告
  • 标题组织问题

你总是有机会将它们包装在你自己的标题中。

例如,说我有:

/include
  /file1.h
  /file2.h
  /detail
    /mustInclude.h
    /exception.h

任何时候你想要包含一个文件,你必须包含'exception.h'BEFORE和'mustInclude.h',当然你有一个问题,就是很难发现所包含的文件来自第3个派对图书馆,而不是你自己的(当前)项目。

好吧,只需换行:

/include
  /3rdParty
    /file1.h (same name as the one you would like to include, it's easier)

file: "/include/3rdParty/file1.h"

#pragma push
// ignore warnings caused
#include "detail/exception.h" // necessary to include it before anything
#include "file1.h"
#include "detail/mustInclude.h"
#pragma pop

然后在你的代码中:

#include "3rdParty/file1.h"

您刚刚解决了问题,现在所有困难都存在于您的包装文件中。

注意:我只是意识到你可能会遇到第三方标题相互引用但没有考虑“相对路径”的问题,在这种情况下,你仍然可以避免“多重包含”综合症(即使没有版本) ),但这可能是命运多..

我想你没有机会不使用这样的废话:x?

答案 1 :(得分:2)

如果以任何可能的方式你真的应该花时间重做那个烂摊子。它只会变得更糟。

如果您将其作为库包含在内,那么您可能只需要其功能的一部分 - 让它可以逐步访问并再次使用。

编辑:
不,没有递归包含 - 有充分的理由。从一定的大小开始就完全无法控制,你一直都会遇到文件名冲突 您可以通过脚本和项目文件来解决限制,但从长远来看,您真的会后悔。

EDIT2:
好的,紧急程序然后。将库放在自己的项目中,并使用一个简短的脚本生成一行,其中包含;分隔的必要路径,该路径将项目文件放入项目.vcproj(这只是一个xml文件)下:
VisualStudioProject -> Configurations -> Configuration -> Tool -> AdditionalIncludeDirectories
(至少在VS2005中,在以后的版本中可能略有不同)。

如果您需要调用代码中的所有包含,您可能需要考虑将该部分包装在单独项目中的静态库中,以避免污染其余部分。

答案 2 :(得分:0)

  

问:我无法编辑此结构   项目。我只能链接到它。一世   不喜欢代码的方式   比任何人都组织起来了   似乎,但我必须在内部工作   这种约束。而不是花钱   可能需要几个小时才能容易出错   找到所有的过程   相互依赖并将它们放入   一个项目文件,有办法吗?   这个以编程方式?

这应该让你开始:

  1. 编写一个脚本(用您最喜欢的“快速”语言)来枚举库目录中的所有[sub -...]目录

  2. 过滤目录(开始时,删除那些不包含任何.h文件的目录)

  3. 将它们输出到您描述的头文件或直接输出到vcproj文件。该 vs2008 vcproj文件是比较简单的XML。它甚至可能有文档记录,但如果您只是在文本编辑器中查看它,您将找出包含路径的定义位置和方式

  4. 尝试编译

  5. 如果出现错误,请尝试找出原因,调整目录过滤器(黑名单特定目录等)并返回2.

  6. 成功

  7. 无论如何,不​​要害怕编写代码生成脚本