Forcing mbed's build system to respect directory structure

In my experience, the mbed build system “flattens” the project’s directory structure in some contexts, so source and header files are identified by just their base file name, with no regard to their full paths. It may be convenient in some cases, but I find that it is more problematic than helpful, especially for larger projects.

Because of this, no two header files can have the same name in your project, including mbed-os and all of the other libraries, or else issues happen. In my current project, when I tried to create a base/device.h in my project root, it immediately caused compilation errors because it had precedence over another header file in targets/TARGET_*/**/device.h. That might be fixed by adding #include_next "device.h", but that doesn’t seem right. It’s not overriding the existing device.h, it serves a completely different purpose in a different part of the project.

Likewise, no two source files can have the same name in your project. I ran into problems because I had a base/power_supply.cpp, and then added a library that created a file named drivers/power_supply/power-supply-control/power_supply.cpp, During linking, it caused a warning: Object file power_supply.o is not unique!.

This means that organizing my project purely by directory structure is not feasible. There are other options, but they are suboptimal in comparison:

  • Preserve the directory structure, and make base names unique by prefixing them with the path, so base/device.h becomes base/base_device.h. But that creates redundant names that involve extra typing, extra maintenance, and can’t be reasonably applied to libraries that are maintained separately.

  • Forgo directory structure, and just put all of the files under a single directory in a project. This mostly solves the redundancy and clash problems, but it’s relatively disorganized. In addition, I still have to have special directories like TARGET_*/ which I’ll have to be careful about, and separately maintained libraries which have a bunch of file names that I’ll still have to avoid using.

It would be nice to have a per-project option to enforce namespacing of source and header files by their paths. Unfortunately, mbed-os and many other libraries have been developed for a while without this mentality, and so applying such an option project-wide would likely cause breakage. This means that there would have to be some kind of workaround that preserves the “flattening” behavior but scoped per library, and only for the libraries that don’t opt in to non-flattening.

Would such a feature be desirable, and if I can implement it without breaking existing projects and libraries, would there be the possibility to merge it upstream?

Hi Adam,

we are currently looking at making improvements to our build system that may well address your concerns. Please feel free to take a look at https://github.com/ARMmbed/mbed-os/tree/feature-cmake to see what is currently on going.

Regards
Anna

1 Like

FWIW, it is possible to partially fix this problem using the mbed-cmake build system. You still can’t name a header file the same as something in MBed OS, but you do have complete control over include paths within your own source code. So e.g. you could add only your top-level include directory to the include path, and then do

#include <system1/foo.h>
#include <system2/foo.h>

without any conflicts.