Maverik
Maverik

Reputation: 2398

CMake - Visual Studio project dependencies

In few words

My question is: Is there a way for generating a visual studio solutions that contains a project, for which I'm writing the CMake, and another project, for which the CMake is already available?

I was thinking about using add_subdirectory, but I'm not sure this is the best solution and the meaning of the parameter binary_dir is not really clear to me.

More in details

I have a Visual Studio project (B) which depends on another one (A). I've written the CMakeLists for A and I'm able of generating the VS project and compiling it.

I've written a CMakeLists for B. I'm able to configure the VS project for B in such a way that it can access the headers and the libraries of A. Everything compiles.

A
- CMakeLists.txt
- src
  - *.cpp

B 
- CMakeLists.txt
- src
  - *.cpp

Build
- Build_A
- Build_B

However when I change something in A, from the B project (that's possible because with visual studio I can access the headers of A from the project B), and I try to compile, A is not compiled.

The project B compiles only B.

I was able to improve the situation by using add_subdirectory. In the CMakeLists of B I included the following line:

add_subdirectory(PATH_TO_A  A)

However with this solutions there is a duplication of the compilation files of A. They are generated in the out-of-source build directory BUILD_A when I compile from the project A; and they are generated in the out-of-source build directory BUILD_B\A when I compile from the project B.

What's the best practice for including the A project in the solution generated from the CMakeLists of B and avoid duplication of compilation files?

P.S. If possible I would like to avoid the need of recompiling everything twice. That is, If I have compiled A and I need to compile B for the first time I would like to avoid the need of recompiling A.

Upvotes: 0

Views: 1794

Answers (1)

ComicSansMS
ComicSansMS

Reputation: 54589

In principle using add_subdirectory is a good way to solve this.

A CMake project that can be compiled on its own can also be compiled as a subproject, if it follows a few rules. First of all, any change to the global state will of course also affect all other projects being built from the same root. Aggressive changes to the global build environment are likely to disturb other projects and should be avoided.

Additionally, a project that is being pulled in like this must not assume that its CMakeLists file is the root of the build. For instance, the CMAKE_BINARY_DIR variable always points to the top-level binary directory, while the PROJECT_BINARY_DIR points to the binary directory of the most recent project. A library that always assumes it's being built as a top-level binary may use those two interchangeably. A library that can be built both on its own or as a sub-project must be aware of the difference.

Note that add_subdirectory introduces a tight coupling between the projects and only works well if both involved projects behave accordingly.

A more loosely coupled alternative would be to include the dependency as an ExternalProject, but from what you wrote in the question (project should automatically recompile if source of the dependency changes), add_subdirectory seems the better match for you.

Upvotes: 3

Related Questions