18

I have some projects that follows this dependency graph:

Executable
Main 
Libraries A, B, and C


Main //_Depends_A_B_C

A //_Depends_B

B

C //Depends_B

Does it make more sense for me to make a super project that uses add_subdirectory to put A, B, and C in global scope and link them all together?

Proj/

CMakeList.txt // Has add_subdirectory for each directory in b,a,c,Main order.

a/

b/

c/

Main/

Or should I go through the trouble of making a find_package solution for them.

Main/

A/   //Installed to system

B/   //Installed to system

C/   //Installed to system

These libraries are in development so it is nice to be able to treat them all as one project in my IDE, but I don't want to be misusing add_subdirectory to fit my specific dev tools.

Kevin
  • 16,549
  • 8
  • 60
  • 74
user514156
  • 630
  • 1
  • 7
  • 14
  • 1
    Both approaches work. The choice is up to you (that is, mostly subjective). As you already have notice, using `add_subdirectory` is simpler than `find_package`. If you want a list of all props and cons, such list would be a large one, so it is unsuitable for Stack Overflow. – Tsyvarev Jun 28 '16 at 16:52
  • A third possibility would be `ExternalProject_Add()`. Generally speaking when you setup your build environment, you should put some thought into the following three topics: 1. Dependecies / Coupling, 2. Deployment, 3. Teams. For some of the discussions about "the best CMake project structure" see [here](http://stackoverflow.com/questions/33443164), [here](http://stackoverflow.com/questions/31512485) or [here](http://stackoverflow.com/questions/33534115). – Florian Jun 28 '16 at 19:14
  • @Alexis: What do you mean? The blog in your link tells nothing about "super project". – Tsyvarev Oct 17 '20 at 22:44
  • It seems `add_subdirectory` is an anti-pattern and should be avoided for out-of-tree modules. `find_package()` is good pattern even though it requires to use custom `Find*.cmake` to indicate where is the module (because as OP said, he doesn't want to install the libs). I don't know myself tho.. I'm reading a lot to find the best practices for CMake. – Alexis Oct 18 '20 at 02:27
  • It's really not on topic, but I think you should consider as well `externalproject_add`. I think it's a much better alternative to `find_package` than `add_subdirectory`. – Black May 03 '21 at 17:00

1 Answers1

2

If the dependency is third-party, then you should use find_package. This allows someone to replace your dependencies with system-provided ones instead. This is important when authoring a library that might be included in a package manager, like vcpkg or a Linux distro's standard repositories.

If the dependency might be cross-compiled relative to your code (eg. it is a build-time tool or code generator like Bison), then you must use find_package. Only one toolchain may be active during a given CMake build.

If you store dependencies in your repository (either directly or as submodules), then a super-build setup using ExternalProject will likely be convenient. Your top-level project would consist of solely external project orchestration, and each sub-project would install to a local prefix, and look for packages in that same prefix. See CMAKE_INSTALL_PREFIX and CMAKE_PREFIX_PATH for more detail.

In any other case, prefer add_subdirectory.

Alex Reinking
  • 16,724
  • 5
  • 52
  • 86