help-gnu-utils
[Top][All Lists]
Advanced

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

Re: make: need help reducing boilerplate repetition


From: Doug
Subject: Re: make: need help reducing boilerplate repetition
Date: Mon, 3 Mar 2008 07:25:26 -0800 (PST)
User-agent: G2/1.0

On Feb 28, 3:05 pm, Derekasaurus Rex <address@hidden> wrote:
> I have written a simple makefile that builds all of the C++ source
> files in a folder and turns them into a static library. Ultimately I
> need to build multiple libraries, so I need to accomplish this:
>
> Src/Lib/libfoo/*.cpp --> Lib/libfoo.a
> Src/Lib/libbar/*.cpp --> Lib/libbar.a
> Src/Lib/libbaz/*.cpp --> Lib/libbaz.a
> etc.
>
> I have accomplished this by writing the following code for each
> library, shown here just for libfoo.a:
>
> # source are just all .cpp files in the libfoo directory
> libfoo_SOURCES = $(wildcard Src/Lib/libfoo/*.cpp)
>
> # replace .cpp with .o to create list of objects
> libfoo_OBJECTS = $(patsubst %.cpp, %.o, $(libfoo_SOURCES))
>
> # this is how we link the objects in Src/Lib/libfoo to mkae Lib/
> libfoo.a
> libfoo: $(libfoo_OBJECTS)
>         $(AR) $(ARFLAGS) Lib/libfoo.a $(libfoo_OBJECTS)
>
> # here is how we compile objects; needed so .o files end up in Src/Lib/
> libfoo
> Src/Lib/libfoo/%.o : Src/Lib/libfoo/%.cpp
>         $(COMPILE) -c $< -o $@
>
> It's all simple enough, except that I have about 15 libraries to
> build. That translates to a lot of boilerplate repetition Can anyone
> suggest how to structure my makefile such that I could build multiple
> libraries without writing the above lines for each and every one?

Rex,

It's possible to get what you want by using a combination of the
foreach, eval, and template features of Make. I have done it, but
unfortunately can't post my actual Makefile, and don't have time to
work through a full example. Here's an untested snippet which may help
you get started. You need the double $$'s inside calls to eval for
things to work (I think). The Make documentation should help with any
questions.

# Library names
LIBNAMES = foo bar baz

# Build src/obj lists of form lib<name>_SOURCES, lib<name>_OBJECTS
$(foreach name, $(LIBNAMES), $(eval lib$(name)_SOURCES=$$(wildcard Src/
Lib/lib$$(name)/*.cpp)))
$(foreach name, $(LIBNAMES), $(eval lib$(name)_OBJECTS=$$(patsubst
%.cpp, %.o, $$(lib$$(name)_SOURCES))))

You can then create a template for other targets/rules and eval a call
to the template for each library.
I think you would want something like...

define COMPILE_TEMPLATE
Src/Lib/lib$(1)/%.o : Src/Lib/lib$(1)/%.cpp
    $$(COMPILE) -c $$< -o $$@
endef

# The you call the compile template for each library
$(foreach name, $(LIBNAMES), $(eval $(call COMPILE_TEMPLATE,$(name))))

Hope that helps...
-Doug


reply via email to

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