Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I wish we had a culture that expected every new C/C++ build system to handle a non-trivial project like Boost or Qt (and their dependencies, like ICU and OpenSSL) before it being pitched as the new best thing. It's trivial to make a build system that elegantly handles your own toy projects that follow your preferred style and structure. But the real world of C/C++ is a harsh place with a lot of variability.


This is wisdom right here. It's tragedy of the commons.

I find that the real problem is no one wants to properly learn how their build system works. I don't care if it's make, cmake or bazel -- whatever it is, you need to _learn_ it. I've worked with folks that have 20 years of experience, fantastic C/C++ developers, that look at a makefile and say "Ugh what is this complicated mess, can you do it in cmake or bazel or something" and expect a silver-bullet where-in the makefile build will somehow transform itself into a self-describing intuitive build system by virtue of some sort of hype-osmosis.


> I've worked with folks that have 20 years of experience that look at a makefile and say "Ugh what is this complicated mess, can you do it in cmake or bazel or something"

This is so true, it happened to me more than once.

A couple of projects ago, we had a complicated build process (7-8 manual build steps that depend on files generated from each other before) for an embedded system. I wrote a little makefile deleting all those 7-8 shell scripts and i was asked to re do it in cmake.. I was like wtf.. each clearly defined step in makefile would turn into multiple unreadable function calls in cmake.. why would anyone want to do that..

Not that Makefiles are perfect, but sometimes, the right tool for the job isn't the shiniest. Make does a job of being "good enough" for a lot of little tasks.


> each clearly defined step in makefile would turn into multiple unreadable function calls in cmake

Utter nonsense. For most projects CMake is far more readable and maintainable than Makefiles. There's a reason it's the only build system even close to being a de facto standard in the C++ world.

And yes, CMake is totally awful. But it's still slightly better than Make.

(Feel free to post the Makefile!)


> For most projects CMake is far more readable and maintainable than Makefiles

That's only true for pure C/C++ projects. (I haven't used cmake with other languages so i won't comment on that.). I was specifically talking about the project where there were 7-8 shell scripts to build each intermediate step's target.

When you have to call external commands to build your artifacts, you end up relying on:

add_custom_target()/add_custom_command()/execute_process()/etc..

Example from that Makefile:

    $(DISK_IMAGE): $(PARTITION_LAYOUT) $(BOOT_IMAGE) $(SYSTEM_IMAGE) $(HOME_IMAGE) 
        $(info "~~~~~ Creating disk image ~~~~~")
        $(eval PARTITION_LAYOUT_BOOT_START:=$(shell grep boot $(PARTITION_LAYOUT) | grep -oP 'start=\s*\K(\d+)'))
        $(eval PARTITION_LAYOUT_SYSTEM_START:=$(shell grep root $(PARTITION_LAYOUT) | grep -oP 'start=\s*\K(\d+)'))
        $(eval PARTITION_LAYOUT_HOME_START:=$(shell grep home $(PARTITION_LAYOUT) | grep -oP 'start=\s\*\K(\d+)'))
        dd status=none if=/dev/zero of=$(DISK_IMAGE) bs=1M count=2000
        sfdisk $(DISK_IMAGE) < $(PARTITION_LAYOUT)
        dd conv=notrunc if=$(BOOT_IMAGE) of=$(DISK_IMAGE) bs=$(BLOCK_SIZE) seek=$(PARTITION_LAYOUT_BOOT_START)
        dd conv=notrunc if=$(SYSTEM_IMAGE) of=$(DISK_IMAGE) bs=$(BLOCK_SIZE) seek=$(PARTITION_LAYOUT_SYSTEM_START)
        dd conv=notrunc if=$(HOME_IMAGE) of=$(DISK_IMAGE) bs=$(BLOCK_SIZE) seek=$(PARTITION_LAYOUT_HOME_START)
When you toss in other variables, cmake becomes a lot more verbose/less readable for these kind of use cases. Other steps in that Makefile were about generating, signing, verifying each of the partition images, fetching keys from the servers etc.. That whole Makefile was 500+ lines, and pretty sure in cmake it would have been lot longer.


> That's only true for pure C/C++ projects.

Ah I assumed this was primarily a C++ project given the context of the discussion. You're right it's not really the right tool if you're not doing a C++ project!

> Example from that Makefile

Honestly that looks like a typical fragile Makefile. Grepping all over the place. Regexes. Shelling out to `dd`. This sort of build system leads to constant fighting confusing error messages. It's a "works for me" build system.

I can see one bug and it's only 10 lines!

I think you can use Makefiles robustly - if you only use it for handling the build DAG, but apparently the temptation to use it as a general scripting system is too great for basically everyone.


Mhm. The nature of the task itself was to use several different command line tools to do various build steps.

Makefile was the only tool that felt "good enough" compared to those shell scripts. As for "works for me" problems, i directly packed up my ubuntu 14.04 rootfs for chroot and told my colleagues this was / will be the only supported build environment for this task. (docker wasn't that widespread there back then).

> I think you can use Makefiles robustly - if you only use it for handling the build DAG, but apparently the temptation to use it as a general scripting system is too great for basically everyone.

This is very true. it starts off with "Oh i can just use bash eval for this simple math" and ends with "Okay this makefile is too ugly.. might as well use a python script to handle this step". I kinda wanted to write a make tool that integrated better scripting language then. and variable checking.

Error messages were typically manageable when you sprinkle enough :"|| (echo "Error: You didn't do the right thing; exit -1)"


Like many C++ devs I hacked around in cmake for years, but not really understanding what I was doing or how to structure cmake projects. This was made worse as newer ways of doing things came into being.

If this sounds like you, do yourself a favor and go through these slides (or watch the talk they came from):

https://github.com/boostcon/cppnow_presentations_2017/blob/m...

It really clarified things for me, but also avoids going too much into detail. You will definitely need more info as you go along, but you can look those things up in the docs. This presentation does a good job at showing the core essentials that you can build your knowledge on later.


> whatever it is, you need to _learn_ it.

The problem in my experience is you invest time learning build system A, then a year later build system B comes out, and not only do you need to relearn a bunch of stuff again, often build system B does some of the stuff of system A but not all of it, plus it does new stuff that you've never encountered before. Then this cycle repeats, endlessly, and every new team you join has adopted the newest build system.

Granted some ecosystems are worse than others here. in the JavaScript world it went something like: make/grunt/bower, gulp/webpack, esbuild, parcel, vite, rollup, and on and on it goes.

Even in the conservative Java ecosystem we've been through maven, ant, groovy/gradle...

Most of these tools offer incremental improvements for a huge learning cost. It's a nightmare.


> Most of these tools offer incremental improvements for a huge learning cost. It's a nightmare.

Huge learning cost and even more huge interoperability cost. "Oh you need to cross compile your C++ project to that architecture? this dependency uses that build system and you need to build those libraries separately and make sure your build system can use that then"


ant is still being used in the Java space? That would be new to me. Gradle is just enforced by google for Android deployment for some arbitary reason.

For 90% of use-cases nothing beats the simplicity of Maven.


Who says you have to learn tool B just because it was released? Just ignore it and keep using A.


Because "every new team you join has adopted the newest build system".

Just like in the last 2-3 years, every single new team I've joined is using kubernetes from day 1. Cargo culting is a huge force.


The problem is not the build system, it's projects that are seemingly enjoying complexity.


I think there's a good reason for people moving to Rust, aside from the merits of each language, the tooling for using packages is just so much better in Rust.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: