On Feb 28, 3:05 pm, Derekasaurus Rex <[EMAIL PROTECTED]> 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