help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Makefile question


From: Todd Showalter
Subject: Re: Makefile question
Date: Tue, 9 Mar 2010 08:58:52 -0500

On Tue, Mar 9, 2010 at 4:27 AM, Ole Amund Søvde <address@hidden> wrote:

> I'd like to ask a question about make, and hope you could help me with
> it. :-) Maye it's trivial, but I cannot seem to find out how to solve it...
>
> I have some directories with fortran files, say
> src/fil1.f
> src/fil2.f
> src2/fil2.f
>
> where you can see fil2.f is in both directories.
>
> I would like to list all files I want to compile in a variable:
> SRCFILES = src/fil1.f src2/fil2.f
>
> and compile them to a separate object directory:
> OBJFILES = tmp/fil1.o tmp/fil2.o
>
> Whether fil2.f is compiled from src/ or src2/ should therefore be
> defined by SRCFILES.
>
> Hopefully, something like this would be possible:
> $(OBJFILES): $(SRCFILES)
>       address@hidden "Compiling $< ... $@"
>
> But I cannot make it work, and wonder if it is possible?

    Our build system deals with a similar situation; our game engine
supports multiple platforms, and we want as much of the code as
possible to be generic.  To do this, our source tree has
subdirectories for different architectures.  An example:

.../Input/Input.c
.../Input/arch.NintendoDS/Input.c
.../Input/arch.NintendoWii/Input.c
.../Input/arch.SonyPS3/Input.c
.../Input/arch.SonyPSP/Input.c

    and so forth.

    Then, if the game engine is being built for (say) Wii, if there's
a file in Input/arch.NintendoWii/ with the same name as the file in
Input/, we build the one in the arch directory instead.  This lets us
override files on a per-architecture basis, which means most of our
code can be completely generic, and we don't have to sprinkle
architecture macros all through the code.

    I could not find a clean way to do that entirely within make; the
directory recursion and rule assembly required is too complex for
make's syntax to express in a maintainable way.  That is to say, it
can be done, but it can't be done in a way that you'll have any fun
debugging when it's not quite working right three months from now.

    What we have instead is a preprocessor that walks the code tree
and generates a makefile with explicit dependencies.  The current
version is written in C, but originally it was a ruby script that took
an afternoon to write; it's not a particularly hard too to make.  It
takes the base of the tree and the architecture flags as arguments,
and spits out something intended to be included in a makefile.

    The output file is basically a list of sources and objects, laid
out in such a way that the build rule can be simple.  In our case,
given your example, the output would look like:

SRCS= src/fil1.f src/fil2.f
OBJS= tmp/src/fil1.o tmp/src/fil2.o
OBJDIRS= tmp/src

   or for the src2 version:

SRCS= src/fil1.f src2/fil2.f
OBJS= tmp/src/fil1.o tmp/src2/fil2.o
OBJDIRS= tmp/src tmp/src2

    Note that the complete path gets preserved in OBJS.  That way, the
build rules can be:

tmp/%.o: %.f | $(OBJDIRS)
    $(compile) $< -o $@

target: $(OBJS)
    $(link) $(OBJS) -o $@

$(OBJDIRS):
    $(mkdir) $@

   This system has actually worked quite well for us.  Ours is a
little more complex than I've described here (it allows multiple
architecture flags to be defined at once and handles things like code
dependency generation, amongst other things), but it sounds like the
simple version solves your problem.

                                                                  Todd.

-- 
 Todd Showalter, President,
 Electron Jump Games, Inc.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]