WorldSEnder
WorldSEnder

Reputation: 5044

Inconsistent ifeq and ifneq

I can't figure out why in the following the two different versions yield different results:

$(INCLUDE_DIR)/%: TRGT_PATH = \
    $(INCLUDE_DIR)/$(patsubst $(word 1,$(subst /, ,$(dir $*)))/%,%,$*)
$(INCLUDE_DIR)/%: INCLUDEDS = $(TRGT_PATH)
$(INCLUDED_FILES) : $(INCLUDE_DIR)/%: %
ifeq ($(TRGT_PATH),$(findstring $(TRGT_PATH),$(INCLUDEDS)))
    @echo [INC][WARN] File $(TRGT_PATH) already exists while copying from $*
else
    @echo $(findstring $(TRGT_PATH),$(INCLUDEDS))
    @echo [INC] $* $(TRGT_PATH)
    @cp $* $(TRGT_PATH)
endif

Output:

[INC][WARN] File include/GeometricObject.h already exists while copying from engine/GeometricObject.h
[INC][WARN] File include/util.h already exists while copying from engine/util.h
[INC][WARN] File include/util.h already exists while copying from test/util.h

If I change the line ifeq ($(TRGT_PATH),$(findstring $(TRGT_PATH),$(INCLUDEDS))) to ifneq (,$(findstring $(TRGT_PATH),$(INCLUDEDS))) the output is:

include/GeometricObject.h
[INC] engine/GeometricObject.h include/GeometricObject.h
include/util.h
[INC] engine/util.h include/util.h
include/util.h
[INC] test/util.h include/util.h

As far as I know $(findstring t,l) returns the t if t is in l and else an empty string. But the output (if VAR is equals LIST) still is:

foo
bar

Can someone explain?

PS: I tested a more simple code and that worked fine...

Upvotes: 0

Views: 356

Answers (1)

MadScientist
MadScientist

Reputation: 100781

If you'd provided a complete example, including the values of VAR and LIST, we'd be able to help. As it is, all I can say is "it works for me", so you must not be accurately reporting your environment in your question:

$ cat Makefile
VAR = v
LIST = v
all:
ifneq (,$(findstring $(VAR),$(LIST)))
        @echo foo
else
        @echo bar
endif

$ make
foo

ETA:

Aha. Well, your problem has absolutely nothing to do with findstring, so it's not surprising that your original question was not answerable.

The issue is that you're trying to use target-specific variables in a non-recipe context, and the documentation clearly states that they are not available outside of recipes.

The ifeq, etc. statements are like preprocessor statements: they are evaluated as the makefile is being parsed, not later when the recipes are being invoked. So the values of TRGT_PATH and INCLUDEDS when the ifeq/ifneq is invoked are the global values of those variables (which might be the empty string if they're not set otherwise) not the target-specific values.

Upvotes: 1

Related Questions