Gradle internals: use makedep to generate cpp dependencies

I know that the cpp feature is incubating, but I would like to use it as the basis of a build and test system for a fairly large project. I guess I took for granted that there would be some way to specify that a certain C++ source file depended on a (large) number of header files (some outside of any project in /usr/include, /usr/local/include, etc.). Now, however, I realize that there seems to be no accounting for these extra-project include files at all.

If I would like to develop a way to inject these into the dependency calculations for individual source files, where should I begin looking?

It is not feasible to specify all of these dependencies by hand, but a tool like makedep/makedepend/etc. could be made to generate source file dependency lists.

Any advice would be greatly appreciated. There’s a dearth of flexible, extensible build tools for C++ projects, and I’m a little disappointed as I feel gradle slipping through my fingers due to something like this.

Gradle has support for prebuilt libraries which can just be a set of headers:

model {
  repositories {
    libs(PrebuiltLibraries) {
      myTemplateLibrary {
        headers.srcDir "libs/myTemplateLibrary/include"
      }
    }
  }
}
  sources.myapp.cpp {
  lib library: 'myTemplateLibrary'
}

Is that what you’re looking for?

Thanks very much for your reply; I really appreciate it!

I think this is the right direction, but I believe it is still a little short. So lets say I have a source file in cpp-example/src/hello.cpp:

#include <string>
#include <iostream>
#include <try-hello.hpp>
  void hello( std::string s ) {
        std::cout << "hello, there " << s << std::endl;
}
  int main(void) {
    std::cout << "Well, ";
    hello("Fred");
    hello(HELLO_STR);
    return 0;
}

try-hello.hpp is in /usr/include, and it contains:

#define HELLO_STR "mick"

So my question boils down to how do I tell Gradle that hello.cpp depends on /usr/include/try-hello.hpp for compilation? I like the fact that with Gradle you specify the things to build without specifying how it should be done, but somehow when try-hello.hpp changes gradle has to know to recompile hello.cpp.

I have the tools to automatically create lines like:

file('cpp-example/src/hello.cpp').dependsOn(file('/usr/include/try-hello.hpp'))

but I don’t know how to hook this into the gradle dependency engine.

thanks again!

My previous example showed how to set the dependency up. So, assuming your executable was named “hello” and you defined your prebuilt library as “tryHello”

executables {
  hello
}
model {
  repositories {
    libs(PrebuiltLibraries) {
      tryHello {
        headers.srcDir "/usr/include"
      }
    }
  }
}
// this creates the dependency
sources.hello.cpp {
  lib library: 'tryHello'
}

So maybe your question is how to restrict the library definition to only include certain source files instead of all the files in a directory? If so, you can filter the sourceset:

model {
  repositories {
    libs(PrebuiltLibraries) {
      tryHello {
        headers.srcDir("libs/myTemplateLibrary/include").include("**/try-hello.hpp")
      }
    }
  }
}

Ah, I understand, thank you very much!

I am trying to test this using gradle 2.2, but I get the error:

* What went wrong:
Shared library link file not set for prebuilt library 'tryHello'.

Do I need a newer version of gradle? FWIW, my build.gradle file looks like:

apply plugin: 'cpp'
  model {
    toolChains {
        clang(Clang)
    }
    repositories {
        libs(PrebuiltLibraries) {
            tryHello {
                headers.srcDir("/usr/include").include("**/try-hello.hpp")
            }
        }
    }
}
  executables {
    hello
}
  // this creates the dependency
sources.hello.cpp {
    lib library: 'tryHello'
}

Try setting the linkage to “api” for the library:

sources.hello.cpp {
    lib library: 'tryHello', linkage: 'api'
}

Beautiful, thank you again! I saw that in the user manual and should have remembered it.

We’re using cmake currently. I would love to switch to gradle, but I have to convince my boss that gradle is up to the task. It’s a pretty large project project (3196 *.cpp files, 5687 header files). If you have any advice, I’d love to hear it.

Thanks again!

Just to make sure I understand the details. What this can do is specify that all of the source files in a library or executable depend on some set of header files (the union of all “tryHello” like API dependencies and the exported header files dependencies, which were exported by library dependencies). Any time an element of that set changes all the constituent source files for the library or executable in question are rebuilt. Is this right? Is there a way to specify a finer granularity, e.g. xyz.cpp depends on this header-file-set?

I tried to find out from the manual, but it is a little vague about these compilation dependency sets.

I appreciate you taking the time for so many questions; it helps a lot.