how do you make a *good* makefile?

Programming, for all ages and all languages.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: how do you make a *good* makefile?

Post by Solar »

Combuster wrote:
Solar wrote:Have you seen the Makefile tutorial? If it doesn't suit your needs, tell me what's missing and I'll see if I can extend the tutorial...
It leaves dealing with multiple intermediate/output files (like kernel, separate drivers, bundling into floppy image) as an exercise to the reader. And it doesn't support multiple architectures...
A nice example of "it's not easy enough for the beginner, and it doesn't include all the tricks for the pro". When writing a tutorial, I tend to address only one of the two...

Besides, there are many different ways of supporting multiple architectures (autoconf, makefile tweaking, file overlays, ...), and I didn't want to open that can of worms as my preference (file overlay) is rather non-standard.

I'll look into it if an hour of free time materializes.
(speaking of which, a pro's comment on my make settarget hack would be welcome :D).
Not a pro on makefiles either, but...

The passing of parameters by environment is a nice one, I used that for my "make find" and "make test" targets myself. I'm not sure I like the idea of having to maintain seperate Makefiles for each supported architecture, though.
Every good solution is obvious once you've found it.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: how do you make a *good* makefile?

Post by Combuster »

Love4Boobies wrote:instead of including all makefiles like you did, I'd do something like this:

Code: Select all

subdirs : foo bar foobar

.PHONY : all $(subdirs)
all :
        $(MAKE) -C $@
I deliberately decided against that, since it would mean (in my case) two screens full of entering directory...nothing to be done...leaving directory every time I call make (several directories for libc, libarch, libfb, and then the kernel, drivers and apps)
Right now it isn't spamming me at all :wink:
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: how do you make a *good* makefile?

Post by Solar »

Love4Boobies wrote:Also, instead of including all makefiles like you did, I'd do something like this...
Please read "recursive make considered harmful".
Every good solution is obvious once you've found it.
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Re: how do you make a *good* makefile?

Post by earlz »

ok, thanks to brynet, I've found some info on BSD make... (your wiki page works just about only with GNU make)

in place of your

Code: Select all

OBJFILES:=$(patsubst %.c,%.o,$(SRCS)
I have discovered

Code: Select all

OBJFILE:=$(SRCS:%.c=%.o)
and that works with both GNU make and BSD make...

it's little tricks like that that have prevented me from making a good makefile. just simple tricks I have yet to find.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: how do you make a *good* makefile?

Post by Solar »

GNU make is pretty much "the standard", and you didn't mention that you're looking for cross-make compatibility...
Every good solution is obvious once you've found it.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: how do you make a *good* makefile?

Post by AJ »

earlz wrote:it's little tricks like that that have prevented me from making a good makefile.
In order to create that tutorial, Solar has obviously had to do background work and playing around with Make in order to come up with a solution that works nicely for the vast majority of cases. As he says - when you say "make", you pretty much mean GNU Make.

If you want something unusual, you need to do the background research and not expect to find what you need in a premade tutorial.

Cheers,
Adam
User avatar
Love4Boobies
Member
Member
Posts: 2111
Joined: Fri Mar 07, 2008 5:36 pm
Location: Bucharest, Romania

Re: how do you make a *good* makefile?

Post by Love4Boobies »

Combuster wrote:
Love4Boobies wrote:instead of including all makefiles like you did, I'd do something like this:

Code: Select all

subdirs : foo bar foobar

.PHONY : all $(subdirs)
all :
        $(MAKE) -C $@
I deliberately decided against that, since it would mean (in my case) two screens full of entering directory...nothing to be done...leaving directory every time I call make (several directories for libc, libarch, libfb, and then the kernel, drivers and apps)
Right now it isn't spamming me at all :wink:
In GNU make, you can use -s for silent, or --no-print-directory which won't spam you with directory entrances and leavings. I'm sure there's a similar option in BSD make.
Solar wrote:
Love4Boobies wrote:Also, instead of including all makefiles like you did, I'd do something like this...
Please read "recursive make considered harmful".
I am aware of that, but it's not always the case. Sometimes it is much more convenient to have separate makefiles because you may want to be able to distribute your modules separately (together with makefiles). My OS only has a few such modules so it's not as if I had 1337 makefiles which would burden the process. I took a peek at Combuster's makefile and the case is pretty much the same.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: how do you make a *good* makefile?

Post by Combuster »

Love4Boobies wrote:In GNU make, you can use -s for silent, or --no-print-directory which won't spam you with directory entrances and leavings. I'm sure there's a similar option in BSD make.
-s makes debugging makefiles nasty. In regular usage it causes it to say too little.
I took a peek at Combuster's makefile and the case is pretty much the same.
Look harder - there are cross-dependencies that don't work with recursive makefiles. As well as it doesn't build libraries if it doesn't need them at any moment (And I can't do without that since libc hasn't got a config.h for each platform yet, and libfb will break on any non-x86 target, and I still want my m68k kernel to compile)

I used recursive makefiles in the past - it ended up being unmaintainable.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: how do you make a *good* makefile?

Post by Solar »

Combuster wrote:
Love4Boobies wrote:In GNU make, you can use -s for silent, or --no-print-directory which won't spam you with directory entrances and leavings.
-s makes debugging makefiles nasty. In regular usage it causes it to say too little.
'make -s' is a user option, which shouldn't be used by makefiles themselves. (If you insist on making them recursive, at least leave the option of "silent or not" to the user.)
Love4Boobies wrote:Sometimes it is much more convenient to have separate makefiles because you may want to be able to distribute your modules separately (together with makefiles).
If a module is self-sufficient, it's a seperate project and shouldn't be in the same source tree, but in a tree of its own with its own top-level makefile. You shouldn't work on that module while you're also working on your (other) project (moving target problems).

If a module is not self-sufficient but has dependencies, it cannot be distributed seperately anyway...
Every good solution is obvious once you've found it.
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Re: how do you make a *good* makefile?

Post by earlz »

I don't see how things can be done so easily without recursive makefiles.. but in my project I only have like 5 makefiles at this time.. anyway..
I found this link to the POSIX standard for make(which means it is suppose to work with any make) http://www.opengroup.org/onlinepubs/009 ... /make.html

It's pretty helpful..
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: how do you make a *good* makefile?

Post by Solar »

earlz wrote:I don't see how things can be done so easily without recursive makefiles.
It boils down to pretty much the same thing, only that instead of a seperate makefile for each subdirectory, you provide a make include per subdirectory. There are some papers on the issue around, this one being one of them.

Note that, in the tutorial, I don't use per-subdirectory includes, but gather the file lists automatically from the top level. It's all down to preferences and the specifics of your project, really.
earlz wrote:I found this link to the POSIX standard for make...
Don't put your hopes up too much. I don't know about the specific document you linked regarding 'make', but have come across numerous fallacies, inconsistencies, and incompatibilities regarding POSIX over the yeras. (Linux using different errno values than defined by POSIX, or the time handling being "funny" when it comes to leap seconds.) POSIX was an attempt to bring the several flavours of Unixes together after they diverged, and as such, it's a collection of compromises. (Same as the C or C++ language standards.)

...

What's my point? Well, I think it doesn't matter if you define "POSIX make" or "GNU make" as your standard, or whether you use special GNU extensions or not, as long as you are aware you are doing it.

I admit I should have mentioned the Makefile tutorial being written with GNU make in mind. You should have mentioned that cross-make compatibility is a serious issue for you. (As GNU make is available on virtually every platform.)
Every good solution is obvious once you've found it.
User avatar
Steve the Pirate
Member
Member
Posts: 152
Joined: Fri Dec 15, 2006 7:01 am
Location: Brisbane, Australia
Contact:

Re: how do you make a *good* makefile?

Post by Steve the Pirate »

bewing wrote:You create variables for your output destination directories. You do your compilation in two stages.

gcc -c sourcefile.c -o ${objdir}/sourcefile.o

gcc ${objdir}/file1.o ${objdir}/file2.o ... -o ${bindir}/target.bin
I've been looking at completely re-writing my makefile (my current one is very hard-coded, and builds every source file every time). Anyway, I would really like to do an out-of-tree build, and I can't get it to work properly. Won't your way mean that if you tried to 'make somefile.o', it would always rebuild it, because it wouldn't exist in the directory, and if you tried to build, say, 'make obj/sourcefile.o' it wouldn't work because it wouldn't be able to find all the variables? Maybe I'm just not understanding how Make really works...
My Site | My Blog
Symmetry - My operating system.
User avatar
Love4Boobies
Member
Member
Posts: 2111
Joined: Fri Mar 07, 2008 5:36 pm
Location: Bucharest, Romania

Re: how do you make a *good* makefile?

Post by Love4Boobies »

I'm not exactly sure what you're trying to say, but you can do this:

Code: Select all

path\targets : prerequisites
Now here comes my question. Although this might be slow, I know most compilers provide command line arguments akin to GCC's -M, which can be used to automatically add the files used by the #include directive to the prerequisites list. I'm saying it'd be slow because of all the parsing. However, I'm not entirely sure how this is supposed to work. I can only think of a hack: redirecting stdout to a file (as -M outputs to the screen) and then including that. Can anyone give a proper example how this can be used?
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: how do you make a *good* makefile?

Post by Solar »

Steve the Pirate wrote:Anyway, I would really like to do an out-of-tree build, and I can't get it to work properly. Won't your way mean that if you tried to 'make somefile.o', it would always rebuild it, because it wouldn't exist in the directory, and if you tried to build, say, 'make obj/sourcefile.o' it wouldn't work because it wouldn't be able to find all the variables? Maybe I'm just not understanding how Make really works...
For an out-of-tree build, you'd have to copy the makefile into the build directory first. For the "usual" out-of-tree builds you know from e.g. the GNU tools, you start with ../<sourcetree>/configure, which creates the Makefile in the current (build) directory.
Every good solution is obvious once you've found it.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: how do you make a *good* makefile?

Post by Solar »

Love4Boobies wrote:Now here comes my question. Although this might be slow, I know most compilers provide command line arguments akin to GCC's -M, which can be used to automatically add the files used by the #include directive to the prerequisites list. I'm saying it'd be slow because of all the parsing.
It's not slow. At least, not as slow as always recompiling from scratch whenever you edited a header file...
However, I'm not entirely sure how this is supposed to work. I can only think of a hack: redirecting stdout to a file (as -M outputs to the screen) and then including that. Can anyone give a proper example how this can be used?
Makefile?
Every good solution is obvious once you've found it.
Post Reply