8

I'm developing or maintaining a free software project Foo which uses CMake for a build system, as well as source control (e.g. Mercurial or Git), with the repository being available online.

Now, this project depends on another project, Bar - say, it uses include files that this other project provides. Bar exists independently, and is also FOSS and available from a public source-control repository.

Now, CMake has a mechanism for downloading, configuring and building such sub-projects: ExternalProject. However, I could also make Bar be a sub-repository of the Foo source repository, so that it is checked out together with Foo, and CMake can treat the composition of checked-out files and folders as though it was just one file hierarchy.

Would you recommend one approach over the other, generally? If not, what are the considerations for choosing one option over the other?

einpoklum
  • 2,752

2 Answers2

1

Vendoring the other project can be a suitable stopgap measure in the absence of a suitable dependency management tool. In particular, operating in a SCM level can be appropriate if the other project is not a stable, versioned library. Vendoring or mono-repo style projects can be quite beneficial

  • to manage internal dependencies that are developed together,
  • when an external project does not provide suitable packages,
  • when an external project changes too rapidly so that you effectively have to maintain a snapshot,
  • or when an external project needs other modifications.

In most other cases using available dependency management tools is much easier. There is the slight caveat that your builds are now dependent on external systems and that the dependency management tool might not be particularly good so that it ends up causing more problems than it solves. But CMake specifically – despite its numerous flaws – is pretty good at avoiding outright incompatibility. OTOH you can always whip up a simple shell or Python script that downloads and compiles the dependency, if portability is not an issue.

I'd also like to point out that sub-repositories have problems. E.g. a git submodule requires extra steps during checkout of the main project, and can have confusing semantics.

amon
  • 135,795
0

A third option to consider is actually "neither".

CMake has a subsystem, if you will, of package registration and location through installed configuration .cmake files. A lot of these are bundled with CMake itself, but you can set things up so that other packages generate and install their own .cmake configuration files, in paths which your dependent package will search. When this is the case, the dependent package just needs to find_package(foo) in the CMakeLists.txt, and it is "not its problem" where foo comes from (it can also constrain the version if necessary).

Of course, this makes the whole thing less "turn-key", since the dependent package could well fail without you having built and installed the dependencies somewhere visible. On the other hand, this is quite the flexible solution, and fits very well when you need to override versions etc.

einpoklum
  • 2,752