Re: Bug 116411: tools/perf_clean: output directory does not exist. Stop.

From: TJ
Date: Fri Apr 15 2016 - 16:06:55 EST


Thanks for looking at this; I've become lost in Makefile hell trying to figure it out :)

On 15-04-2016 17:00, Arnaldo Carvalho de Melo wrote:
Em Fri, Apr 15, 2016 at 03:21:35PM +0100, TJ escreveu:
v4.6-rc3
tools/perf then tools/perf_clean fails in the source tree:
*** output directory
"/home/all/SourceCode/linux/linux/tools/perf/tools/perf/" does not exist.
Stop.
https://bugzilla.kernel.org/show_bug.cgi?id=116411

----8-<---- snip

I can reproduce the:
[acme@jouet linux]$ rm -rf ../build/perf
[acme@jouet linux]$ mkdir ../build/perf
[acme@jouet linux]$ make O=../build/perf -C tools/perf
make: Entering directory '/home/acme/git/linux/tools/perf'
BUILD: Doing 'make -j4' parallel build
../scripts/Makefile.include:3: ***
O=/home/acme/git/linux/tools/build/perf does not exist. Stop.

----8-<---- snip
git blame shows commits c883122a and bf35182f are responsible for the path
calculation code.
Thanks for narrowing it down, do you have any patch fixing this?

Over the last week I've exhaustively tried several alternative approaches, based around the idea of capturing the initial launch command-line O= value (since changing that for sub-makes is the problem here), but I've not been able to come up with a solution that works for all cases (srctree {relative,absolute} path or objtree {relative,absolute} path).

I'm also basing the command-line on the help from ./tools/Makefile which recommends:

@echo ' $$ make -C tools/ <tool>_install'

I've added extensive debugging to track the changing variables from ./tools/scripts/Makefile.include. The most successful for most situations (when starting from the base ./Makefile) captures BASE_O and then uses it for creating all paths, but the various subtle interactions of $(subdir) and the sub-makes, $(objtree), and others causes regressions such as generating output to the wrong directory.

diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include
index 8abbef1..871c183 100644
--- a/tools/scripts/Makefile.include
+++ b/tools/scripts/Makefile.include
@@ -1,7 +1,11 @@
ifneq ($(O),)
ifeq ($(origin O), command line)
- dummy := $(if $(shell test -d $(O) || echo $(O)),$(error O=$(O) does not exist),)
- ABSOLUTE_O := $(shell cd $(O) ; pwd)
+ifeq ($(BASE_O),)
+ export BASE_O := $(abspath $(if $(filter ..% .%,$(O)),$(srctree)/$(O),$(O)))
+endif
+ __T := $(info BASE_O=$(BASE_O))
+ dummy := $(if $(shell test -d $(BASE_O) || echo $(BASE_O)),$(error BASE_O=$(BASE_O) does not exist),)
+ ABSOLUTE_O := $(shell cd $(BASE_O) ; pwd)
OUTPUT := $(ABSOLUTE_O)/$(if $(subdir),$(subdir)/)
COMMAND_O := O=$(ABSOLUTE_O)
ifeq ($(objtree),)


Basing paths on BASE_O will fail (with incorrect paths) when starting the build directly with -C ./tools/ or -C ./tools/perf/ - it has felt like playing whack-a -mole!