Subject: Re: [boost] [cmake] Minimum viable cmakeification for Boost
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2017-06-20 21:56:38
> I'll ask again: do you have any reference to those statements? The
> official cmake docs seem to disagree about this specific case.
The cmake docs are updated on a git pull request basis by volunteers as
and when someone feels they need to be updated. They are, in general,
woefully out of date. And as I mentioned here before, Stephen never
finished the cmake3 documentation effort he began due to changes in
personal circumstance (returning home to Ireland).
> Why should the root cmake be responsible for configuring a specific sub
> module. This is asking for cluttering everything into one single entity
> in a (almost) totally unrelated place. Why not keep it local to where it
> should be used.
I'll repeat myself yet again, but to be honest it'll be for the last
time as I really don't care about this enough to spend more time
repeating myself. I have other stuff to be doing than repeating myself
(specifically, Outcome v2).
In the cmake I mocked up we are separating concerns: "how to build this
library" from "how to configure this library". It is like the intended
difference between the SConstruct and SConscript files in scons: one
file says what needs to be built and how they relate declaratively, the
other file sets flags, optimisation, settings according to the target
system etc imperatively.
In exactly the same way as with scons, the non-root CMakeLists are the
declarative structure describing a build graph. The rootmost CMakeLists
are the imperative commands transforming some subset of that build graph
into a build according to local conditions.
That's the way you ought to be ideally speaking writing your cmake3. I
don't know what else I can explain here. As Peter mentioned, this is 101
elementary build system theory here. It's nothing cmake specific, though
because of how variable scopes usually begin with CMakeLists.txt, it
does strongly encourage the imperative logic to go into the rootmost
layer rather than somewhere more logically placed. But it is what it is.
> One concrete example: I have networking layer which supports different
> transports, say tcp, libfabric, MPI and infiniband verbs. The user of my
> library doesn't really care about which one is used, so ideally, I would
> give him a compiled version of my library with the internal settings I
> believe are best for him. In that case, my network layer module would be
> configured with one of those options. Naturally, I would think, those
> options are defined within this very sub project. The root project
> really doesn't care, nor do I want that this implementation detail leaks
> into the users CMakeLists.txt.
> Would you consider that bad practice to begin with? How would you solve
It depends on if you ever expect unknown third parties to want to do
custom builds of your codebase. If you don't, your approach is fine, and
it's easier. If you do, then you need to separate the declarative stuff
from the imperative stuff. Then unknown third parties can reuse your
declarative stuff, and skip or ignore your imperative stuff as they are
doing a custom build.
> There are tons of other use cases very similar to that. Having
> everything clobbering up in the root Cmakelists.txt doesn't sound
> appealing to me.
You obviously don't place ALL your imperative logic in the very rootmost
CMakeLists. There are natural root points where build config markedly
changes when you go up a directory level. That's where you locate the
imperative logic. If higher level cmake wants to ignore your imperative
logic, it skips over the directory with the CMakeLists with the
imperative logic and adds the subdirectories of the inner directories
directly, thus bringing in only the declarative parts only. So you
"reach in" two directory levels to skip the imperative logic.
Does this make more sense now?
-- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/