Feedback on documentation for installing headers with target_sources(FILE_SET)

I was looking at the documentation for installing a directory, and I noticed the note at the top of the section:

Note If installing header files, consider using file sets defined by target_sources(FILE_SET) instead. File sets associate headers with a target and they install as part of the target.

However there’s not a whole lot of examples of how to use this, and there are a few aspects of the existing documentation or occasional lack thereof that were a bit confusing to me or caused points of pain.

Commonly used shorthand is not immediately apparent

Let’s consider the signature for target_sources under the File Sets section

target_sources(<target>
  [<INTERFACE|PUBLIC|PRIVATE>
   [FILE_SET <set> [TYPE <type>] [BASE_DIRS <dirs>...] [FILES <files>...]]...
  ]...)

I was expecting that I’d need to do something like
target_sources(my_target PUBLIC FILE_SET my_headers TYPE HEADERS ...), but I’d seen examples in the forum like, these two posts: (1) (2), that put FILE_SET HEADERS right next to each other. This was confusing because it was inconsistent with the documentation. That is, it was really easy to miss the note a lot further down in the documentation for the type parameter

As a special case, if the name of the file set is one of the types, the type does not need to be specified and the TYPE <type> arguments can be omitted. For all other file set names, TYPE is required.

I think it would be helpful to have an example here toward the beginning of the documentation section that sets this precedent. It could even reference the existing tutorials:
target_sources(MathFunctions PUBLIC FILE_SET HEADERS FILES MathFunctions.h)

Exporting a library with file sets requires additional parameters to install targets

Another pain point was that it doesn’t mention that when specifying the library targets for exporting (see the exporting targets section of the importing and exporting guide), you also need to specify FILE_SET HEADERS. Continuing with the MathFunctions example, this would look like:

install(TARGETS MathFunctions
        EXPORT MathFunctionsTargets
        # ...
        FILE_SET HEADERS
)

I was able to figure this out reasonably quickly by searching the error message I got and finding this github issue, but I think making this a note in the documentation for target_sources would be nice

What happened to FILES_MATCHING PATTERN?

This was a neat parameter from install(DIRECTORY) because it allowed you to glob all of your header files without creating a variable in the global namespace. file(GLOB_RECURSE) is also discouraged in the official documentation. Is there a better alternative than just to manually specify every single header file?

What exactly does BASE_DIRS do?

This is still unclear to me. The documentation for the parameter describes preconditions on the arguments passed to it, but it doesn’t really say what it’s used for. The only thing I could find was at the very bottom of the page.

INCLUDE_DIRECTORIES If the TYPE is HEADERS or CXX_MODULE_HEADER_UNITS, and the scope of the file set is PRIVATE or PUBLIC, all of the BASE_DIRS of the file set are wrapped in $<BUILD_INTERFACE> and appended to this property.

This is also kind of unclear about what this means, but I’m wondering if this is the only place BASE_DIRS is used, or if there’s a more well-defined description for what this parameter does?

@josiest thanks. This part of the forum is for feedback on the forum itself, or presentation issues on cmake.org. For feedback on CMake’s documentation proper, please use the CMake Issue Tracker.

1 Like