Is it possible to customize the include path of a file?

Assume I have a directory structure like

Libs/
    Foo/
        File.h
        File.cpp
        CMakeLists.txt
    Bar/
        File2.h
        File2.cpp
        CMakeLists.txt

I want the include paths for files to be Foo/File.h and Bar/File2.h. However, if I do

target_include_directories(Foo ..)

then not only am I breaking the mental model of CMake by traversing upwards from a CMakeLists.txt, but I now also enabled including files in Bar and other targets in Libs even if I didn’t add a target dependency on them to Foo.

However, if I do

target_include_directories(Foo .)

then now the include is

#include "File.h"

which loses context as to what target the file is part of.

We have been working around this by using a directory structure of

Foo/
    include/Foo/
        Baz/
            Baz.h
        File.h
    Baz/
        Baz.cpp
    File.cpp
    CMakeLists.txt

which produces the desired include paths, but particularly for targets with verbose names that are deeper in the directory tree, this has pushed us over the Windows path length limit in several cases. I’d like to outright disable the path length limit, but key, external tool maintainers are dragging their feet fixing the dinosaur path length limit in their tools.

Is there a way to customize the include path (e.g. prepend it with something) of these files without actually changing the directory structure on disk?

While the standard does not have anything to say about how header lookup works, just about everything actually works on filepaths. The closest you could probably get is to copy the headers into the desired layout in the build tree. However, note that compiler warnings and such will drop you into this copy and not the original if you do any followup edits.

You could create symlinks in the build tree?

If all of your build platforms support them, sure.

1 Like

Would it work to do

target_include_directories(Libs ..)

when working with the assumed directory structure?

That would set the -I path to ..../Libs and then your #includes would be

#include "Foo/File.h"
#include "Bar/File2.h"

I guess it would work.