Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;报头实现报头实现依赖链 我试图用依赖性分解器创建简单的C++增量构建工具。 我对cpp构建过程中的一个问题感到困惑。 假设我们有一个由多个文件组成的库: // h1.h void H1(); // s1.cpp #include "h1.h" #include "h2.h" void H1(){ H2(); } // h2.h void H2(); // s2.cpp #include "h2.h" #include "h3.h" void H2(){ /*some implementation*/ } void H3(){ /*some implementation*/ } // h3.h void H3();_C++_Compiler Construction_Build_Incremental Build - Fatal编程技术网

C++;报头实现报头实现依赖链 我试图用依赖性分解器创建简单的C++增量构建工具。 我对cpp构建过程中的一个问题感到困惑。 假设我们有一个由多个文件组成的库: // h1.h void H1(); // s1.cpp #include "h1.h" #include "h2.h" void H1(){ H2(); } // h2.h void H2(); // s2.cpp #include "h2.h" #include "h3.h" void H2(){ /*some implementation*/ } void H3(){ /*some implementation*/ } // h3.h void H3();

C++;报头实现报头实现依赖链 我试图用依赖性分解器创建简单的C++增量构建工具。 我对cpp构建过程中的一个问题感到困惑。 假设我们有一个由多个文件组成的库: // h1.h void H1(); // s1.cpp #include "h1.h" #include "h2.h" void H1(){ H2(); } // h2.h void H2(); // s2.cpp #include "h2.h" #include "h3.h" void H2(){ /*some implementation*/ } void H3(){ /*some implementation*/ } // h3.h void H3();,c++,compiler-construction,build,incremental-build,C++,Compiler Construction,Build,Incremental Build,在客户端代码中时,包括h1.h // app1.cpp #include "h1.h" int main() { H1(); return 0; } s2.cpp实现存在隐式依赖关系: 我们的_src->h3->s1->h2->s2。因此,我们需要链接两个obj文件: g++ -o app1 app1.o s1.o s2.o 相比之下,当h3.h包括 // app2.cpp #include "h3.h" int main() { H3(); return 0; } 只有一

在客户端代码中时,包括h1.h

// app1.cpp
#include "h1.h"
int main()
{
  H1();
  return 0;
}
s2.cpp实现存在隐式依赖关系: 我们的_src->h3->s1->h2->s2。因此,我们需要链接两个obj文件:

g++ -o app1 app1.o s1.o s2.o
相比之下,当h3.h包括

// app2.cpp
#include "h3.h"
int main()
{
  H3();
  return 0;
}
只有一个源依赖项: 我们的_src->h3->s2

因此,当我们包含h3.h时,只需要编译s2.cpp(尽管包含s1.cpp->h2.h):

这是一个非常简单的问题示例,在实际项目中,我们可能有数百个文件,而无效的包含链可能包含更多的文件

所以我的问题是:当我们检查依赖项时(没有CPP解析),有没有一种方法或工具可以找出哪些头包含可以省略


如果您能给我回复,我将不胜感激。

这不是一个容易的问题。这其中有很多困难:

  • 如果在N>1个源文件中实现了一个头文件,该怎么办?例如,假设
    类Foo
    Foo.h
    中定义,但在
    Foo\u cotr\u dotr.cpp
    中实现,
    Foo\u this\u function.cpp
    Foo\u that\u function.cpp
  • 如果在多个源文件中实现相同的功能会怎么样?例如,假设
    Foo::bar()
    Foo\u bar\u linux.cpp
    Foo\u bar\u osx.cpp
    Foo\u bar\u sunos.cpp
    中有实现。要使用的实现取决于目标平台
  • 一个简单的解决方案是构建一个共享的或动态的库,并针对该库进行链接。让工具链解决这些依赖关系。如果你有一个足够聪明的makefile,问题1会完全消失,问题2也会消失


    如果你坚持反对这个简单的解决方案,你需要自己做些事情来解决这些依赖关系。您可以通过项目规则“一个头文件==一个源文件”来消除上述问题(不是详尽的列表)。我见过这样一个规则,但不像我见过的项目规则那样频繁,它说一个函数==一个源文件。

    在您声明要查看对s2.cpp的隐式依赖的情况下,您需要解析实现模块s1.cpp,因为只有在那里,您才会发现s1模块正在使用s2。因此,对于“我能在不解析.cpp文件的情况下解决这个问题”这个问题,答案显然是否定的

    顺便说一句,就语言而言,在头文件或实现文件中可以放置的内容没有区别。<>代码>包含指令不在C++级别工作,它只是文本宏函数,不理解语言。 此外,即使解析“仅仅”C++声明也是一个真正的噩梦(C++语法的难点是声明,而不是语句/表达式)。

    可以使用该解析C++文件的结果,并返回一个可以检查的XML数据结构。

    < p>您可以查看我是如何实现的。它使用指令为单个源文件添加依赖项。文档尚未完全完成,但Gabi的源代码中有Wand指令的示例

    例子 线程类包含文件 Thread.h在链接时需要Thread.o

    #ifdef __WAND__
    dependency[thread.o]
    target[name[thread.h] type[include]]
    #endif
    
    线程类在windows上的实现(Thread-win32.cpp) 仅当Windows是目标平台时才应编译此文件

    #ifdef __WAND__
    target[name[thread.o] type[object] platform[;Windows]]
    #endif
    
    GNU/Linux上的线程类实现(Thread Linux.cpp) 仅当GNU/Linux是目标平台时,才应编译此文件。在GNU/Linux上,链接时需要外部库pthread

    #ifdef __WAND__
    target
        [
        name[thread.o] type[object] platform[;GNU/Linux]
        dependency[pthread;external]
        ]
    #endif
    
    利弊 赞成的意见
    • Wand可以扩展到其他编程语言
    • Wand只需发出Wand命令,即可保存成功链接新程序所需的所有必要数据
    • 项目文件不需要提及任何依赖项,因为它们存储在源文件中
    欺骗
    • Wand在每个源文件中都需要额外的指令
    • 该工具尚未被图书馆作者广泛使用

    感谢您的回复!情况并没有比我预料的更糟。我已经尝试过rbgccxml(Ruby接口),但发现该解决方案只有一个缺点:它需要gcc,并且在构建时将gccxml与其他编译器一起使用不是很好。@Bombazook:Re“感谢您的响应!”:在这个网站上表达感谢的恰当方式是投票选出好的答案,并接受你认为最好的答案。@David Hammen:对不起,我的名声不允许我投票。我知道我在试图重新发明轮子,但我讨厌糟糕的makefile语法,一开始总是尝试静态链接。您的解决方案可以帮助我解决当前cpp项目的问题,但我希望在将来使其更容易。因此,我想基于gccxml或类似SWIG的东西创建自己的依赖项解析器。
    #ifdef __WAND__
    target
        [
        name[thread.o] type[object] platform[;GNU/Linux]
        dependency[pthread;external]
        ]
    #endif