Generator expressions in external projects.

Most external project commands support generator expressions. INSTALL_DIR isn’t used by CMake directly but instead used as placeholder in commands which support generator expressions. Documentation doesn’t mention and from experimental results it seems that using generator expressions inside INSTALL_DIR doesn’t work as CMake tries to validate the path without expanding generator expressions. In case of INSTALL_DIR workaround is not using <INSTALL_DIR> and specifying generator expression directly, but in case BINARY_DIR where the project gets built such workaround doesn’t work.

Is there a reason for not supporting generator expressions for external project directories? Am I using external projects incorrectly?

My motivation is that using “Visual Studio” generator executables get placed in directory that depends on Config (Release or Debug). I want to install the dlls from external project in the same directory so that development build can be run.

1 Like

I think that may be something that just hasn’t come up yet. Which error message are you getting?

As for a workaround, you may be able to use $(Configuration) which ends up letting MSBuild do the replacement (it only works for the VS generators though).

Error looks something like this. It happens during configuration.

CMake Error at C:/Program Files/CMake/share/cmake-3.17/Modules/ExternalProject.cmake:1713 (message):
  dir 'C:/Users/karlis/source/repos/cutter/build/$<CONFIG>' does not exist
  after file(MAKE_DIRECTORY)
Call Stack (most recent call first):
  C:/Program Files/CMake/share/cmake-3.17/Modules/ExternalProject.cmake:3223     (_ep_set_directories)
  cmake/BundledRadare2.cmake:29 (ExternalProject_Add)

At least during my first attempt I wasn’t able to repeat it on Linux. I wonder if it succeeds on Linux by actually creating directory with “$<>” symbols in the path.

Yes, on Linux it creates directory called $<CONFIG> later during build creates the corresponding directory with $<CONFIG> correctly substituted.

file(MAKE_DIRECTORY) is a configure-time action and does not support generator expressions. If you do file(GENERATE OUTPUT "dir/with/$<CONFIG>/.dummy" CONTENT ""), CMake will generate the directory that way (though you’ll be stuck with the .dummy placeholder files).

I ran into this same issue… switched to use and that directory can’t be made…(Windows doesn’t allow < and > in filenames). $(Configuration) almost works, but I’d really like to have it indirected into the generated .sln files.

cmake_all/CMakeLists.txt generates builds for several sub-projects within the same source tree. for $(Configuration)_out The sub-projects then get Debug_out, but only when the top-level is re-generated; I would like to work with the projects generated directly, and have them have $(Configuration) in their setup; otherwise when I build a subproject with Release it still goes to Debug_out. I tried like $$(Configuration) but then I get $Debug_out as the target (for example)… so even if worked, I’d want to pass that to the target projects and have it resolved when they are built.

I do get a $(Configuration)_out directory created which is empty - not sure why external project is even trying to make this directory, since the install part will handle creation of the directory anyway.

Actually - seems the install_prefix gets stuck with whatever the first build generated…