In search of a good build system for C++

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

User avatar
raudorn
Posts: 351
Joined: Mon Jun 13, 2011 11:59 am UTC

In search of a good build system for C++

Postby raudorn » Thu May 03, 2018 9:53 am UTC

Lately I've been writing a lot of C++ code scattered across both existing and newly created projects and so far I find compiling and building things in C++ to be a check on the con side of a pro-con-analysis of C++. Does anyone have recommendations on how to build projects?

Here's an unordered list of things that are nice to have in a build system:
  • Automatic inclusion of new .cpp and .hpp (or .h) files into pool of compiled files
  • Makes #include statements just work
  • Works on most systems without having to install an outrageous amount of dependencies (for the build system anyway)
  • Makes inclusion of external libraries (outside the project folder) easy
  • Allows division of code into internal libraries for faster compilation (only recompile what changed)
  • If there is any boilerplate at all, makes it clear what is necessary
  • Effort to configure the build of a project scales with the amount of features used, not with the amount of code to compile, especially with nested folders

I have tried mostly cmake and scons so far. The latter feels like a version of the former that makes some things more convenient, but isn't all that different. cmake meanwhile is definitely a step up from writing Makefiles manually, but it's a far cry from things like Rust's crates. I feel like I could do anything I need with cmake, but it does not make things easy.
There are probably solutions for any problem I might encounter, but these do not feel like clean programming practices. For example, automatically including new code files requires writing some recursive globing-loop inside cmake's description language, which of course I didn't write myself and instead copy from other projects. If that is the best solution, why isn't this part of cmake itself?!

Tub
Posts: 373
Joined: Wed Jul 27, 2011 3:13 pm UTC

Re: In search of a good build system for C++

Postby Tub » Thu May 03, 2018 12:30 pm UTC

If your build system is as simple as "compile every single file in this directory into an executable", then a simple Makefile will do. See here, for example. This has minimal dependencies, but isn't easily portable to toolchains that don't use gcc/clang's command line syntax.

For example, automatically including new code files requires writing some recursive globing-loop inside cmake's description language, which of course I didn't write myself and instead copy from other projects. If that is the best solution, why isn't this part of cmake itself?!

file(GLOB_RECURSE ...) ?

CMake does not recommend using globs to enumerate files though, because it cannot detect added files automatically. You'll end up manually re-running cmake on every new file, or you'll waste time by running cmake on every compile. Globbing inside the makefile is faster and more reliable.

User avatar
raudorn
Posts: 351
Joined: Mon Jun 13, 2011 11:59 am UTC

Re: In search of a good build system for C++

Postby raudorn » Thu May 03, 2018 9:47 pm UTC

Tub wrote:If your build system is as simple as "compile every single file in this directory into an executable", then a simple Makefile will do. See here, for example. This has minimal dependencies, but isn't easily portable to toolchains that don't use gcc/clang's command line syntax.

For some small projects, yes. The main thing I'm currently working on requires more functionality however. I honestly don't really understand how it works, except that it uses cmake and needs a CMakeLists file in every subdirectory, which is a lot of duplicated code, but at least this allows splitting of the code into sort-of internal libraries.

Tub wrote:file(GLOB_RECURSE ...) ?

CMake does not recommend using globs to enumerate files though, because it cannot detect added files automatically. You'll end up manually re-running cmake on every new file, or you'll waste time by running cmake on every compile. Globbing inside the makefile is faster and more reliable.

Ah, yeah, that's what I meant. It's still necessary to run cmake again when new files are added, but at least the new files don't have to be registered in the CMakeLists files.

User avatar
Soupspoon
You have done something you shouldn't. Or are about to.
Posts: 3094
Joined: Thu Jan 28, 2016 7:00 pm UTC
Location: 53-1

Re: In search of a good build system for C++

Postby Soupspoon » Thu May 03, 2018 10:20 pm UTC

Can't you script something to autogenerate all the CMakeLists stuff for you? A shell-script (or a .bat¹, as I didn't see anything to narrow down what OS this was under, at first look at your posts), or a .pl or .py one, could go in there to interrogate all makeable files/etc in a directory and format them into the midst of a config, and bookended by the invariable stuff.

Or maybe your next compiled project could be to develop a utility/wizard/app to do this, if you're happier with just sticking with C++ rather than having to pick up a script dialect you're not currently familiar with… If you can't find one already made, maybe you could even fill a much needed development niche (if you've got time to 'support' other people with need for somethinf similar and yet with varying requirements.


Just an idea, maybe.a bit left-field, and not totally sure I picked up on all of your nuanced needs.


¹ Although it's a more awkward to use "FOR /D IN …" and "FOR /F IN …", with tokens and variable expansion modifiers you can do most of what you could do trivially in a (foo)sh shell.

User avatar
raudorn
Posts: 351
Joined: Mon Jun 13, 2011 11:59 am UTC

Re: In search of a good build system for C++

Postby raudorn » Fri May 04, 2018 10:36 am UTC

Soupspoon wrote:Can't you script something to autogenerate all the CMakeLists stuff for you?

In theory, sure, that's possible. A build system is "just" a layer wrapped around the compiler to make it a bit more convenient to tell the compiler what and how to compile. However I don't think cmake is missing any functionality I need. It's more that it is not as easy to use as I would like it to be. A build system is supposed to take some work off the developer's shoulder, not add to it.

User avatar
Link
Posts: 1331
Joined: Sat Mar 07, 2009 11:33 am UTC
Location: ᘝᓄᘈᖉᐣ
Contact:

Re: In search of a good build system for C++

Postby Link » Sun May 13, 2018 8:17 am UTC

Going by what I've read, if you're already comfortable with CMake, there's basically zero reason to switch to anything else. Personally, though, I still love the bog-standard Autotools (especially in combination with autogen.sh). Going through your list:

Automatic inclusion of new .cpp and .hpp (or .h) files into pool of compiled files
This one is a bit of a problem with Autotools because it's not at all obvious how new files should be compiled. A real project will typically have many binaries and libraries with complex interdependencies, and figuring out which source file belongs to which parts is a highly nontrivial task. This is not something Autotools does for you by default, but in my opinion also isn't something a build system should do. Even so, a few lines of m4 should cover simple cases; there may already be something in the Autoconf archive.

Makes #include statements just work
As long as you don't do outrageous stuff, sure.

Works on most systems without having to install an outrageous amount of dependencies (for the build system anyway)
Most *NIX-like systems already have them out of the box. There are lots of dependencies, but they're all small -- that's the UNIX philosophy at work. It's pretty easy to set up on most OSes, AFAIK.

Makes inclusion of external libraries (outside the project folder) easy
pkg-config!

Allows division of code into internal libraries for faster compilation (only recompile what changed)
Yup, out of the box.

If there is any boilerplate at all, makes it clear what is necessary
I'm not sure understand exactly what you mean by this, but this sounds like more of a task for a separate script or an IDE than it does for a build system. Tip for GCC users: -Wl,--as-needed tries to minimise the linking of unnecessary code.

Effort to configure the build of a project scales with the amount of features used, not with the amount of code to compile, especially with nested folders
Mostly true. Typically adding new source files requires adding them to the appropriate SOURCES directives in Makefile.am, and adding subdirectories requires adding a SUBDIRS directive to the parent Makefile.am and a new trivial Makefile.am to the subdir itself, but those are all one-time overhead. The actual operation time of autoconf and configure depends mostly on the complexity of configure.ac, which typically does not depend directly on the size of the source code.


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 2 guests