Mail Archives: djgpp/2000/03/06/06:52:58
On Mon, 6 Mar 2000, Jason Green wrote:
> -------- makefile --------
> all:
> cd sub1; make
> cd sub2; make
[snip]
> Here's what happens when make is run:
>
> D:\Tmp>make
> cd sub1; make
> make.exe[1]: Entering directory `d:/tmp/sub1'
> touch test1
> make.exe[1]: Leaving directory `d:/tmp/sub1'
> cd sub2; make
> make.exe: *** [all] Error -1
This is a feature ;-).
On DOS and Windows, the current working directory is a global
variable: it affects all the programs running in the current Virtual
Machine. In contrast, on Unix and Linux, the current directory is
local to each process.
Your Makefile assumes that the current directory is restored after
each command line finishes. That is, after "cd sub1; make" exits, you
assume you are back in the directory where you started. This is
indeed so on Linux, but not on DOS/Windows.
While it would be possible for ported Make to return to the original
directory after running a command, it is not done on purpose, because
this would break lots of Makefiles of the DOS origin that rely on the
current directory being global. One of the reasons that DOS Makefiles
need to rely on that is that DOS shells don't support multiple
commands on the same line separated by a semi-colon (the fact that it
works in the DJGPP port of Make is an extra-special feature of the
DJGPP library function `system'). So the only way for a DOS Makefile
to chdir into another directory and do something there was as in the
following snippet:
foo: bar
cd foobar
do-something
There are lots of Makefiles out there which use this, and we don't
break them.
If you want a Makefile that will work on DOS/Windows and Linux alike,
you need to return to the original directory explicitly, like this:
all:
cd sub1; make; cd ..
cd sub2; make; cd ..
Alternatively, force Bash to be the shell used by Make, in which case
Bash will return to the original directory after running each command
line. With the DJGPP port of Make, you need to put the following line
in you Makefile, to force Make use Bash:
SHELL = /bin/sh
(This will only have the desired effect if Bash is actually installed
on the machine where the Makefile runs.)
However, this last method will probably break with non-DJGPP ports of
Make.
> The problem does not exist if make recursion is done correctly:
>
> -------- makefile --------
> all:
> $(MAKE) -C sub1
> $(MAKE) -C sub2
Right. This is because, when invoked with the -C switch, Make *does*
return to the original directory before exiting.
If you can rely on GNU Make (other Make's don't have the -C switch),
it is better to use "make -C" to recurse into subdirectories.
- Raw text -