[Top][All Lists]

[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 <> 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?


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

# 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/
$(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...

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

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

Hope that helps...

reply via email to

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