1

I recently wrote a Makefile instruction for compiling .proto files and ran into odd behavior.

This command works when running in my own shell, but when inside a Makefile target...

    protoc \
        --proto_path ./protos \
        --go_out ./protos/gen \
        --go_opt paths=source_relative \
        --go-grpc_out ./protos/gen \
        --go-grpc_opt paths=source_relative \
        ./protos/**/*.proto

...it fails with:

Could not make proto path relative: ./protos/**/*.proto: No such file or directory

However, this does work inside the Makefile:

    protoc \
        --proto_path ./protos \
        --go_out ./protos/gen \
        --go_opt paths=source_relative \
        --go-grpc_out ./protos/gen \
        --go-grpc_opt paths=source_relative \
        $(shell find ./protos -name '*.proto')

The only difference is the last argument.

Specifically, inside the Makefile:

  • This correctly expands all the files: $(shell find ./protos -name '*.proto')
  • But, this does not: ./protos/**/*.proto

My question is How come the expansion of files via ./protos/**/*.proto does not work with Make?

Joe B
  • 1,261
  • 14
  • 20

1 Answers1

3

Because make invokes /bin/sh as its shell, and /bin/sh is a POSIX shell which does not support ** as a globbing operation.

Using ** to mean "search all subdirectories" is non-standard, extra feature of some shells like bash, etc.

MadScientist
  • 92,819
  • 9
  • 109
  • 136