Search code examples
c++compiler-constructionbuildincremental-build

C++ header-implementation-header-implementation dependency chain


I'm trying to create simple C++ incremental-build tool with dependency resolver. I've been confused about one problem with cpp build process. Imagine we have a library consists several files:

// 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();

When in client code including h1.h

// app1.cpp
#include "h1.h"
int main()
{
  H1();
  return 0;
}

there is implicit dependency of s2.cpp implementation: our_src -> h3 -> s1 -> h2 -> s2. So we need to link with two obj files:

g++ -o app1 app1.o s1.o s2.o

In contrast when h3.h included

// app2.cpp
#include "h3.h"
int main()
{
  H3();
  return 0;
}

there is only one source dependency: our_src -> h3 -> s2

So when we include h3.h we need only s2.cpp compiled (in spite of s1.cpp -> h2.h inclusion):

g++ -o app2 app2.o s2.o

This is very simple example of the problem, in real projects surely we may have several hundreds files and chains of inefficient includes may contain much more files.

So my question is: Is there a way or instruments to find out which header inclusion could be omitted when we check dependencies (without CPP parsing)?

I would appreciate for any responce.


Solution

  • In the case you stated to see the implicit dependence on s2.cpp you need to parse the implementation module s1.cpp because only there you will find that the s1 module is using s2. So to the question "can I solve this problem without parsing .cpp files" the answer is clearly a no.

    By the way as far as the language is concerned there is no difference between what you can put in an header file or in an implementation file. The #include directive doesn't work at the C++ level, it's just a textual macro function without any understanding of the language. Moreover even parsing "just" C++ declarations is a true nightmare (the difficult part of C++ syntax are the declarations, not the statements/expressions).

    May be you can use the result of gccxml that parses C++ files and returns an XML data structure that can be inspected.