Page 2 of 3

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

Posted: Tue Feb 03, 2009 2:00 am
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.

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

Posted: Tue Feb 03, 2009 9:04 am
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:

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

Posted: Tue Feb 03, 2009 9:14 am
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".

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

Posted: Tue Feb 03, 2009 2:33 pm
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.

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

Posted: Tue Feb 03, 2009 11:39 pm
by Solar
GNU make is pretty much "the standard", and you didn't mention that you're looking for cross-make compatibility...

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

Posted: Wed Feb 04, 2009 3:28 am
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

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

Posted: Wed Feb 04, 2009 5:49 am
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.

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

Posted: Wed Feb 04, 2009 7:00 am
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.

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

Posted: Wed Feb 04, 2009 7:50 am
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...

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

Posted: Wed Feb 04, 2009 1:42 pm
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..

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

Posted: Wed Feb 04, 2009 3:02 pm
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.)

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

Posted: Wed Feb 11, 2009 2:03 am
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...

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

Posted: Wed Feb 11, 2009 2:24 am
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?

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

Posted: Wed Feb 11, 2009 2:44 am
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.

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

Posted: Wed Feb 11, 2009 2:47 am
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?