How to get $ (error ...) to work conditionally in GNU Make?

I would like to use $(error ...)to abort my make process if some of the preconditions are not met. The target fails_to_workshould be interrupted on error test -d /foobar.

BAD.mk

all: this_works fails_to_work

this_works:
        @echo echo works...
        @test -d ~ || echo ~ is not a directory
        @test -d /foobar || echo /foobar is not a directory

fails_to_work:
        @echo error does not work...
        @test -d ~ || $(error ~ is not a directory)
        @test -d /foobar || $(error /foobar is not a directory)

$ make -f BAD.mk

echo works...
/foobar is not a directory
BAD.mk:9: *** ~ is not a directory.  Stop.

As you can see, even the "error does not work ..." is displayed on the screen. The recipe fails_to_workdoes not work until it begins. How can i solve this? One of my use cases is @test -d $(MY_ENV_VAR), but I don't think this is different from the hard-coded paths given in the example.

UPDATE (version information)

$ make --version

GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for x86_64-pc-linux-gnu
+5
source share
3 answers

, makefile, , .

:

  • $(error). test , , Make .

  • (, , ), :

    ifeq ($(shell test -d /foobar; echo $$?),1)
    $(error Not a directory)
    endif
    
+5

make . make , , . $(error ...), , make .

, a $(if ...) $(or ...) & c. . ,

.PHONY: rule-with-assert
rule-with-assert:
    $(if $(realpath ${should-be-file}/),$(error Assertion failure: ${should-be-file} is a folder!))

, / realpath.

, .

assert-is-file = $(if $(realpath $1/),$(error Assertion failure: [$1] is a folder!))

.PHONY: rule-with-assert
rule-with-assert:
    $(call assert-is-file,${should-be-file})

, , $(call assert-is-file,…) . $(error) , .

+5

Why don't you just use the exit 1shell command instead $(error ...)? Is there a reason to use the latter?

try_this:
    @test -d /foobar || { echo /foobar is not a directory; exit 1; }

or_this:
    @if [ ! -d /foobar ]; then echo /foobar is not a directory; exit 1; fi

Both of them will abort the make process if -kflag is not specified .

-k --keep-going

Continue as many errors as possible after the error. Although a goal that has failed, and those that depend on it, cannot be redone, other prerequisites for these goals can be handled anyway.

0
source

All Articles