brw@jim.odr.oz (Brian Wallis) (07/22/88)
Is this a bug in make, or am I just missing something obvious? The simple example for the make file is as follows... | | exe: file1.o | ld -o exe file1.o | | file1.o: dir1/file1.c | 'Makefile' is in '.' and the file 'file1.c' is in './dir1' I want to make the file 'exe' from 'file1.o' in '.' where 'file1.o' depends on './dir1/file1.c' as is stated in the Makefile. I expect the default '.c.o:' rule to be used to generate the file 'file1.o' from ./dir1/file1.c. I can get this to work by including an explicit rule for the 'file1.o' dependency, but this is a little awkward since I use mkdep to generate the dependancies and have a large number of source files in a large number of subdirectories. Here is the output from the make with debug on (and ignore errors, the bug still exists without -i, but the debuging is truncated). *** Note: that file1.o DOES NOT exist but a time is returned which is later that that returned for dir1/file1.c !!! *** | | 127% ls -l | total 2 | -rw-r----- 1 brw 65 Jul 22 17:23 Makefile | drwxr-x--- 2 brw 512 Jul 22 17:17 dir1 | 128% ls -l dir1 | total 1 | -rw-r----- 1 brw 87 Jul 22 14:51 file1.c | 129% make -d -i exe | doname(exe,0) | doname(file1.o,1) | doname(dir1/file1.c,2) | TIME(dir1/file1.c)=585550307 | TIME(file1.o)=585559519 <<< where the hell does this time come from!!!! | ld -o exe file1.o | ld:file1.o: cannot open | *** Error code 4 (ignored) | Open directories: | 4: . | 3: dir1 | Macros: | ? = file1.o | @ = | * = file1 .... (deleted stuff) | dir1/file1.c done=2 | | file1.o: done=2 | depends on: dir1/file1.c | | exe: done=2 (MAIN NAME) | depends on: file1.o | commands: | ld $(LFLAGS) -o exe file1.o ... (deleted stuff) | .c.o: done=0 | commands: | $(CC) $(CFLAGS) -c $< ... (deleted stuff) | .SUFFIXES: done=0 | depends on: .out .o .c .F .f .e .r .y .yr .ye .l .s .cl .p Can someone with source help out here??? I have tried this on... MicroVax running Ultrix 2.0 Sun 3/110 running SunOS 3.2 Altos 586 running Xenix 3.0 with the same results each time (minor differences in debugging output). -- Brian Wallis (brw@jim.odr.oz) O'Dowd Research P/L. (03) 562-0100 Fax: (03) 562-0616, Telex: Jacobs Radio (Bayswater) 152093
banderso@sagpd1.UUCP (Bruce Anderson) (07/31/88)
In article <525@jim.odr.oz> brw@jim.odr.oz (Brian Wallis) writes: > >Is this a bug in make, or am I just missing something obvious? >The simple example for the make file is as follows... > >| >| exe: file1.o >| ld -o exe file1.o >| >| file1.o: dir1/file1.c >| > >'Makefile' is in '.' and the file 'file1.c' is in './dir1' > >I want to make the file 'exe' from 'file1.o' in '.' where 'file1.o' >depends on './dir1/file1.c' as is stated in the Makefile. I expect >the default '.c.o:' rule to be used to generate the file 'file1.o' >from ./dir1/file1.c. > >I can get this to work by including an explicit rule for the >'file1.o' dependency, but this is a little awkward since I use mkdep >to generate the dependancies and have a large number of source files in >a large number of subdirectories. > [lots of debug output deleted] >-- >Brian Wallis (brw@jim.odr.oz) O'Dowd Research P/L. > (03) 562-0100 Fax: (03) 562-0616, > Telex: Jacobs Radio (Bayswater) 152093 I had the same problem on our HP-9000 system running HP's version of Unix, HP-UX and simply ended up using explicit rules because I couldn't figure out any other way to do it. Then I ran across a PD version of make and looked at the source (which I assume is similar in intent to the Unix version) and discovered an explanation for the behaviour experienced. Basically, when you have a dependency in the Makefile such as: test.o: test.c and don't give an explicit rule, it goes out and check the modifcation times of the two files and then determining that is needs to update test.o it goes out to itts implicit rule base and looks for a way to generate test.o. It however, *TOTALLY IGNORES* the test.c filename on the dependency line and generates the source file name from the target file name. So for example, if you have a line test.o: whatever.c it will try to make test.o from test.c NOT whatever.c even though whatever.c is in the same directory. So you can see that in the case of a subdirectory, it will go out and check the dependency of the source file in the subdirectory but then generate an entirely new name which by default is in the current directory to try to make the target out of. As far as I can tell, this is the way that the Unix make works as well.
chris@mimsy.UUCP (Chris Torek) (08/01/88)
>In article <525@jim.odr.oz> brw@jim.odr.oz (Brian Wallis) writes: >>[sample simple makefile] >>| exe: file1.o >>| ld -o exe file1.o >>| >>| file1.o: dir1/file1.c >>'Makefile' is in '.' and the file 'file1.c' is in './dir1'. >>I want to make the file 'exe' from 'file1.o' in '.' where 'file1.o' >>depends on './dir1/file1.c' as is stated in the Makefile. I expect >>the default '.c.o:' rule to be used to generate the file 'file1.o' Good so far; >>from ./dir1/file1.c. oops. In article <284@sagpd1.UUCP> banderso@sagpd1.UUCP (Bruce Anderson) writes: >[make] goes out to itts implicit rule base >and looks for a way to generate test.o. It however, *TOTALLY IGNORES* >the test.c filename on the dependency line and generates the source >file name from the target file name. This is right, but a bit misleading. Here is another makefile: foo: foo.o ld -o $@ foo.o foo.o: dir/foo.c ${CC} -c ${CFLAGS} $*.c This one has as an explicit line the same rule that appears in the default .c.o. The point is that $*.c (or $<, which works only in generic rules, so I actually modified the rule a bit) expands to `foo.c', not `dir/foo.c'. The names of the files upon which foo.o depends are irrelevant; they have nothing to do with the expansion of the various macros. Solutions to the original problem? Unless you have VPATH, there are no nice ones. Make does not deal well with directories. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
rdt@teddy.UUCP (Ron D. Thornton) (08/02/88)
In article <525@jim.odr.oz> brw@jim.odr.oz (Brian Wallis) writes: > >Is this a bug in make, or am I just missing something obvious? >The simple example for the make file is as follows... > >| >| exe: file1.o >| ld -o exe file1.o >| >| file1.o: dir1/file1.c >| > ... > I expect >the default '.c.o:' rule to be used to generate the file 'file1.o' >from ./dir1/file1.c. ... >*** Note: that file1.o DOES NOT exist but a time is returned which > is later that that returned for dir1/file1.c !!! *** ... >| 129% make -d -i exe >| doname(exe,0) >| doname(file1.o,1) >| doname(dir1/file1.c,2) >| TIME(dir1/file1.c)=585550307 >| TIME(file1.o)=585559519 <<< where the hell does this time come from!!!! >| ld -o exe file1.o >| ld:file1.o: cannot open Make has some subtle things going on. '.c.o' is an inferred or implicit rule, NOT a default rule. Inferred rules are only used when make constructs an inferred 'prerequisite' from the .SUFFIX list. Since you supplied a dependency line AND make could not build an inferred prerequisite from the .SUFFIX list, make assumed the target (file1.o) was successful and therefore assigned the current time to it. This allows constructs like: all: program_a program_b program_c to work without getting an error because the target "all" never really exists. I think you are stuck with specifying explicit rules if you move the source out of the current directory. You might think about putting the Makefile in with the sources and objects, just pushing the exe's into something other than the current directory. -Ron- rdt@genrad.com