I could use some help with properly setting up my project in CMake. The main platform is Visual Studio on Windows (but it would be nice to have something portable that works on other systems, esp. Linux + Ninja + gcc). What I have right now is an existing project, let’s call it A, that comprises two shared libraries and an executable. It uses CMake as its build system – it works like a charm, no issues there.
Now I want to set up another project, named B, which uses A (or, to be more specific, shared libraries created by building and installing A). Both A and B have some external dependencies, but all of that is handled by find_package, so it isn’t a problem. What is the problem, is the fact that B uses a different (older) version of VS compared to A. This is because some 3rd party dependencies force the use of an older version of Visual Studio. At the same time, A uses C++17/C++20 internally, so that pretty much requires the latest and greatest versions of MSVC/clang. A has been designed to be usable from older platforms, so the mismatch isn’t really an issue.
I would like to set up B in such way that the generated VS solution can reference A and rebuild (and reinstall) it, if necessary (i.e. A source has been modified). Because the toolchains are different, I don’t think I can use FetchContent here, despite A being CMake-based – which realistically leaves the ExternalProject route (assuming I want to stay in the CMake land).
I’ve run some basic experiments on using ExternalProject_Add to handle A as a dependency in B and it looks promising so far. But here is where I’ve run into some issues. I’ve been reading Craig Scott’s book on CMake and it describes superbuilds as one of the recommended ways of handling this situation: I did some googling and found this example in Chromium codebase: https://chromium.googlesource.com/external/github.com/grpc/grpc/+/HEAD/examples/cpp/helloworld/cmake_externalproject/CMakeLists.txt
What it amounts to, is basically writing a script that pulls in both A and B via ExternalProject_Add. B then could be simply written to find_package A. While this works fine for our automated builds, the developer experience leaves something to be desired, as the generated solution seems to only contain references to A and B with some CMake rules on how to configure/build/install each project, while I would prefer to have B set up more like a traditional VS project (with includes and sources in the project, neatly grouped using filters) and keep A as an external reference. The only way I could achieve something like that was by using ExternalProject_Add to add A directly in the CMake script for B, but that I think would force me to mix the targets defined by ExternalProject and the ones I define in B, which seems to be strongly discouraged by Craig.
Is there some clever solution I’ve missed? Is there a way to use the superbuild script AND have the typical VS project for B in the same solution working nicely? Should I just forget about superbuild in this case?