I just need to be able to assign the value of pwd
after cd
to a variable so I can open a file in my web browser, but I can't seem to figure out how to do that in a Makefile. Interestingly, when searching other answers about people who want to get the directory of the currently-running Makefile after a cd (as opposed to what I want to do, which is get the actual current working directory regardless of where the Makefile is), doing things that they said don't work after a cd still seem to point to the Makefile, not the directory I cd'd into.
I'm running GNU Make 3.81 on Mac OS 10.15, if that matters.
This is my directory setup:
whatever/
|
├── foo/
│ ├── Makefile
│ └── make_a_file.py
└── bar/
└── Makefile
make_a_file.py generates output.txt. make_a_file.py can be run from /foo/Makefile via make bizz
, resulting in:
whatever/
|
├── foo/
│ ├── Makefile
│ ├── make_a_file.py
│ └── output.txt
└── bar/
└── Makefile
If I manually copy output.txt to the bar directory, and run /bar/Makefile's make html
, I end up with an html file in bar, i.e.,
whatever/
|
├── foo/
│ ├── Makefile
│ ├── make_a_file.py
│ └── output.txt
└── bar/
├── Makefile
├── output.txt
└── output.html
My problem is that I want to open output.html in my web browser using /foo/Makefile, but it seems that I cannot get the absolute path of /bar/output.html, so I can't call something like python -mwebbrowser file:///$(WHATEVER)/bar/output.html
or python -mwebbrowser file:///$(FULLPATH)/output.html
. I do not want to hardcode the absolute path; I can only count on bar/ and foo/ not changing their names, not necessarily anything above them.
This is what /foo/Makefile currently looks like.
bizz:
python make_a_file.py
compile:
cp outputs/outfile.txt ../bar/output.txt
cd ../bar/; \
echo "$(PWD)"; \
echo "$(shell pwd)"; \
echo "$(CURDIR)"; \
make html; \
python -mwebbrowser file:///$(CURDIR)/_build/html/output.html
Which results this when I run it from foo/:
(venv) foo user$ make compile
cp output.txt ../bar/output.txt
cd ../bar/; \
echo "/whatever/foo"; \
echo "/whatever/foo"; \
echo "/whatever/foo"; \
make html; \
python -mwebbrowser file:////whatever/foo/output.html
/whatever/foo
/whatever/foo
/whatever/foo
Running Sphinx v4.4.0
[and other miscellaneous output from the makefile in bar]
build succeeded.
0:85: execution error: File some object wasn’t found. (-43)
I know that the cd must have worked, and that the make html
must be executed in the same subshell as the cd because make html
does not work without cd'ing into bar first. And yet, all of the echos would you have believe that you are still in foo.
What's going on here? Is there a way around this without hardcoding the absolute path?
The methods you've tried are all evaluated by make
before the shell command is ever executed. You need to write a shell command that outputs the current directory, one that executes after the cd
.
The simplest option is pwd
:
compile:
cp outputs/outfile.txt ../bar/output.txt
cd ../bar/; \
pwd; \
make html; \
python -mwebbrowser file:///$$(pwd)/_build/html/output.html
Alternatively, you could delay the evaluation of $PWD
by escaping the $
so that the shell evaluates it rather than make
:
compile:
cp outputs/outfile.txt ../bar/output.txt
cd ../bar/; \
echo $$PWD; \
make html; \
python -mwebbrowser file:///$$PWD/_build/html/output.html