Live data from Hacker News

Makefiles – Best Practices

danyspin97.org

111–120 of 127 posts

Re: Makefiles – Best Practices

#111

A particularly tricky task with GNU make is automatically adding target dependencies on header files and handling updates to them (gcc's -M and -MMD switches). It would be great if the article explained those best practices, too.

Here's all you need to track header file dependencies. Basically, when compiling a .cpp file to generate a .o file, a corresponding .deps file is also generated. And at make startup, we include all the .deps files we find in the bin (output) directory, if there's one.

$(BIN)/%.cpp.o: %.cpp

     $(CXX)  -c $(CXXFLAGS) "$
-include $(shell test -d $(BIN) && find $(BIN) -name "*.deps")

Re: Makefiles – Best Practices

#112
post #72
post #66

Earlier quoted context omitted.

I doubt most people even know that there are different versions. (I didn't!)

It's pretty common knowledge that there are differences from the GNU package set and linux package sets. I've been exposed to this multiple times: from downloading GNU packages using Homebrew on OSX, downloading different packages on Android, the variety of options available to ArchLinux users, etc. Anyone with basic Linux knowledge should be well aware of this. From a minimum of following tutorials and having the ba…

I don't agree that "basic Linux knowledge" requires knowing which commands have different versions. You can be intimately familiar with the Linux kernel and never step outside of the GNU environment.

I've never used OSX, and have no desire to compile things on my phone.

And I know that there are non-GNU versions of some tools, like grep, but whenever I've attempted to use them, I find them lacking some key feature that I always use. I can't be bothered to learn the entire set of GNU-improved tools, since I'm always just going to be using the GNU version anyway.

Re: Makefiles – Best Practices

#113

CFLAGS := ${CFLAGS} CFLAGS += -ansi -std=99 What's the point of the first line? Why not just: CFLAGS += -ansi -std=99

Speaking of, why both -ansi and -std=99 [ sic [1]]? [1] should be -std=c99

I've used these comments[1] as source for writing the CFLAGS. Did I misunderstood?

[1] https://stackoverflow.com/a/2193647

Re: Makefiles – Best Practices

#114
post #62

> Using the assignment operator = will instead override CC and LDD values from the environment; it means that we choose the default compiler and it cannot be changed without editing the Makefile. People can use `make CC=clang` to override assignments. That's a pretty common use.

Came here to say this. The "strength" of user specified variables depends on where they come from: the environment is weaker than those specified as command line arguments - which can lead to confusion.

Re: Makefiles – Best Practices

#115
post #19
post #16

Earlier quoted context omitted.

Make is simple.. it gets me started. I can do multiple targets with dependencies and incremental compilation.. Sure, you should be careful of scaling it far. BUT, please enlighten me on a sane high-level build system? cmake, bazel and the like all seems to rely on unintuitive macros. And let's not talk about auto tools :) What other mainstream build system will get you started quickly without unintuitive macros. (I w…

What's more simple than "add_executable(foo bar.cpp)"? It's concise, cross-platform and hides all the boilerplate for you. Sure, everything in CMake is not super intuitive, but I've led workshops were people got the hang of it pretty quickly for simple to advanced cases (including multiple targets and some scripting). Keep it simple, most of the time, you don't need the advanced features at all! Can't say the same fo…

Something like:

include "rules.mk"

foo: bar.cpp

But if the syntax for cmake was more sane, I would like it a lot more... Why does cmake use a DSL, and let me define targets as first class objects..

Re: Makefiles – Best Practices

#116

Earlier quoted context omitted.

Or just use Rust. :3 Cargo handles makes with very simple TOML scripts, and it's the more modern language, to boot.

I've been planning to, but unfortunately it still lacks 128 bit float and decimal types, which I need.

You may be interested in this crate which adds decimal types https://crates.io/crates/rust_decimal. Here is another that I have not used but appears to add a f128 type https://crates.io/crates/f128.

Re: Makefiles – Best Practices

#117
post #4

I recently decided it was time to get a better understanding of how makefiles work, and after reading a few tutorials, ended up just reading the manual. It's long, but it's very, very well written (a good example of one of the Gnu projects biggest strengths), to the point where just starting at the top and reading gives an almost tutorial-like effect. Just read the manual!

Can you humor a dumb question and tell me how you got the manual in your terminal? I'm on Debian, and when I `man make`, I just get a typical GNU CLI util manpage that's five paragraphs of intro and a line-by-line explanation of each command line option. Same for `info make`.

Re: Makefiles – Best Practices

#118
post #25

Earlier quoted context omitted.

FWIW I also read the GNU Make manual, and based some code for automatic deps off a profoundly ugly example it had. Then later people on HN showed me a better/simpler way to do it. https://news.ycombinator.com/item?id=15060149 https://www.gnu.org/software/make/manual/html_node/Automatic... After reading the manual and writing 3 substantial Makefiles from scratch, I still think Make is ugly and, by modern standards, no…

Its not actually all that hard to make well-parallelized makefiles, provided you follow a few basic rules. - Each build step has a unique artifact. - That artifact is visible to Make as a file in the filesystem. - That artifact is named $@ in the rule's recipe. - Every time the recipe is executed, $@ is updated on success. - If the recipe fails, it must return nonzero to Make. - All of the dependencies of the artifac…

You forgot the most important and most difficult part. Ensuring transitive dependencies really make their way into the makefile without huge manual effort. For C-like languages just adding an additional #include in a header file will break most makefiles. To solve it you need to generate makefiles using -MMD flags which are included from your main makefile and this is not very obvious.

As make was mainly intended to build C projects, not getting these batteries included is why i think parent, and many others, consider makefiles needlessly complex.

Re: Makefiles – Best Practices

#119
post #96
post #19

Earlier quoted context omitted.

What's more simple than "add_executable(foo bar.cpp)"? It's concise, cross-platform and hides all the boilerplate for you. Sure, everything in CMake is not super intuitive, but I've led workshops were people got the hang of it pretty quickly for simple to advanced cases (including multiple targets and some scripting). Keep it simple, most of the time, you don't need the advanced features at all! Can't say the same fo…

You forgot -Wall. Also, does this enable C++11? And don’t forget to set that NDEBUG macro. All the things above is still a 2 line Makefile. And it is intuitive, too - you jusy copy your command-line g++ invocation and paste into Makefile.

That has nothing to do with the compilation of your program. This is a specific option to use in a specific configuration and specific compilers.

So if you want a configuration with some flags like that, then you can have a separate file for it. Each compiler is different after all, some will need different options.

Re: Makefiles – Best Practices

#120
post #117
post #4

I recently decided it was time to get a better understanding of how makefiles work, and after reading a few tutorials, ended up just reading the manual. It's long, but it's very, very well written (a good example of one of the Gnu projects biggest strengths), to the point where just starting at the top and reading gives an almost tutorial-like effect. Just read the manual!

Can you humor a dumb question and tell me how you got the manual in your terminal? I'm on Debian, and when I `man make`, I just get a typical GNU CLI util manpage that's five paragraphs of intro and a line-by-line explanation of each command line option. Same for `info make`.

Have you installed the make-info (https://packages.debian.org/jessie/make-doc) package? It adds info documentation as well as pdf and html formats.
Post reply on HN