|
From: Keith M. <kei...@us...> - 2014-12-29 23:41:14
|
On 29/12/14 11:14, Tuomo Latto wrote: > On 24.12.2014 15:15, 孔涛 wrote: >> Hello,everyone >> >> How to set different prerequisites for the same target when it >> belong to a different target. For example,target t1 depends on file >> main.o and t1.o where main.o depend on t1.o (it's a module file in >> fortran, similar as a head file .h in C) Huh? Surely t1.o is an *object* file; the corresponding module file should be t1.mod, should it not? (Disclaimer: I've not written any FORTRAN code in years, and only ever FORTRAN-66/77 ... never F90/95). >> besides its source, while target t2 depends on file main.o and t2.o >> where at this time main.o depends on t2.o together with it's souce >> file. i.e >> -------------------------- >> t1 : main.o t1.o >> main.o: t1.o >> ------- >> t2:main.o t2.o >> main.o: t2.o If you put these in one makefile, you make main.o simultaneously dependent on t1.o and t2.o, (which doesn't make any sense, because each object file should depend only on its sources ... not other objects). >> ------------------------- >> I wrote them together in one makefile, but unforturanatly, the dependece of main.o does not take effect. why? >> -- >> 1 .SECONDEXPANSION: >> 2 >> 3 FC=gfortran >> 4 PRJ = t1 t2 >> 5 >> 6 all: $(PRJ) >> 7 >> 8 %.o:%.f90 ; $(FC) -c $< >> 9 >> 10 >> 11 t1: tname = t1.o >> 12 t2: tname = t2.o >> 13 >> 14 $(PRJ) : main.o $$(tname) ; $(FC) $^ -o $@ >> 15 main.o : $$(tname) >> 16 >> 17 clean: >> 18 rm -rf $(PRJ) *.o *.mod >> ---- >> line 15 does not make any sense. why? Likely because you are attempting to use a target specific variable, $(tname), expanded on the second expansion pass, but that variable has no definition in the context of the main.o target, (which is the target on line 15). > AFAIK make generally likes to spawn new child processes to handle each > of the dependencies (and each command line within rules), so naturally > variables won't stay set across targets. Shell variable, set within the commands invoked by the rule won't, across separate commands; make variables *will*. > To be sure you'd have to set (environment?) variables in the parent make, > if you want sticky variables, Nope ... you would use make variables. > but I think you can find better ways to organize the build. I agree. > For example, does main really need the t1/t2 dependency? Possibly on the t1.mod and t2.mod files? However, the OP's fundamental misunderstanding seems to be that main.o can depend on one or other, but not both simultaneously, and that make can rebuild it as required, to satisfy some other dependency. Unless the two build objectives are separated into distinct "if" blocks, *and* main.o is deleted at the end of each logical build sequence, it can't; once built, it will not be rebuilt unless it is definitively out of date WRT its prerequisites, and there can be only one inclusive set of prerequisites in any one logical invocation of make. > Also, are you sure the syntax on lines 11 and 12 is correct? They look okay to me. They define a target specific variable, which is one of those features of GNU make which many consider to be obscure, so is likely little used; it's certainly a feature which I've never had occasion to use, (as is secondary expansion, which hardly seems to be justified by the examples in the GNU make manual). > And have you noticed that line 8 also defines the compilation of > main.o? That's fine; it's an implicit rule, defining the commands which are to be executed, WRT the prerequisites specified... > Are you sure you're not hitting that rule instead of lines 11, 12 > and 15? ...here; the issue seems to be that those prerequisites make little or no sense. -- Regards, Keith. |