DEV Community

Ryan Westlund
Ryan Westlund

Posted on • Updated on

What I hate about the C ecosystem


I don't know very much about C. The most I've done in it is a few educational projects, like implementing the basic functionality of cat, rm, and a chat server using Unix sockets. But what I hate about the C ecosystem is build systems. They're absurdly complicated and I can never get them to work.

Okay, so we have our compiler. It might be Clang or GCC or whatever. I actually think the C compilers are pretty neat; they're sometimes able to suggest what you mean when you misspell a name and warn about dangerous stuff even if it doesn't strictly break the rules. But we also need make, which is a separate tool, and virtually a language unto itself. Okay, well, that's tolerable. Except BSD make and GNU make are different. And then there's the whole GNU autotools toolchain, not to mention cmake, which I've had to deal with for compiling ROXTerm...

When I submitted my patch to GTK to fix a GObject Introspection annotation, I wanted to compile GTK after my change first, just to make 100% sure it would build, even though I was 99% sure it couldn't have broken the build process. I spent about 12 hours trying to do so before giving up. The quest to compile GTK led me through installing both meson and ninja, hunting down numerous dependencies manually after each failed compilation informed me of another one, googling countless cryptic error messages and reading old mailing list archives, trying on an Ubuntu system after giving up on the FreeBSD one, and finally deciding I'd just submit the merge request and hope it worked (it did).

I've never seen a language other than C that even has any need for "build systems". With Go, you just go build it, end of story. With... hm. Okay, most of the other languages I know are interpreted. Haskell doesn't exactly have build systems per se, but it's package management experience is also a nightmare as far as I'm concerned. So maybe I'm being unfair. You tell me - do C build systems suck, or is Go a rare gem in this regard?

Discussion (1)

phlash profile image
Phil Ashby

I'll bite/rant with you :)

Firstly, C or more specifically the compiler is independent of any build tooling you (or the creator of whatever you are fighting with) choose. IDEs tend to blur this separation, especially fat opaque ones (hello Visual Studio, Eclipse, Netbeans, ...). Some compilers (IME CodeWarrior) include poorly documented, surprising build voodoo but they probably shouldn't, some (MSVC) like to spew pre-compiled headers around to make things faster, which has been pointless for years with good disk caches / SSDs.

The same applies to many other compiled languages (Java, {whatever}/.NET, etc.) although some come with strong recommendations for build tooling - this is to help with this:

The problem is humans can choose what to inflict upon each other for build tools, and they are creative, so we have a multitude of conflicting tools, such as SCONS, GNU autotools, CMake, GNU make, build.bat, ANT (seen it done), PMake, MSbuild, ...ouch.

Other languages come with built in build systems or helper tools (go build, dotnet build, cargo, etc.), which can be equally unhelpful if you need to debug them as you now need to learn a whole new ecosystem for each language.. YMMV :)

So what to do?

Choose a well managed distribution (I choose Debian), and rely on their expertise, common tooling and testing to build things from source. I can build any package in the repository with the same commands: and reliably reproduce them :)

For my own work, I usually write a single short Makefile, as I am unlikely to need the huge flexibility of more complex tooling, even with a cross-language project (JNA anyone?). One syntax to learn, efficient and transparent IMO.

I imagine this sort of pain is also one of the drivers for moving to rust as a systems programming language, everyone has to use cargo!