Boost logo

Boost :

Subject: Re: [boost] [ot] choosing a build system
From: Daniel Krikun (krikun.daniel_at_[hidden])
Date: 2012-05-15 15:46:49


I almost agree. When it comes to build system it is oftentimes better to be
more verbose and less elegant, because it is easier for the
user to maintain the build system code. And also, being less abstract, more
low-level is often desirable, as users do want to control various
platform-specific details of the build process. But there are also time
they are not! So I guess, there should be some sound abstraction level.

Also, I need to notice, being meta-build system has its disatvantages:
1. Requires extra step. This matters, because you need to remember
arguments tools, manage files, env. vars etc.
2. The meta-build system could not do more than a build system. See, you
can add fancy pre- and post- build rules to visual studio, but the logic of
how this rules are invoked are determined by the build system, not the
meta-build one.
3. Synchronization between the two might be annoying, for example,
regenerating Visual Studio solution, while it is opened in IDE;
understanding build system files are temporaries and should not be checked
in the source control and so on.

On the other hand, as somebody mentioned, good IDE should be interoperable
w/ any reasonable build-system, however, in practice this is oftentimes not
the case, so meta-build comes handy.

On Sat, May 12, 2012 at 6:56 AM, Dave Abrahams <dave_at_[hidden]> wrote:

>
> on Thu May 10 2012, Beren Minor <beren.minor+boost-AT-gmail.com> wrote:
>
> > Hi,
> >
> > My 2 cents regarding build systems as I've recently had to write a
> > build framework using CMake and as I use Boost.Build for personal
> > projects.
> >
> > I think Boost.Build and CMake are at a totally different level of
> > abstraction: CMake is low-level when Boost.Build is high-level. For
> > comparison with other build systems, Make, SCons are at the same level
> > as CMake. Premake is probably closer to Boost.Build (I don't know
> > enough others but there's not a lot being as high-level as BBv2).
>
> One of the problems people have with Boost.Build is that its high-level
> abstractions make it hard to control. There's so much going on between
> the code you write in your Jamfile and the actual command-lines that
> come out the other end, that it can be hard to know how to get the
> effect you want. If you need to do something specific for a given
> platform or compiler, you can't use a simple if/then statement based on
> some variable; you have to use a creatively-defined declarative
> language, and hope that the Boost.Build engine makes the choices you
> intend. I was a major participant in the design of that language, and
> in principle I think a declarative approach is ideal, but I now accept
> that the language we have doesn't match up well with the way that most
> users of the build system think, and that the high level of abstraction
> is not a net win.
>
> Parts of Boost.Build are an elegant design, no doubt. When Troy and
> Doug started talking up CMake to me, I kept pushing them to implement
> more of the abstractions in Boost.Build. But I've come to see that many
> of them aren't needed. Boost is a pretty good test case for complexity,
> and the CMake files for building boost portably
> (https://github.com/ryppl/boost-zero/tree/master/cmake) are not
> especially more complicated than its Jamfiles. But there's an order of
> magnitude more code in Boost.Build than there is in Ryppl's CMake
> support (https://github.com/ryppl/ryppl/tree/develop/cmake/Modules).
>
> > Of course SCons and CMake still have a major advantage over Make
> > because of their portability. But they offer a very little abstraction
> > over simple Make. Surely, there are some built-in rules to easily
> > create shared/static libraries or executables, but you still have to
> > define a lot of things manually. As an example, I quickly realized
> > that CMake is simply unable to create both shared and static version
> > of a library if you don't explicitly write the two rules to build
> > them.
>
> You mean, in a single build run?
>
> This is exactly the sort of situation where I think the abstraction
> capabilities you're wishing for are a net loss. It's not that much
> better to write
>
> lib foo : a.cpp b.cpp : : <link>static <link>shared ;
>
> (or is it <link>static/shared? I forget. And that's part of the
> problem)
>
> than it is to write
>
> set(sources a.cpp b.cpp)
> add_library(foo STATIC ${sources})
> add_library(foo SHARED ${sources})
>
> and the latter one matches up really well with what users understand.
> Furthermore, anyone who wants to build a library both ways with less
> boilerplate can write a simple function that does it.
>
> > For comparison, with Boost.Build, creating a library is as simple as
> writing:
> > lib foo : bar.c ;
> >
> > Then, depending in which context the library is used, BBv2 will create
> > shared or static or both versions of the library.
> > You don't have to care about the details, you'll have automatic
> > resolution of what is required to satisfy the build request, based on
> > the build condition you asked for.
>
> ...until it surprises you, as in
> https://trac.lvk.cs.msu.su/boost.build/wiki/AlternativeSelection
> Sometimes it's better to be a little more verbose and a little less
> automatic.
>
> > The abstraction level of Boost.Build is also very visible when you
> > start working on multiple compiler and/or multiple build variants. As
> > long as you don't need fancy compiler flags (and I think most projects
> > shouldn't play with fancy compiler flags) you can trust Boost.Build to
> > abstract all the details of the compiler flags and to offer you the
> > possibility to build everything you want, at once.
> >
> > With CMake and others, as comparison, you are only able to build one
> > variant at a time, and by default everything will be build in
> > conflicting way between build variants (build once in release mode and
> > once in debug mode, and you'll overwrite the previous build output).
>
> Meh; you just use different build directories. This is another one of
> those advantages of Boost.Build that cost more than they deliver, IMO.
> It means that every Boost.Build target is actually a meta-target
> representing one or more real targets, which complexity makes the whole
> system harder to understand and control... and, especially, harder to
> extend.
>
> > As said, you can use different build folders for different variants,
> > but that's much less easy to use and not very maintainable unless you
> > maintain a wrapper around the build system that does this for you.
>
> The advantage of maintaining a thin wrapper over the build system, if
> you need this kind of thing regularly, is that it's easy to get in
> underneath this layer and work with the build system directly: to
> experiment, extend, whatever. And at that level, you're just dealing
> with a single target and build variant. In the case of Boost.Build,
> there's no way to separate anything from the possibility of multiple
> variants, compilers, etc. In the end, most users of the build system
> don't need to do multiple builds at once anyway, so they never see the
> wrapper and never even have to deal with that incremental increase in
> complexity.
>
> > I like very much Boost.Build, and I was quite disappointed to hear
> > that there's a plan to move Boost to CMake. Boost is the main user of
> > Boost.Build and I'm a little bit afraid of seeing it disappear, or
> > being less and less unsupported. Even if I perfectly understand the
> > reason of this change: Boost.Build suffers from lack of documentation
> > and lack of popularity, whereas CMake is very well documented and
> > widely used, it leaves me a bitter taste in mouth.
>
> I don't know that the change will happen, but I hope very much that it
> will. I'm sorry for the bitter taste and for the hurt feelings of those
> who have invested so much in Boost.Build. However, my priority has to
> be on what's best for Boost's mission as a vehicle for C++ libraries.
>
> > From a personal point of view, Boost.Build (even if not perfect as it
> > is) does what a build system should do: abstract the user all the
> > detail on how the objects will be built and let him only care about
> > the high-level objects and their relations.
>
> The problem with that approach is that when something breaks, you
> usually end up working backwards from the actual command-lines you need
> the system to issue, and if the connection between the build description
> files and those command-lines is too distant, it can be hard to make the
> leap.
>
> > CMake and others are "old-generation" build systems, which may be used
> > as building blocks to achieve this goal.
>
> I think you're not giving CMake enough credit. It has been evolving
> quite quickly over the past few years. Its programming language may be
> old and crusty, but it's expressive enough to get the job done. Most
> importantly, it hits a "sweet spot" between abstract and direct that
> makes it practical and accessible.
>
> --
> Dave Abrahams
> BoostPro Computing
> http://www.boostpro.com
>
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>

-- 
Daniel Krikun

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk