Skip to content(if available)orjump to list(if available)

Parallel ./configure

Parallel ./configure

101 comments

·April 25, 2025

iforgotpassword

The other issue is that people seem to just copy configure/autotools scripts over from older or other projects because either they are lazy or don't understand them enough to do it themselves. The result is that even with relatively modern code bases that only target something like x86, arm and maybe mips and only gcc/clang, you still get checks for the size of an int, or which header is needed for printf, or whether long long exists.... And then the entire code base never checks the generated macros in a single place, uses int64_t and never checks for stint.h in the configure script...

rollcat

This.

Simple projects: just use plain C. This is dwm, the window manager that spawned a thousand forks. No ./configure in sight: <https://git.suckless.org/dwm/files.html>

If you run into platform-specific stuff, just write a ./configure in simple and plain shell: <https://git.suckless.org/utmp/file/configure.html>. Even if you keep adding more stuff, it shouldn't take more than 100ms.

If you're doing something really complex (like say, writing a compiler), take the approach from Plan 9 / Go. Make a conditionally included header file that takes care of platform differences for you. Check the $GOARCH/u.h files here:

<https://go.googlesource.com/go/+/refs/heads/release-branch.g...>

(There are also some simple OS-specific checks: <https://go.googlesource.com/go/+/refs/heads/release-branch.g...>)

This is the reference Go compiler; it can target any platform, from any host (modulo CGO); later versions are also self-hosting and reproducible.

IshKebab

I don't think it's fair to say "because they are lazy or don't understand". Who would want to understand that mess? It isn't a virtue.

A fairer criticism would be that they have no sense to use a more sane build system. CMake is a mess but even that is faaaaar saner than autotools, and probably more popular at this point.

epcoa

> either they are lazy or don't understand them enough to do it themselves.

Meh, I used to keep printed copies of autotools manuals. I sympathize with all of these people and acknowledge they are likely the sane ones.

rbanffy

It’s always wise to be specific about the sizes you want for your variables. You don’t want your ancient 64-bit code to act differently on your grandkids 128-bit laptops. Unless, of course, you want to let the compiler decide whether to leverage higher precision types that become available after you retire.

codys

I did something like the system described in this article a few years back. [1]

Instead of splitting the "configure" and "make" steps though, I chose to instead fold much of the "configure" step into the "make".

To clarify, this article describes a system where `./configure` runs a bunch of compilations in parallel, then `make` does stuff depending on those compilations.

If one is willing to restrict what the configure can detect/do to writing to header files (rather than affecting variables examined/used in a Makefile), then instead one can have `./configure` generate a `Makefile` (or in my case, a ninja file), and then have the "run the compiler to see what defines to set" and "run compiler to build the executable" can be run in a single `make` or `ninja` invocation.

The simple way here results in _almost_ the same behavior: all the "configure"-like stuff running and then all the "build" stuff running. But if one is a bit more careful/clever and doesn't depend on the entire "config.h" for every "<real source>.c" compilation, then one can start to interleave the work perceived as "configuration" with that seen as "build". (I did not get that fancy)

[1]: https://github.com/codyps/cninja/tree/master/config_h

tavianator

Nice! I used to do something similar, don't remember exactly why I had to switch but the two step process did become necessary at some point.

Just from a quick peek at that repo, nowadays you can write

#if __has_attribute(cold)

and avoid the configure test entirely. Probably wasn't a thing 10 years ago though :)

o11c

The problem is that the various `__has_foo` aren't actually reliable in practice - they don't tell you if the attribute, builtin, include, etc. actually works the way it's supposed to without bugs, or if it includes a particular feature (accepts a new optional argument, or allows new values for an existing argument, etc.).

codys

yep. C's really come a long way with the special operators for checking if attributes exist, if builtins exist, if headers exist, etc.

Covers a very large part of what is needed, making fewer and fewer things need to end up in configure scripts. I think most of what's left is checking for items (types, functions) existence and their shape, as you were doing :). I can dream about getting a nice special operator to check for fields/functions, would let us remove even more from configure time, but I suspect we won't because that requires type resolution and none of the existing special operators do that.

mikepurvis

You still need a configure step for the "where are my deps" part of it, though both autotools and CMake would be way faster if all they were doing was finding, and not any testing.

throwaway81523

GNU Parallel seems like another convenient approach.

creatonez

Noticed an easter egg in this article. The text below "I'm sorry, but in the year 2025, this is ridiculous:" is animated entirely without Javascript or .gif files. It's pure CSS.

This is how it was done: https://github.com/tavianator/tavianator.com/blob/cf0e4ef26d...

o11c

Unfortunately it forgets to HTML-escape the <wchar.h> etc.

tavianator

Whoops! Forgot to do that when I switched from a ``` block to raw html

epistasis

I've spent a fair amount of time over the past decades to make autotools work on my projects, and I've never felt like it was a good use of time.

It's likely that C will continue to be used by everyone for decades to come, but I know that I'll personally never start a new project in C again.

I'm still glad that there's some sort of push to make autotools suck less for legacy projects.

eqvinox

To extend on sibling comments:

autoconf is in no way, shape or form an "official" build system associated with C. It is a GNU creation and certainly popular, but not to a "monopoly" degree, and it's share is declining. (plain make & meson & cmake being popular alternatives)

monkeyelite

You can use make without configure. If needed, you can also write your own configure instead of using auto tools.

Creating a make file is about 10 lines and is the lowest friction for me to get programming of any environment. Familiarity is part of that.

viraptor

It's a bit of a balance once you get bigger dependencies. A generic autoconf is annoying to write, but rarely an issue when packaging for a distro. Most issues I've had to fix in nixpkgs were for custom builds unfortunately.

But if you don't plan to distribute things widely (or have no deps).. Whatever, just do what works for you.

edoceo

Write your own configure? For an internal project, where much is under domain control, sure. But for the 1000s of projects trying to multi-plarform and/or support flavours/versions - oh gosh.

monkeyelite

It depends on how much platform specific stuff you are trying to use. Also in 2025 most packages are tailored for the operating system by packagers - not the original authors.

Autotools is going to check every config from the past 50 years.

tidwall

I've stopped using autotools for new projects. Just a Makefile, and the -j flag for concurrency.

psyclobe

cmake ftw

JCWasmx86

Or meson is a serious alternative to cmake (Even better than cmake imho)

torarnv

CMake also does sequential configuration AFAIK. Is there any work to improve on that somewhere?

OskarS

Meson and cmake in my experience are both MUCH faster though. It’s much less of an issue with these systems than with autotools.

aldanor

You mean cargo build

yjftsjthsd-h

... can cargo build things that aren't rust? If yes, that's really cool. If no, then it's not really in the same problem domain.

malkia

cmake uses configure, or configure-like too!

ahartmetz

Same concept, but completely different implementation.

fmajid

And on macOS, the notarization checks for all the conftest binaries generated by configure add even more latency. Apple reneged on their former promise to give an opt-out for this.

gorgoiler

On the topic* of having 24 cores and wanting to put them to work: when I were a lad the promise was that pure functional programming would trivially allow for parallel execution of functions. Has this future ever materialized in a modern language / runtime?

  x = 2 + 2
  y = 2 * 2
  z = f(x, y)
  print(z)
…where x and y evaluate in parallel without me having to do anything. Clojure, perhaps?

*And superficially off the topic of this thread, but possibly not.

gdwatson

Superscalar processors (which include all mainstream ones these days) do this within a single core, provided there are no data dependencies between the assignment statements. They have multiple arithmetic logic units, and they can start a second operation while the first is executing.

But yeah, I agree that we were promised a lot more automatic multithreading than we got. History has proven that we should be wary of any promises that depend on a Sufficiently Smart Compiler.

lazide

Eh, in this case not splitting them up to compute them in parallel is the smartest thing to do. Locking overhead alone is going to dwarf every other cost involved in that computation.

gdwatson

Yeah, I think the dream was more like, “The compiler looks at a map or filter operation and figures out whether it’s worth the overhead to parallelize it automatically.” And that turns out to be pretty hard, with potentially painful (and nondeterministic!) consequences for failure.

Maybe it would have been easier if CPU performance didn’t end up outstripping memory performance so much, or if cache coherency between cores weren’t so difficult.

snackbroken

Bend[1] and Vine[1] are two experimental programming languages that take similar approaches to automatically parallelizing programs; interaction nets[3]. IIUC, they basically turn the whole program into one big dependency graph, then the runtime figures out what can run in parallel and distributes the work to however many threads you can throw at it. It's also my understanding that they are currently both quite slow, which makes sense as the focus has been on making `write embarrassingly parallelizable program -> get highly parallelized execution` work at all until recently. Time will tell if they can manage enough optimizations that the approach enables you to get reasonably performing parallel functional programs 'for free'.

[1] https://github.com/HigherOrderCO/Bend [2] https://github.com/VineLang/vine [3] https://en.wikipedia.org/wiki/Interaction_nets

chubot

That looks more like a SIMD problem than a multi-core problem

You want bigger units of work for multiple cores, otherwise the coordination overhead will outweigh the work the application is doing

I think the Erlang runtime is probably the best use of functional programming and multiple cores. Since Erlang processes are shared nothing, I think they will scale to 64 or 128 cores just fine

Whereas the GC will be a bottleneck in most languages with shared memory ... you will stop scaling before using all your cores

But I don't think Erlang is as fine-grained as your example ...

Some related threads:

https://news.ycombinator.com/item?id=40130079

https://news.ycombinator.com/item?id=31176264

AFAIU Erlang is not that fast an interpreter; I thought the Pony Language was doing something similar (shared nothing?) with compiled code, but I haven't heard about it in awhile

juped

There's some sharing used to avoid heavy copies, though GC runs at the process level. The implementation is tilted towards copying between isolated heaps over sharing, but it's also had performance work done over the years. (In fact, if I really want to cause a global GC pause bottleneck in Erlang, I can abuse persistent_term to do this.)

inejge

> …where x and y evaluate in parallel without me having to do anything.

I understand that yours is a very simple example, but a) such things are already parallelized even on a single thread thanks to all the internal CPU parallelism, b) one should always be mindful of Amdahl's law, c) truly parallel solutions to various problems tend to be structurally different from serial ones in unpredictable ways, so there's no single transformation, not even a single family of transformations.

fweimer

There have been experimental parallel graph reduction machines. Excel has a parallel evaluator these days.

Oddly enough, functional programming seems to be a poor fit for this because the fanout tends to be fairly low: individual operations have few inputs, and single-linked lists and trees are more common than arrays.

null

[deleted]

speed_spread

I believe it's not the language preventing it but the nature of parallel computing. The overhead of splitting up things and then reuniting them again is high enough to make trivial cases not worth it. OTOH we now have pretty good compiler autovectorization which does a lot of parallel magic if you set things right. But it's not handled at the language level either.

rbanffy

I get the impression configure not only runs sequentially, but incrementally, where previous results can change the results of tests run later. Were it just sequential, running multiple tests as separate processes would be relatively simple.

Also, you shouldn’t need to run ./configure every time you run make.

fishgoesblub

Very nice! I always get annoyed when my fancy 16 thread CPU is left barely used as one thread is burning away with the rest sitting and waiting. Bookmarking this for later to play around with whatever projects I use that still use configure.

Also, I was surprised when the animated text at the top of the article wasn't a gif, but actual text. So cool!

SuperV1234

CMake also needs this, badly...

torarnv

Agreed! The CMake Xcode generator is extremely slow because not only is it running the configure tests sequentially, but it generates a new Xcode project for each of them.

null

[deleted]

redleader55

Why do we need to even run most of the things in ./configure? Why not just have a file in /etc which is updated when you install various packages which ./configure can read to learn various stats about the environment? Obviously it will still allow setting various things with parameters and create a Makefile, but much faster.

o11c

Keep in mind that the build intentionally depends on environment variables, people often install non-packaged dependencies in bad ways, and cross-compiling is a thing, so it's not that simple.

wolfgang42

Some relevant discussion/pointers to other notes on this sort of proposal can be found here: https://utcc.utoronto.ca/~cks/space/blog/sysadmin/AutoconfVa...

(The conclusion I distilled out of reading that at the time, I think, was that this is actually sort of happening, but slowly, and autoconf is likely to stick around for a while, if only as a compatibility layer during the transition.)

pabs3

Not every OS is going to have such a file, and you also don't know if it matches the actual system ./configure runs on.

amelius

What I'd like to see is a configure with guarantees that if the configure succeeds, then the build will succeed too.