[HN Gopher] You can handle The Diamond with CMake
___________________________________________________________________
You can handle The Diamond with CMake
Author : todsacerdoti
Score : 32 points
Date : 2021-03-27 14:23 UTC (8 hours ago)
(HTM) web link (beza1e1.tuxen.de)
(TXT) w3m dump (beza1e1.tuxen.de)
| wheybags wrote:
| This is a really weird way of doing things. You can just
| add_subdirectory from the top level all the way down as intended.
| Then if you only want to build A, you just do "make A" instead of
| parameterless "make". Am I missing something that makes this
| approach bad? IMO this is the idiomatic way to do it.
| BeeOnRope wrote:
| How would you lay out the directory structure for the diamond
| dependency shape discussed in the post? Specifically, where
| would "base" live?
| sjburt wrote:
| root/ base/ a/ b/
|
| As long as root has a CMakeLists.txt and includes base, a,
| and b, cmake will figure it out. After the build tree has
| been built with cmake, you can even run make from the
| build/root/a/ directory and base/ and a/ will be built. The
| author, for some reason, does not want a cmakelists.txt in
| root/ and wants to run cmake from a or b alone so they have
| to use a more convoluted approach.
| qznc wrote:
| One reason against the CMakeLists.txt at the root: When you
| generate a Visual Studio "solution", every target becomes a
| "project". At work this results in a few hundred projects
| and VS gets slow. Someone build a Python script to trim it
| down. This is treating symptoms instead of root causes and
| adds accidental complexity.
|
| Of course, the root CMake also needs to parse all sub
| directories which requires time. However, this has not been
| a big problem in practice so far. Only on the "annoying"
| level.
| ihnorton wrote:
| Many (if not most) libraries don't work correctly with
| add_subdirectory.
| cheesedoodle wrote:
| I really appreciate the advice from Daniel Pfeifer [0] where you
| treat all your build-tree sub-projects as out of tree
| dependencies, by overriding the `find_package` macro. This way,
| you can just find project dependencies using the `find_package`
| as if you were referring to something pre-built. Save a lot of
| hassle. macro(find_package) if(NOT
| "${ARG0}" IN_LIST as_subproject) _find_package(${ARGV})
| endif() endmacro()
|
| [0] C++Now 2017: Daniel Pfeifer "Effective CMake"
| https://www.youtube.com/watch?v=bsXLMQ6WgIk&vl=en slides:
| https://github.com/boostcon/cppnow_presentations_2017/blob/m...
| xaedes wrote:
| I like to have a meta project with the root CMakeLists.txt.
|
| In this meta project I either just add_subdirectory all necessary
| components manually, or I use Findxyz.cmake scripts for each
| module with that "header guard". They check if target is already
| defined, if not they add_subdirectory the required component.
|
| For each component (i.e. cmake project) I can then just
| find_package (module mode) all dependencies and target_link them.
| Like any other dependency.
|
| For consistency reasons I like to put cmake find modules for all
| external (installed) library as well and then let the find
| modules use find_package in config mode for installed libraries,
| and add_subdirectory for my own components, or for projects I
| want to include with source and build along with the other stuff.
| This way I have one point where I can control the source of all
| dependencies.
|
| Another way would be to just install all components as libraries
| in the system with proper cmake config files for find_package in
| config mode. I dont like to clutter my system with all kinds of
| application specific libraries, so that is not the way for me.
| hedora wrote:
| Other than the fact that it generates VC++ projects, I haven't
| been able to find any advantage of cmake over plain make. (I
| think auto downloading stuff during the build is a bug, not a
| feature. I'd also rather never use find_package. Many people
| disagree. That's OK.)
|
| Are there any reasonable raw make based solutions for VC++?
| pjc50 wrote:
| > raw make based solutions for VC++?
|
| You can certainly run regular Make in Windows, either natively
| or in one of the unix-ish environments, and have it call
| CL.EXE?
|
| Having it emit VS/MSbuild projects is more of a problem, since
| MSBuild itself is rather like Make with different terminology
| and a strange pre-existing library.
| banachtarski wrote:
| You probably feel the way you do because:
|
| - you don't target different platforms
|
| - you don't target different compilers
|
| - you don't cross compile and need to maintain multiple
| toolchains
|
| - you like juggling different compiler flags
|
| - you work on small codebases
|
| - you haven't bothered to sit down with cmake for the few hours
| needed to understand why a cmake project might be more
| maintainable than a make one
| hedora wrote:
| 100% of your assumptions are wrong.
|
| I have years of experience with cmake, and all the other
| things you mentioned. I work in environments where the
| correctness of the binaries is important, and cmake fights
| that at every possible step. The documentation is poorly
| organized and overly verbose. 99% of the details in the docs
| are irrelevant 99% of the time, and the important details are
| missing or relegated to a non-discoverable page elsewhere on
| their site.
| OnlyOneCannolo wrote:
| I agree with your opinion of CMake.
|
| Most of my career has been in non-mainstream software
| development. There's always a ton of rare, unique, or
| broken stuff that I have no control over. In many
| situations, adding an extra layer via a generator (such as
| CMake) adds more work than convenience.
|
| I've also found CMake's documentation to be useless most of
| the time.
|
| By the time I track down and fix all the issues, I might as
| well have just written a Makefile (or whatever obscure,
| ancient build tool they use).
| banachtarski wrote:
| Please substantiate the claim about how "cmake fights that
| at every possible step." There's so much hyperbole in your
| statement that it really does seem like you've spent "years
| of experience with cmake" futzing around.
| hedora wrote:
| 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.
| eqvinox wrote:
| I don't know what exactly the poster was dealing with,
| but I've been trying to get reproducible builds out of
| cmake and it was a serious pain due to cmake insisting on
| using absolute file paths.
|
| (Ed.: Also I agree the cmake docs are atrocious.)
| banachtarski wrote:
| > due to cmake insisting on using absolute file paths
|
| ????
| eqvinox wrote:
| I can't tell you whether this is/was innate cmake
| behavior or whether something was wrong with the specific
| project, but cmake passed all source file names to the
| compiler using the full file system path rather than a
| relative path.
|
| This is a serious (though slowly becoming a non-issue)
| problem since compilers encode source file names into the
| output binary's debug information and strings (__FILE__).
| The "-fdebug-prefix-map=old=new" GCC option and its
| cousins are what is slowly making this a non-issue, but
| those are a relatively recent addition.
| Galanwe wrote:
| Though I agree with your points, and do not like CMake
| either (I tend to much prefer autotools or plain make)
| there has been a time when I saw the use of it: maintaining
| a software with developers both on Windows using VS and
| Linux using make.
| paul_manias wrote:
| Come on... make is a perfectly good choice (and for me,
| preferable) for any project that is small to medium sized.
| However if you get to a stage where you have to compile for
| 3 or more platforms and need to account for different
| compiler versions & systems that people may be using,
| 'make' quickly becomes hell to use. The possible build
| combinations just get out of hand, and you can't if-then-
| else your way out of every situation. Ultimately you get to
| a point where makefiles can't deal with the growing
| complexity of a big project.
|
| That is where CMake really shines - it takes the headache
| out of managing complex, sprawling builds once you get it
| setup, and you won't have to keep tweaking the config to
| manage every other dev's system. I grant that the
| documentation is not perfect and there is a significant
| time investment in getting everything 'just so', but the
| long-term time savings make up for that completely in my
| experience.
| eqvinox wrote:
| Pending one caveat:
|
| - I do not target nor care about Windows systems (which is in
| agreement with the GP I guess - cmake may be useful as to get
| project files for VC covered.)
|
| I agree with the GP post and:
|
| - I do target different platforms (Linux, BSDs and Solaris)
|
| - I do target different compilers (GCC, clang and ICC)
|
| - I do cross compile and maintain multiple toolchains (I have
| 16 GCCs and 8 clangs on my box)
|
| - I do juggle different compiler flags
|
| - I work on a codebase with 1.24M lines
|
| - I have experienced the pain of working with dependencies we
| need that use cmake.
|
| The only thing cmake has given me is having to learn another
| way to do all the same things I already know how to do for 10
| other build systems.
|
| NB: I do not agree with the GP post that make by itself is a
| good tool. In most cases, the best tool is simply the most
| popular one, which - sadly, because it's a pretty bad tool -
| is autotools for my use cases. I know how to deal with it, my
| co-developers know how to deal with it, and my users know how
| to deal with it. Even if I learn 10 other build systems, that
| still leaves my co-developers and users hanging.
|
| If we disregard this and go purely with technical merits, my
| personal opinion (= I don't care to argue for this, feel free
| to ignore) for the best tool becomes Meson.
|
| (I'm aware this post is a bit condescending, but I feel that
| this is an appropriate response to the parent post's equal
| condescension. ["You probably feel the way you do because:" -
| really? What gives you that "insight"?])
| hedora wrote:
| GP here: I'm also ambivalent about autotools. It integrates
| in well with distro package managers. It's ridiculously
| complicated, but at least it handles all the corner cases
| of cross-compilation, etc.
| eqvinox wrote:
| It's definitely showing its age & quite shitty in a lot
| of places, but no argument can be made that it isn't the
| "standard" :(. If it were showing up to the party right
| now as a new entry, it'd be laughed out of the room...
|
| [libtool isn't even actively maintained! Like, seriously,
| I'd guess >90% of packages on any Linux/BSD systems use
| it in their build and it's essentially abandonware!]
| theamk wrote:
| > A problem you might not notice initially is that CMake has no
| namespacing. This means it gets littered with pre- or postfixes
| like ${PROJECT_NAME}
|
| It is 2021, and we still have C++ developers program in a
| language which lacks namespaces, types and relies heavily on
| generated variable names.
|
| How did we end up there?
| randrews wrote:
| The article-title-rewriting thing has actually made this sound
| _more_ clickbaity. The original title prepends the word "how"
| which is much better.
| qznc wrote:
| (author here)
|
| Initially my draft had the title "CMake and the Diamond". When
| the article was finished, I decided to make it more clickbaity
| because I'm not Paul Graham or Scott Alexander. Rumors are that
| words like "How to" and "You" make it look more interesting. I
| weakened it intentionally by adding the "can" because I don't
| claim that this approach is the one best solution.
| randrews wrote:
| I think the article title is fine, I'm saying that the HN
| thing that removes numbers and "how to" and so on (to prevent
| clickbait titles) has done the opposite here. :)
___________________________________________________________________
(page generated 2021-03-27 23:01 UTC)