Subject: bin/22559: make -j can execute commands in wrong directory (not in the objdir)
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <uwe@netbsd.org>
List: netbsd-bugs
Date: 08/21/2003 00:50:52
>Number:         22559
>Category:       bin
>Synopsis:       make -j can execute commands in wrong directory (not in the objdir)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Aug 21 00:51:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     Valeriy E. Ushakov
>Release:        -current as of 2003-08-21
>Organization:
>Environment:
N/A
>Description:
When make is run with -j flag, it forks a subshell for the job abd then feed
commands to it.  If it detects that the next command is ${MAKE}, it
feeds

	test -d ${.CURDIR} && cd ${CURDIR};

first.

A side effect is that after that the job subshell will no longer be in the objdir,
so if the rule has further commands after the one with ${MAKE}, those
commands will be executed in the wrong directory: ${.CURDIR} instead
of ${.OBJDIR}.

See job.c:JobPrintCommand() and how it invokes Check_Cwd_Cmd()
near the end of that function.

>How-To-Repeat:
I found this by doing a fresh build.sh -j N with read-only sources.
It failed with

	echo /usr/nb3/tools > PREVIOUSTOOLDIR
	cannot create PREVIOUSTOOLDIR: read-only file system

because preceding command of this rule:

	${MAKE} cleandir

triggers this bug and the subshell ends up in read-only ${.CURDIR}
instead of ${.OBJDIR}

A simple test case is a makefile like this:

test:
	@/bin/pwd
	@${MAKE} submake
	@/bin/pwd

submake:
	@true

$ mkdir obj
$ nbmake MAKEOBJDIR=
/tmp/make-bug/obj
/tmp/make-bug/obj
$ nbmake MAKEOBJDIR= -j1
/tmp/make-bug/obj
/tmp/make-bug		# <- wrong directory

[And also:

$ nbmake 
/tmp/make-bug/obj
nbmake: don't know how to make submake. Stop
]
>Fix:
Possible workarounds are running make with -B flag
or changing ${MAKE} invocation in rules to be

	(cd ${.CURDIR} && ${MAKE} ... )

which turns of the "cd magic".

Arguably, in the presence of objdirs, the latter is the best/safest way
to write it in the first place...

>Release-Note:
>Audit-Trail:
>Unformatted: