   Makefile question - SOLVED
  Why is it that the $@ variable is not available in the dependency list, but only in the body of the makefile block. Those are odd scoping rules, and I'm trying to get around it somehow. I'll give a simple example to show what I mean:Suppose I have something like this:prog1: $(OBJS) prog1.o@echo "Linking $@..."@$(LD) $(LDFLAGS) -o $@ $(OBJ) $@.oprog2: $(OBJS) prog2.o@echo "Linking $@..."@$(LD) $(LDFLAGS) -o $@ $(OBJ) $@.oThis works fine. Clearly, I'm separating the executable's linker object from the libraries' ones, since I have more than one executable. That's fine and dandy.But what if I don't want to have that ugly repeating code block? I can have a variable called DESTS, containing "prog1 prog2" and try to do something like this:$(DESTS): $(OBJS) $@.o@echo "Linking $@..."@$(LD) $(LDFLAGS) -o $@ $(OBJ) $@.oThis works great if I don't have that $@.o in the dependency list and compile the .o separately somewhere else, but if I try to do what the sample above shows, it says it can't find ".o" (in other words, $@ is empty until the echo statement below).Am I totally on crack here? Is there a way to do this nicely? The problem with setting up .o compilation of the exe's outside of that block is that if I change just the code in (say) prog1.cpp, then it will not relink everything, because prog1.o is not in the dependency list..... help? :)[Edited by - Replicon on June 4, 2006 11:49:50 PM]
  If you're using GNU make > =3.80 you can use eval and call to do what you want:# Creates rules to create a library# $(eval $(call make-exe prog-name,objs))define make-exe   $1: $2 $1.o @echo "Linking $@..." @$(LD) $(LDFLAGS) -o $@ $(OBJ) $@.oendef$(eval $(call prog1,$(objs)))$(eval $(call prog2,$(objs)));  You could do this:all: $(DESTS)   %: %.o   @echo "Linking $@..."   @$(LD) $(LDFLAGS) -o $@ $(OBJ) $@.o In theory that should work, but having "%" as a target may be a problem because Make will try to apply the rule to every file.;Quote:Original post by jamessharpeIf you're using GNU make > =3.80 you can use eval and call to do what you want:# Creates rules to create a library# $(eval $(call make-exe prog-name,objs))define make-exe   $1: $2 $1.o @echo "Linking $@..." @$(LD) $(LDFLAGS) -o $@ $(OBJ) $@.oendef$(eval $(call prog1,$(objs)))$(eval $(call prog2,$(objs)))That's a cool and interesting approach :). Interestingly, when I have several eval calls like you do in your sample, it only executes the first one (no errors). Also, if instead of putting it in the body, I put it under a target (say 'default:'), it warns about overriding commands for target and ignoring old commands for target. Very odd behaviour. I also tried doing something like that with a foreach on $(DESTS), but again, it only executed the first one.Quote:JohnBoltonall: $(DESTS)   %: %.o   @echo "Linking $@..."   @$(LD) $(LDFLAGS) -o $@ $(OBJ) $@.o This looks like it works, but it (by default) deletes all the .o's it created and only leaves the binary behind, which defeats the purpose. Why does it do an rm on all those .o files? It's not executing my own clean target, it's a builtin of some sort.... gah!   ;  Bingo! I just realized what eval actually does hehe sorry for the confusion :-). I was able to use a foreach to generate all my targets. My magic Makefile is now working!   