| So, assume that you need byte-for-byte identical upstream dependencies, and also assume you want to run in a modern CI environment. In make, you build a docker with a line like: RUN tar -C opt xvf /…/foo-1.2.3.tgz
RUN <build the thing if needed> And a few lines like this in make: INC += $(wildcard /opt/foo-*)/include
LIBS += -L… This generalizes elegantly to subdirectories. (See “Recursive Make Considered Harmful” for the right way to do it), and (crucially!) it won’t build if you don’t have the build environment set up correctly. It also lets you prevent the CI build container from talking to the internet, so outages of upstream server infrastructure, or package-manager-du-jour serving bitcoin miners can’t directly break production binaries. It also generalizes to building in other people’s operating systems, etc. With cmake, you need to read the documentation for find_foo, which invariably has a different calling convention than find_bar (if it exists at all), and it will try to look places it should not for the library. Adding a library this way takes hours. Also, the docker + make approach works well with languages other than c/c++; cmake does not, unless cmake happens to include built-in support for the language in question. |