Tutorial Step4 documentation error

Am I correct in saying that:

     Note
     VendorLib is an INTERFACE library, meaning it has no build requirements (because it has already been built). All of its properties should also be interface properties.

and

 target_link_directories(MyApp PRIVATE Vendor/lib)
 target_include_directories(MyApp PRIVATE Vendor/include)

are contradictory? The TODO examples show INTERFACE and not PRIVATE and PRIVATE does not work in cmake --build build

I’m new at this so I’m only asking.

It doesn’t look contradictory. The starting (the one which uses target_*() commands on MyApp) is one where the consuming project interacts with the files on disk directly: it doesn’t treat the pre-built libVendor.a as a logical unit (library with usage requirements), but “decomposes” it into the individual parts (binary, include dirs, link dirs, …). It thus sets all those components individually directly on MyApp.

The goal state is one where we tell CMake about the existence of libVendor.a and its usage requirements: we register it as a target CMake knows about and can handle as a first-class item. We then need to set up this target accordingly, which means we’ll be modifying the properties of (the new CMake target) VendorLib, not of MyApp.

I am confused. Are you saying that the target_* commands can be PRIVATE and INTERFACE?

My question arose because the example in the tutorial shows target_* PRIVATE, which doesn’t work, and the actual function must use INTERFACE, so why have an example which doesn’t agree with the tutorial? Shouldn’t the example agree with the tutorial?

When configuring MyApp, which is an executable, it makes no sense to use any scope other than PRIVATE: you want the settings to apply when building MyApp itself, and that’s what PRIVATE means.

When setting up properties for the new target VendorLib which is an interface library, you instead want those settings to apply to whoever consumes (links against) VendorLib, not to the build of VendorLib itself (since it’s an interface library, it doesn’t even have a build step/process). The scope which means “apply to those who consume me” is INTERFACE.

So, the starting point does all the setup by calling target_*(MyApp PRIVATE ...). After the introduction of the VendorLib interface library target, you will want to set up most of the properties on that instead of on MyApp, using target_*(VendorLib INTERFACE ...).

The scopes and related concepts are described in more detail in the CMake buildsystem documentation.