Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The idea (only implemented in Buck AFAIK) is to model not a list of include directories, but a mapping from the path specified in your "#include" to the actual file on disk.

So your code might look like this:

    #include <foo/bar.hpp>
The project folder structure might look like this:

    .
    └── src
        └── include
            └── foo
                └── bar.hpp

And the mapping might look like this:

    {
      "foo/bar.hpp": "./src/include/foo/bar.hpp"
    }

This enables the build system to know exactly which headers are meant to be exposed by a library to its dependees. The build system can then tell you:

(1) Exactly where a header comes from

(2) Exactly which headers a library exports

(3) If two libraries will collide in terms of headers

(4) If someone is trying to use a header that is not explicitly exported by a library.

(5) If some is accessing a header in the wrong way (e.g. abusing the layout of source-files and not using the correct include-path)

This approach scales very well. Constructing the mapping can be done via globs (globs work properly in Buck), so most projects just do:

    exported_headers = subdir_glob([
      ('include', '**/*.hpp'), 
    ])
Additionally, the RHS of the mapping might be another build rule, thus supporting generated headers in hermetic builds.


The ability to specify at a finer level of granularity than directories sounds wildly overcomplicated, to be honest. I'm not aware of any other language that works at that level either (maybe Python's import mechanism does let you tinker at that level, but it would be extremely niche). Also, I'm also a bit confused about how it can work even in C/C++; surely most compilers don't even have the capability of specifying header file locations on an individual level, as opposed to the classic -I switch (or /I for Visual Studio).

I've used generated header files (protobuf) with CMake and they work fine. Although I prefer to create them at configure time rather than build time, even though that's philosophically incorrect, just because that way I can see them in the generated IDE projects and they don't break autocomplete.


I have used Buck for many projects, and in practice it is not complicated all... in fact I think it might be simpler. The reason why is that you define the includes relative to a single path, and the layout is just a Python (well, Skylark) dictionary in the build system. You never have issues with includes happening from the wrong paths, or the build breaking because files have moved around and someone wasn't including things in the correct way. Proper globs are also amazing from a build maintenance perspective.

You can also wire up Protobuf headers in the map.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: