On Feb 28, 3:05 pm, Derekasaurus Rex <derek.goo... grog.net> 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
|