SanderMertens / bake

Bake, A build system for building, testing and running C & C++ projects

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Including Headers From Package

yuvaldolev opened this issue · comments

Hi,
I'm trying to include a header from a package that I wrote and built using bake in an application that uses the package, but am getting an error.
The header is in a folder with the package's name within the package's include folder.
When I'm trying to #include "Lib/Header.h" from files inside the package itself it compiles successfully, because I added an include statement inside the project.json's "lang.cpp" property for the include folder.
But when I'm trying to do the same include from the application it says that the header does not exist.
Do I need to manually add an include directory to the application's project.json?
Thanks!

Good question! TLDR: add a "dependee" attribute to the project.json of your package like this:

{
    "id": "Lib",
    "type": "package",
    "value": {  },
    "lang.cpp": {
        "include": ["${locate include}"]
    },
    "dependee": {
        "lang.cpp": {
            "include": ["${locate include}"]
        }
    }
}

A word of warning: this can cause potential header filename collisions between bake packages! The default pattern is to have a "main" header file, which includes all the other headers. For a package Lib, you'd have a file Lib.h, stored in include. If your package also contains Header.h, you'd add this statement to Lib.h:

#include "Header.h"  // Note I'm using " ", important!

If Header.h is in a subdirectory "Lib" within the include directory, you'd simply add this to Lib.h:

#include "Lib/Header.h"

Then, when you add Lib as a dependency of your application project.json, Lib/Header.h will be automatically available to your code (through bake_config.h). This fully automates including files, and is what most bake packages do. To add it as a dependency, you'd do:

{
    "id": "App",
    "type": "application",
    "value": {  
        "use": ["Lib"]
    }
}

If you want to achieve exactly what you describe in the issue description, it helps to know a bit more about how bake stores include files. When you build, include files are copied to ~/bake/x64-darwin-debug/include/Lib.dir (or equivalent). For your example project, files would be stored in: ~/bake/x64-darwin-debug/include/Lib.dir/Lib/Header.h.

Bake automatically adds ~/bake/x64-darwin-debug/include to the compiler include path. It also automatically creates a file ~/bake/x64-darwin-debug/include/Lib that links to ~/bake/x64-darwin-debug/include/Lib.dir/Lib.h. This lets your application include Lib like this:

#include <Lib>  // Note I'm using < >, important!

However, if you have an additional include file that is not included by include/Lib.h, you can include it with an include statement like this:

#include <Lib.dir/Lib/Header.h>

This works for both the package as well as its dependencies. The downside of that is that it looks a bit weird. So, the alternative is to add the include path to both your project and your dependencies (like you suggested), so that you can do this:

#include <Lib/Header.h>

It would be nice if you wouldn't have to add the include path manually to all your dependencies. You can achieve that in bake with the dependee attribute. It lets you specify attributes that should be added to the configuration of the dependees of a project, instead of to the project itself. To add the project-specific include path to the dependee project configurations, see the example at the top.

The ${locate include} is a bake function which dynamically looks up the correct include path of the project, so you're not tightly coupled with where the package is installed (it can be either in BAKE_HOME or BAKE_TARGET).

So you see, there's quite a bit of complexity to make things "just work", but fortunately all of that complexity can be localized to the configuration of the package.

Ok,
Thank You!