dimitri@cui.UUCP (KONSTANTAS Dimitri) (03/04/88)
Using the make program, I came to case where make behaves differently when executed with the -n option and without. That is with the -n option the actions are listed, as excected, but without it, they are not executed (I get that the target file is up-to-date). Following is a shar file that recreates the case. (the files are empty, but it is the modification dates that count) After unpacking the shar file , just give make -n test and then make test Can anybody explain what is happening? I run the test in both VAX with 4.3 and SUN 3.4 and get the same behavior. Dimitri Konstantas University of Geneva dimitri@cgeuge51.bitnet mcvax!cernvac!cui!dimitri ---- cut here --------------------------------------------- # This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # makefile crf # The files f1.a f2.o f2.c test test.c test.o will also be create echo x - makefile cat > "makefile" << '//E*O*F makefile//' test: f1.a @echo "compiling TEST" f1.a: f2.o @echo "Recompiling f1.a" f2.o: f2.c @echo "recompiling f2.c" //E*O*F makefile// echo x - crf cat > "crf" << '//E*O*F crf//' echo "Please wait a few seconds to recreate the files with correct times" touch test.c ; sleep 1 touch f2.o ; sleep 1 touch f1.a ; sleep 1 touch test.o ; sleep 1 touch test ; sleep 1 touch f2.c //E*O*F crf// sh ./crf exit 0
bww@K.GP.CS.CMU.EDU (Bradley White) (03/06/88)
In article <110@cui.UUCP>, dimitri@cui.UUCP (KONSTANTAS Dimitri) writes: > Using the make program, I came to case where make behaves differently > when executed with the -n option and without. It should not be surprising that "make" and "make -n" can do different things. "make -n" assumes that an "a: b c" rule actually makes "a" out of "b" and "c", and that it does it ``now'', whereas "make" can stat() "a" after the commands are run to see if it was really made. In general, rules that don't make their targets (like those given), or rules that try to be smart about making their target even though the dependencies are out of date (for example, trying to detect benign changes), will always confuse "make -n". -- Bradley White <bww@cs.cmu.edu> +1-412-268-3060 CMU Computer Science Department 40 26'33"N 79 56'48"W
rdh@sun.uucp (Robert Hartman) (03/07/88)
In article <1048@PT.CS.CMU.EDU> bww@K.GP.CS.CMU.EDU (Bradley White) writes: >In article <110@cui.UUCP>, dimitri@cui.UUCP (KONSTANTAS Dimitri) writes: >> Using the make program, I came to case where make behaves differently >> when executed with the -n option and without. > >It should not be surprising that "make" and "make -n" can do different >things. "make -n" assumes that an "a: b c" rule actually makes "a" out >of "b" and "c", and that it does it ``now'', whereas "make" can stat() >"a" after the commands are run to see if it was really made. In >general, rules that don't make their targets (like those given), or >rules that try to be smart about making their target even though the >dependencies are out of date (for example, trying to detect benign >changes), will always confuse "make -n". >-- >Bradley White <bww@cs.cmu.edu> +1-412-268-3060 >CMU Computer Science Department 40 26'33"N 79 56'48"W Another cause for this is if the makefile contains a rule with a 'make' command in it (e.g., a 'nested' make command): all: -cd foo ; make bar When you run make with this makefile, you'll make the target 'bar' as defined in the makefile in ./foo. But if you run this with -n, the nested make isn't performed; you don't see the rule for building bar. In System V make, if you replace 'make' with '$(MAKE)' in the rule: all: -cd foo ; $(MAKE) bar the nested 'make' command line runs despite -n; it runs with the same flags as the calling make command (e.g, -n). So if you run 'make -n' in this case, the nested make will display the rule for bar as given in the makefile in (directory) foo. This allows you to run 'make -n' on an entire source hierarchy. A bit on terminology. Many people call the above a 'recursive' make. But that seems wrong to me, since it makes nothing in the local dir. To me a 'recursive' make is something like this: foo: foo.nested foo.local foo.nested: cd subdir1 ; make foo cd subdir2 ; make foo ... foo.local: touch foo This target propagates the build of 'foo' down the hierarchy, and then builds something in the local directory. Thus, it makes `foo' recursively. A make command can get flags both from the command line and the (automatic) MAKEFLAGS macro, but note that this macro does register options that have arguments (e.g., -f). You can initialize MAKEFLAGS as an envar; other macros can also be initialized in this way, but the precedence of values between the current make, nested makes, and the environment, gets pretty convoluted. For clarity's sake it is probably better to just to initialize macros in the makefile, and to pass macro defs to nested makes as arguments in the nested commands. In an earlier posting about make I included a .DEFAULT rule to get a file out of SCCS. In versions of make that have tilde rules, it is not necessary to do that. The tilde rule for a .c file assures that it will be extracted from SCCS as needed. -bob.