Hacker News new | ask | show | jobs
by saidinesh5 1248 days ago
> 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.

1 comments

> 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)"