'Check if a file is inside a list of files in makefile
how are you?
I have a simple task and i'm failing at it. I have a list of source files that is in GCOV_SOURCES. A small examples of how this list is declared:
GCOV_SOURCES = \
build/main.lst \
build/cmox_low_level.lst \
And it goes on with the rest of the files. What i need to do is to check when the files in GCOV_SOURCES are been built. The makefile i'm using interacts over the C_SOURCES file to build one by one. What i need is to check if the currently file been built is inside of GCOV_SOURCES. I tried the following but no success yet. My biggest problem is the conditional. Find string is able to actually find the file been built inside the list (printed in the first info), but i'm never able to check findstring return in the ifeq conditional. Already tried to use empty values in the conditional, but none of them actually worked either.
$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
$(info *********$(findstring $(BUILD_DIR)/$(notdir $(<:.c=.lst)), $(GCOV_SOURCES))**********)
ifneq ($(strip $(findstring $(BUILD_DIR)/$(notdir $(<:.c=.lst)), $(GCOV_SOURCES))),$(BUILD_DIR)/$(notdir $(<:.c=.lst)))
$(info *** FIND IT $(BUILD_DIR)/$(notdir $(<:.c=.lst))***)
$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
else
$(info *** DIDN'T FIND IT ***)
$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
endif
Solution 1:[1]
You cannot mix and match ifeq/ifneq inside recipes like this. Makefiles are managed in two steps: first all the makefiles are parsed. That means everything in your makefiles that IS NOT indented with a TAB, is expanded and parsed. Second all the recipes for out of date files are run. That means everything in your makefiles that IS indented with a TAB is expanded now. Also, automatic variables like $< that are only valid when building a particular target are set during this second step.
So, it's never possible to use ifeq (which is always parsed during the first step) to reference automatic variables like $< (which is only set during the second step). The value of $< will always be empty.
You have to use shell conditionals, not makefile conditionals, and indent with TAB characters, if you want to test values that are only set during the second phase (building targets). You also cannot use $(info ...) inside shell if-statements, because it's expanded before the shell is invoked so you'll see ALL the info output regardless whether the shell condition is true or false.
Also, it's not a great idea to use findstring here because that looks for substrings, so it will find foo in a string foobar. Better is to use filter (or filter-out if you want the inverse) which matches entire words.
Something like:
$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
$(info *********$(filter $(BUILD_DIR)/$(notdir $(<:.c=.lst)), $(GCOV_SOURCES))**********)
if test -n '$(strip $(filter $(BUILD_DIR)/$(notdir $(<:.c=.lst)), $(GCOV_SOURCES)))'; then \
echo '*** FIND IT $(BUILD_DIR)/$(notdir $(<:.c=.lst))***'; \
$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@; \
else \
echo '*** DIDN'T FIND IT ***'; \
$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@; \
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 |
