Page 2 of 2

Re:Makefile organization

Posted: Mon Feb 09, 2004 8:35 am
by Candy
Hate to brag, but for hierarchical projects that are to be linked to a single target, I think I have a nice bit of makefiling. My code links all module sections to the big kernel object (atm from the core) and links those together. The ugly stuff from the makefiling is stored away in a makefile.default and the actual file specs & details are in a separate makefile for each dir, that only contains 4 vars and 2 includes. Very very clean, and quick too. Auto-dependencies too, so it's a breeze for me, throwing the code around the dir structure, it makes its own dependencies fit back in. (adding a header to a source file adds it to the depends with the next make dep). You might want to check it.

PS: doesn't take away from the makefile.default being completely illegible, but it's contained and working.

Re:Makefile organization

Posted: Mon Feb 09, 2004 9:19 am
by Solar
Now, that sounds good, Candy... leaving only one question: where? 8)

Re:Makefile organization

Posted: Mon Feb 09, 2004 10:26 am
by Pype.Clicker
Solar wrote: Sorry, Pype, but you achieve the same with included makefiles - each of which is for a subproject. It's the recursive call that makes a mess out of things.
hmm .. one thing i'm unsure of is how files will be named in included makefiles ... so far i've only included patterns or variable definition, but not targets. Maybe i should try it -- but i feel it would confuse me more than help me (what if i have a variable named 'x' in two distinct included makefiles ... which one will apply in include-all pattern ? for recursive makes, at least, the locally-defined variable is ... well ... local.

Re:Makefile organization

Posted: Mon Feb 09, 2004 12:51 pm
by Jamethiel
Pype.Clicker wrote: (what if i have a variable named 'x' in two distinct included makefiles ... which one will apply in include-all pattern ? for recursive makes, at least, the locally-defined variable is ... well ... local.
Well, if you actually need the variables, you might try a package prefix setup. Instead of 'x', use 'module_x'.

For my own (non-OS) development, I started breaking out the common parts of programs into separate directories under ~/src/mods/, each with a module.mk file similar to the following:

Code: Select all

#
# module.mk for mods/emu/snd/sn76489
#

SRCS += sn76489.c

# EOF
The toplevel makefile (~/src/playmod/Makefile, for example) is as follows:

Code: Select all

#
# Makefile for playmod
#

include ~/src/supp/prgpre.mk

USES_MODS = unix/snd
SRCS = playmod.c
TARGET = playmod

include ~/src/supp/prgpost.mk

# EOF
Then ~/src/supp/prgpre.mk and ~/src/supp/prgpost.mk have all of the magic bits (and there's not much magic there).

Module inclusion is handled by the following in prgpost.mk:

Code: Select all

ifdef USES_MODS
include $(addprefix $(MODSRC), $(addsuffix /module.mk, $(USES_MODS)))
VPATH += $(addprefix $(MODSRC), $(USES_MODS))
IPATH += $(addprefix -I$(MODSRC), $(USES_MODS))
endif

CFLAGS += $(IPATH)
prgpost.mk also has the basic build rules for .c, .cpp, and .S files, automatic .o file list building, autodep handling, the clean and realclean rules, etc. I haven't put in the changes to make it work with the xmingw cross-compilers yet, but that shouldn't be too hard (even to the point of using something like $(TARGET_OS) in place of unix in the USES_MODS list and having it just work out).

In the end, all of the .o files end up in the toplevel project directory along with the final executable.

Problem is, I figured all of this stuff out, implemented a sizable chunk of it, and then haven't really started a project complex enough to warrant it since. Nor have I done anything about source-control integration, source distribution packaging, multiple-target setups, or anything.

--Jamethiel

Re:Makefile organization

Posted: Mon Feb 09, 2004 3:17 pm
by nullify
Jamethiel wrote: In the end, all of the .o files end up in the toplevel project directory along with the final executable.
If two source files had an identical name but were in different subdirectories of the source tree, the resulting object files would conflict since they would both have the same name and reside in the top-level directory.

My solution to this was to place all object files in ".objs" subdirectories of the corresponding source directories. So, for example...

Consider these three directories, all of which contain source files:

/src/
/src/policy/
/src/mechanism/

The corresponding object files of each directory would be placed in:

/src/.objs/
/src/policy/.objs/
/src/mechanism/.objs/

My top level Jamfile (Perforce Jam equivalent of a Makefile) would include each Jamfile in each subdirectory, putting together a list of all object files (including their file paths) that are to be linked together at the end.

Re:Makefile organization

Posted: Tue Feb 10, 2004 5:29 am
by Candy
Solar wrote: Now, that sounds good, Candy... leaving only one question: where? 8)
hm... should add that page to my home site too...

Anyway, in my OS :D

www.sf.net/projects/atlantisos (version 0.0.2 and up have it). Also, 0.0.2.1 will be released within half an hour, complete rewrite of the FP module :D, and bugfixes... makefiles barely changed.

The makefiles are suffering from most if not all the problems in that paper, but it solves one of my own biggest problems, keeping the makefiles up to date. The only time I have to alter a makefile is when I add, delete or rename a source file. If I modify dependencies, make dep cleans that up completely, and after that it's only a make all-arches (for my OS) to make a kernel for each arch (yes, always keeping optimizations in the back of my head. The binaries are nearly the same though)