'Makefile 'ifeq'/'findstring' Seemingly Incorrect String Comparison Behavior
I have several makefile variables defined similar to this ...
BUILD_DIR = build
APP_SRCS = \
./main.c \
./module1.c \
./module2.c \
etc. \
APP_OBJS = $(addprefix $(BUILD_DIR)/, $(notdir $(APP_SRCS:.c=.o)))
... and a rule defined similar to this ...
$(BUILD_DIR)/%.o: %.c
echo "---"$@"---" "---"$(findstring $@, $(APP_OBJS))"---"
ifeq ($(findstring $@, $(APP_OBJS)), $@)
echo "---App---"
else
echo "---Lib---"
endif
When this rule is executed, the if block is always executed. For example, consider the following terminal output:
---build/main.o--- ---build/main.o---
---App------build/lib1.o--- ------
---App---
In both cases, findstring works correctly. The problem I'm having is that whether the substring is found in the string or not, that is, $@ is found in $(APP_OBJS) or not, the if block is always taken. I want to use such a construct to compile application and library source files with different warning flags to mute all library warnings.
Solution 1:[1]
This statement:
ifeq ($(findstring $@, $(APP_OBJS)), $@)
is a Make conditional, and Make will evaluate before executing any rule, and therefore before the automatic variable $@ has a value. So Make expands "$@" to nothing:
ifeq ($(findstring , $(APP_OBJS)),)
the findstring returns the empty list since it didn't find a match:
ifeq (,)
and the conditional evaluates as true.
You already have one solution: use a shell conditional. Or you could use a static pattern rule:
$(APP_OBJS): $(BUILD_DIR)/%.o: %.c
echo "---"$@"---" "---"$@"---"
echo "---App---"
$(BUILD_DIR)/%.o: %.c
echo "---"$@"---" "---""---"
echo "---Lib---"
Solution 2:[2]
The following works as expected:
$(BUILD_DIR)/%.o: %.c
if test $(findstring $@, $(APP_OBJS)); then \
echo "---App---"; \
else \
echo "---Lib---"; \
fi;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Beta |
| Solution 2 |
