I’m struggling a bit with ExternalProject and multi-config generators (MSVC).
How do I “tell” ExternalProject_Add() whether I need a debug or a release build depending on the currently selected build type ?
The external project has nmake Makefiles.
In addition to a -DCMAKE_BUILD_TYPE:STRING=$<CONFIG>, you’ll likely also want BUILD_DIR something/$<CONFIG> STAMP_DIR/something/$<CONFIG> or the like to avoid rebuilds on every configuration switch. The install tree may also get very confused if the contents of files overlap in ways that are configuration-sensitive (e.g., not changing library names).
I would have expected the ExternalProject to follow the same config used to build the main project. Is that not happening for you, or are you trying to force a particular config different to the main build? When the main project is using a multi-config generator, the ExternalProject module explicitly passes the config to use as --config $<CONFIG> on the cmake --build ... command line it constructs.
I created a small example project (not using nmake, but the ninja single-config generator):
It seems to be mostly working.
I am seeing one problem, after the initial cmake run, not all build types are working:
build> /opt/cmake-3.31.7-linux-x86_64/bin/cmake -G "Ninja Multi-Config" ..
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: /home/alex/src/tests/extproj2/build
build> /opt/cmake-3.31.7-linux-x86_64/bin/cmake --build . --config Debug
ninja: error: '3rdparty/Install/Release/lib/libfoo.so', needed by 'Debug/footest', missing and no known rule to make it
But I can build “Release”:
~/src/tests/extproj2/build> /opt/cmake-3.31.7-linux-x86_64/bin/cmake --build . --config Release
[5/10] Performing configure step for 'EP_libfoo'
Not searching for unused variables given on the command line.
-- The C compiler identification is GNU 14.2.1
-- The CXX compiler identification is GNU 14.2.1
...
[6/10] Performing build step for 'EP_libfoo'
[1/2] Building CXX object CMakeFiles/foo.dir/Release/foo.cpp.o
[2/2] Linking CXX shared library Release/libfoo.so
[7/10] Performing install step for 'EP_libfoo'
[0/1] Install the project...
-- Install configuration: "Release"
-- Installing: /home/alex/src/tests/extproj2/build/3rdparty/Install/Release/lib/libfoo.so
-- Installing: /home/alex/src/tests/extproj2/build/3rdparty/Install/Release/include/foo/foo.h
[10/10] Linking CXX executable Release/footest
Trying to build Debug afterwards works:
build> /opt/cmake-3.31.7-linux-x86_64/bin/cmake --build . --config Debug
[5/10] Performing configure step for 'EP_libfoo'
Not searching for unused variables given on the command line.
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: /home/alex/src/tests/extproj2/build/ExternalProjects/src/EP_libfoo-build
[6/10] Performing build step for 'EP_libfoo'
[1/2] Building CXX object CMakeFiles/foo.dir/Debug/foo.cpp.o
[2/2] Linking CXX shared library Debug/libfoo.so
[7/10] Performing install step for 'EP_libfoo'
[0/1] Install the project...
-- Install configuration: "Debug"
-- Installing: /home/alex/src/tests/extproj2/build/3rdparty/Install/Debug/lib/libfoo.so
-- Installing: /home/alex/src/tests/extproj2/build/3rdparty/Install/Debug/include/foo/foo.h
[10/10] Linking CXX executable Debug/footest
Why does it complain in Debug mode “no known rule to make it”, but after building in Release mode, it works ?
Why do I have to set the IMPORTED_LOCATION target property, I thought it is good enough to set the _Release, _Debug and _RelWithDebInfo properties ?