Page 1 of 3

how do you make a *good* makefile?

Posted: Fri Jan 30, 2009 11:56 am
by earlz
Ok, well, I have been slowly evolving in my makefile ways, but I have yet to understand how to make those robust makefiles that only compile the files that have changed.

I have yet to find any makefile tutorials out there beyond simple

Code: Select all

default:
    gcc -o name_of_binary -c name_of_source
does anyone have any experience with this kind of makefile?

(also, preferably this will work in both BSD make and GNU make)

edit:

Code: Select all

as-ebc:	${OBJS}
	${CC} ${LDFLAGS} ${OBJS} -o as-ebc

.c.o: ${HDRS}
	${CC} ${CFLAGS} -c $*.c

lint:
	lint ${DFLAGS} ${SRCS}
clean:
	rm -f ${OBJS} as-ebc core a.out errs
install:
	install -s as ${DESTDIR}/bin
that is the best makefile I've seen that works with both bsd make and gnu make. My problem with it though is that I can't figure out a way to put output objs into a seperate ./objs directory and the binary in ./bin/ directory...

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

Posted: Fri Jan 30, 2009 12:05 pm
by Love4Boobies
How about adding paths to your compilation commands? An alternative is to have a move command or something do the job for you after everything is finished, though this wouldn't be the cleanest option IMO.

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

Posted: Fri Jan 30, 2009 12:38 pm
by earlz
I would like it to be a little more elegant... mv also won't clean up stuff if the compile fails, plus I am concerned about those people that build from a read-only source location

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

Posted: Fri Jan 30, 2009 1:42 pm
by bewing
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

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

Posted: Fri Jan 30, 2009 2:03 pm
by ruisleipa
I don't know if this a is very good solution but hope it is useful:

Code: Select all

CC = gcc
CFLAGS=-Wall -fstrength-reduce -fomit-frame-pointer -funsigned-char -finline-functions \
-nostdinc -fno-builtin -g -I/home/mikko/agileos/include

LD = ld
LDFLAGS = -T link.ld

AS=nasm
ASFLAGS=-f elf -g

OBJS = main.o gdt.o idt.o irq.o isrs.o panic.o string.o \
timer.o kprintf.o ioport.o logo.o multiboot.o cmos.o

all: $(OBJS) 

clean:
	-rm $(OBJS) 
The makefile compiles only the files that have changed after the last compilation or have not been compiled at all.

Work with GNU make. Haven't tried BSD make, may work or not.

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

Posted: Fri Jan 30, 2009 4:16 pm
by Love4Boobies
berkus wrote:Best makefile is no makefile at all. Use waf/scons/cmake/bam/etcetcetc.
Aren't those (esp. cmake) really makefiles with some different syntax? Probably the easiest would be to use an IDE, but that makes it harder if you want to distribute your source code and make it portable. You could try to build your own tool, though. This kind of tools are amongst the easiest to make.

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

Posted: Fri Jan 30, 2009 4:38 pm
by Love4Boobies
berkus wrote:forgot to mention, not counting requiring python installation, the whole waf is redistributable in a 75kb python file, so you can easily commit it together with your os sources and never bother about building or configuring it separately. [/edit]
If its license permits that *and* if it's compatible with your OS's license, then it sounds neat...

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

Posted: Fri Jan 30, 2009 5:11 pm
by Combuster
Not to mention that gnu make is the most often the only tool of its kind to be installed by default. And the same relative amount of people know how to use it.

If you're looking for ideas for OS scale makefiles, have a go at mine. I'm not saying its good but it does everything I want and need. (link in signature)

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

Posted: Fri Jan 30, 2009 11:19 pm
by earlz
the best thign about make(gnu or bsd) ...
it's existed basically forever without really being considered out of date. I mean, that "good" makefile I posted is from BSD 4.2's as (the original BSD for pdp)

I think I just have to become more acquainted with make to develop a makefile just like I like..

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

Posted: Sat Jan 31, 2009 2:45 am
by Love4Boobies
earlz wrote:the best thign about make(gnu or bsd) ...
it's existed basically forever without really being considered out of date.
Arguably.

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

Posted: Mon Feb 02, 2009 4:22 pm
by earlz
Well, maybe I'll write my own tool to generate a good makefile... (thus, have more control over wildcard resolving)

one problem... in my 3 years or so of working with C... I've never once tried to do anything with directories! D:

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

Posted: Mon Feb 02, 2009 4:34 pm
by Solar
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...

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

Posted: Mon Feb 02, 2009 4:35 pm
by Love4Boobies
And you're making an OS in it? :?

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

Posted: Mon Feb 02, 2009 5:13 pm
by Combuster
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 (speaking of which, a pro's comment on my make settarget hack would be welcome :D).

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

Posted: Mon Feb 02, 2009 5:25 pm
by Love4Boobies
Combuster wrote:(speaking of which, a pro's comment on my make settarget hack would be welcome :D)
I'm no pro, but IMO all you have to do is pass the arch as a command line variable and build according to that (i.e. by passing the right things to your compiler/linker). Also, 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 $@