1

(you may be shocked by the setup of the CMake design of our project. I know that it was not done in a good way, but unfortunately the efforts to change a running system are quite less. So the scope of this question is not how to change the project structure.)

I have a project with a top-level CMakeLists.txt. In this file the project version is specified. The project contains different products selectable by a define. From command line everything works as expected.

The problem comes when using Qt Creator. If I load the top level CMakeLists.txt and configure the cmake environment I can set a product (the configuration is stored in the *.user file next to the CMakeLists.txt). If I now want to work on a different product I have to change the settings, re-run cmake and have to compile everything again. So for this setup it is not possible to work on different products at the same time (for example: checking if the changes work as expected for every product).

To solve this I've create additional CMakeLists.txt (in different folders) which include the top-level CMakeLists.txt and in this additional files I set up the defines for each product. Now I can work on different products using Qt Creator at the same time. With this setting the project version is not updated in CMakeCache. The manual states, that it uses the project information from the top-level CMakeLists.txt, which is now the Qt Creator 'wrapper'. If there is no project defined cmake creates an artificial one called 'Project'.

Now my question: Is there a way to propagate the real project to the artificial top-level CMakeLists.txt?

Maro
  • 43
  • 6
  • You may try to set CACHE INTERNAL variable instead of the normal one. So after `add_subdirectory` is processed, the value of the variable will correspond to the subproject's setting. – Tsyvarev Jul 12 '21 at 10:42
  • You mean, I can overwrite the root project version with the current project version? In the Qt Creator CMakeLists.txt after `add_subdirectory` I should add a call `set(CMAKE_PROJECT_VERSION ${PROJECT_VERSION})`. Sorry, I'm not that used to cmake. – Maro Jul 26 '21 at 05:15
  • 1
    Oh, so you want to change `CMAKE_PROJECT_VERSION` variable... not sure, whether CMake intend it to be writable after the `project()` call. You could try to set the variable via `set(CMAKE_PROJECT_VERSION ${PROJECT_VERSION} CACHE INTERNAL "")` in your root project when you select a product. That way the variable will be propagated to the upper level. – Tsyvarev Jul 26 '21 at 06:19
  • Actually, I don't understand how do you want to "work on different products at the same time". Switching to the other product requires reconfiguration (re-running `cmake`) in any case. Could you add some **code** to your question post for illustrate your case? A code is always better than a *description* of it. – Tsyvarev Jul 26 '21 at 06:22
  • Yes this is the reason why I want to have multiple top level CMakeLists.txt defining one product. Then the cmake project can be located on different folders. I think on comand line you just run `cmake [options] ` in different folders and you will have different configured cmake projects in these folders. If you then change code you can call directly `cmake --build --target install` from source folder. – Maro Jul 26 '21 at 11:34
  • This behaviour I want to achive using Qt Creator. Only disadvantage is that I have to use a CMakeLists.txt with all the necessary defines, because Qt creator stores these information in a *.user file next to the CMakeLists.txt (not allowing having Qt Creator set up correctly for all products at the same time). I got it working with: `get_directory_property(SUB_PROJECT_VERSION DIRECTORY ../ DEFINITION PROJECT_VERSION)` `set(CMAKE_PROJECT_VERSION ${SUB_PROJECT_VERSION} CACHE STATIC "" FORCE)` from here: https://stackoverflow.com/questions/6891447/cmake-variable-scope-add-subdirectory – Maro Jul 26 '21 at 11:44

1 Answers1

1

Together with the comment from @Tsyvarev and this post I could build this:

project(TOP_LEVEL_PROJECT VERSION 0.0.0.0 DESCRIPTION "foobar" LANGUAGES C CXX)
...
add_subdirectory(${PROJECT_ROOT})
get_directory_property(SUB_PROJECT_VERSION DIRECTORY ${PROJECT_ROOT} DEFINITION PROJECT_VERSION)
set(CMAKE_PROJECT_VERSION ${SUB_PROJECT_VERSION} CACHE STATIC "" FORCE)
# repeat for CMAKE_PROJECT_VERSION_MAJOR/_MINOR/_PATCH/_TWEAK

Now I see that in the CMakeCache.txt the entries are updated as I want it.

Maro
  • 43
  • 6