Top project/ master project : vocabulary

Just like Design patterns gives us vocabulary to identify the same thing,pattern. I would like to request a similar thing for cmake, and request that cmake itself provide an implementation.

Thanks to FetchContent “other” libraries can now be source consumed, which is great. This requires off course some discipline of the library writers, they no longer should assume they are in charge of everything, and the first thing they need to know if they are in charge or not is to determine if they are the top/master project, yes or no.

If have already seen 2 mechanisms to detect that:

  1. compare CMAKE_CURRENT_SOURCE_DIR and CMAKE_SOURCE_DIR
  2. compare CMAKE_PROJECT_NAME and PROJECT_NAME

In order to avoid that everyone is writing his/her own version of this boilerplate, it would be nice that cmake provides a function that can be called and gives this as an outcome. That way all use the same implementation, and it has a fixed name (vocabulary).

What do you think ?

kind regards,
Lieven

the first thing they need to know if they are in charge or not is to determine if they are the top/master project, yes or no.

There is also the PARENT_DIRECTORY directory property that is an empty string at the real top-level.

get_property(parent DIRECTORY PROPERTY PARENT_DIRECTORY)
if(NOT parent)
  # I am in charge.
endif()

so that is a third way.

Which makes me case more firm :wink:

there should be some is_top_project() function.

I agree, it should be easy to do the right thing.

If have already seen 2 mechanisms to detect that:

  1. compare CMAKE_CURRENT_SOURCE_DIR and CMAKE_SOURCE_DIR
  2. compare CMAKE_PROJECT_NAME and PROJECT_NAME

I always use option 1. The second option technically isn’t guaranteed, since a project name isn’t required to be unique.

There is also the PARENT_DIRECTORY directory property that is an empty string at the real top-level.

get_property(parent DIRECTORY PROPERTY PARENT_DIRECTORY)
if(NOT parent)
  # I am in charge.
endif()

A while back, I hit some sort of bug where this or something like it wasn’t reliable. I don’t recall the exact scenario and I can’t be certain that it wasn’t an error in the project at the time, but for this reason, I don’t use this approach myself.

there should be some is_top_project() function.

Unfortunately, CMake doesn’t support returning values from functions, so you’d have to provide a variable name to set. That means you would require two separate lines if using this approach. Comparing if(CMAKE_SOURCE_DIR and CMAKE_CURRENT_SOURCE_DIR) directly is about the most concise way to express it given the current language limitations. I agree it would be nice if we had a better alternative. Perhaps the project() command could set/update a variable like CMAKE_PROJECT_IS_TOP_LEVEL, but this would be new functionality and projects would have to do cmake_minimum_required(VERSION X.Y) to ensure it was supported.

well it could be similar like this snippet :

get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(isMultiConfig)

endif()

(just took this as an example, I don’t suggest it should be a global property or whatsoever, just as a style example)

and indeed it would be a new function or variable. And code that wants to support older versions, will need to continue to do the old thing, or require a certain minimum version.
But that is the same with every new thing that gets added, like in the last couple of years.

create an issue for it : https://gitlab.kitware.com/cmake/cmake/issues/20310