Dynamically Changing Targets: A Complex building system generating CMakeLists build files and build types dynamically

I will describe my issue and then provide the code in a public github repository. Even though there is not much code, the structure etc. are also important, and I believe it was the best to do it this way.

I am working on ExaHyPE-2, the significant for you is that it is an engine that generates applications. It has a python code generator that writes source codes and then builds it, this means the python source code generator also generates CMakeLists.txt from templates and adds them to the build tree.

Currently, python code generator generates the applications and builds it with the command:
cmake <path/to/project/root/dir> && cmake <path/to/project/root/dir> && make <target_name>

The first cmake call is necessary for the new target to be visible, as well as overwriting the cached CMAKE_BUILD_TYPE. Even when the BUILD_TYPE is changed, the triggered reconfiguration does not create new targets. I tried to achieve this behavior by adding custom targets that are part of the ALL target that depend on the CMakeCache.txt etc. but to no avail. The second cmake call is needed for the changed CMAKE_BUILD_TYPE to generate the new targets.

My question is a one out of curiosity, as calling cmake twice does not hinder the functionality of the system or anything but is there a possible way to make cmake understand that the build type has changed and we might need new targets due to the new build type.

My minimal example has a library called a, and an application that can be generated as b. b.py generates the source code and required CMakefiles. To reproduce. It will currently only work on Linux. The default target the library is generated in is a debug target and the b.py generates a release application:

git clone https://github.com/ThrudPrimrose/cmake_generate_new_target.git
cd cmake_generate_new_target
mkdir build
cd build
make #Builds liba_Debug
cd src/b #Symlinks are copied over to the build directory in the original exahype-2 repo too
python b.py

[ 66%] Building CXX object build/src/b/CMakeFiles/b_Release.dir/b.cpp.o
[100%] Linking CXX executable b_Release
/usr/bin/ld: cannot find -la_Release: No such file or directory
collect2: error: ld returned 1 exit status

python b.py

[ 20%] Run custom command on CMakeCache change
[ 20%] Built target reconf
[ 40%] Building CXX object src/a/CMakeFiles/a_Release.dir/a.cpp.o
[ 60%] Linking CXX static library liba_Release.a
[ 60%] Built target a_Release
[ 80%] Building CXX object build/src/b/CMakeFiles/b_Release.dir/b.cpp.o
[100%] Linking CXX executable b_Release
[100%] Built target b_Release

The repository can be found here:

I don’t think I quite understand what is being attempted here. I get this error after running b.py:

CMake Error at XXX/build/GeneratedSubdirectory.cmake:2 (add_subdirectory):
  add_subdirectory not given a binary directory but the given source
  directory "XXX/build/src/b" is not a
  subdirectory of "XXX/src".  When
  specifying an out-of-tree source a binary directory must be explicitly
  specified.
Call Stack (most recent call first):
  CMakeLists.txt:45 (include)

I think you want to use the two-argument variant of add_subdirectory where you give the source and build directory explicitly.

I would debug with the Ninja generator and -d explain to see what might be up here.