Riken Shah
Riken Shah

Reputation: 3154

cd.. works without ONESHELL in Makefile

From docs, it is necessary to add a target in .ONESHELL to make all the commands run in a same sub-shell process. Further discussion on that is here.

This is my makefile,

.PHONY: clean build
.ONESHELL: deploy

zip := my.zip

clean:
    cd ..
    rm -f $(zip)

build: clean
    npm install .
    zip -r ../$(zip) . \
        --exclude=package-lock.json \
        --exclude=.gitignore \
        --exclude=makefile \
        --exclude=*.git* 

... more lines

So when I do make build, the zip file in the parent folder gets created. And when I do make clean(from the same directory) the zip is removed too from the parent folder. What I don't understand it since cd .. runs in an independent shell process, how does the zip in parent folder gets removed with the make clean command, since it is not included in .ONESHELL?

Version: GNU Make 4.1 on Ubuntu 18.04

Upvotes: 0

Views: 496

Answers (1)

MadScientist
MadScientist

Reputation: 100781

.ONESHELL doesn't accept prerequisites (or more accurately, it ignores them). If you define it, it's enabled for the entire makefile. It's currently not possible to specify .ONESHELL only for individual targets.

The GNU make manual says:

If the .ONESHELL special target appears anywhere in the makefile then all recipe lines for each target will be provided to a single invocation of the shell.

And just in case you're wondering: this applies to included makefiles -- if any one of the set specifies .ONESHELL:, every recipe in all of them will have it applied.

Upvotes: 6

Related Questions