Home > Enterprise >  cp except a file does not work in Makefile
cp except a file does not work in Makefile

Time:12-31

The trick of using "!" to exclude a directory when using cp works under shell, but does not work in make:

mkdir db09601c && cp -r !(db09601c) db09601c
/usr/bin/bash: -c: line 0: syntax error near unexpected token ('
/usr/bin/bash: -c: line 0:mkdir db09601c && cp -r !(db09601c) db09601c'

I have put SHELL=/bin/bash on top of the Makefile already:

PROJECT_NAME=nnr
HASH=$(shell git log -n1 --pretty=format:%h)
REVS=$(shell git log --oneline|wc -l)
SHELL=/bin/bash

build:
        mkdir $(HASH) && cp -r !($(HASH)) $(HASH)
        cp INSTALL.tpl INSTALL
        sed -i 's/{_G_HASH}/$(HASH)/' INSTALL
        chmod  x INSTALL
        echo $(REVS).$(HASH) > $(HASH)/VERSION
        tar czf $(PROJECT_NAME)-$(REVS).$(HASH).tar.gz $(HASH) INSTALL
        rm -rf INSTALL $(HASH)

CodePudding user response:

The extended glob syntax is specific to Bash. If you are willing to hardcode SHELL=/bin/bash in your Makefile (this was not mentioned when you originally posted your question), you can still use this syntax (though you should probably separately verify that the extended globbing syntax is enabled with shopt -s extglob).

For a portable solution, probably simply loop over the objects:

$(HASH):
    mkdir -p $(HASH)
    for f in *; do \
        case $$f in $(HASH)) continue;; esac; \
        cp -r "$$f" $(HASH); \
    done

(For robustness, you should probably create a temporary directory, and only move it to the final destination when it is properly populated, but that's left as an exercise.)

  • Related