最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

makefile - Finding substring in variable name - Stack Overflow

programmeradmin0浏览0评论

I'm trying to check if a variable contains a particular string. I've tried a solution posted here: Makefile : contains string but in my case it does not seem wot work.

@echo $(findstring 2025, $(basename $(<F)))`

returns 2025, but :

ifeq ($(findstring 2025, $(basename $(<F))),2025)
    @echo $(findstring 2025, $(basename $(<F)))
endif

does not return 2025. Why?

I'm trying to check if a variable contains a particular string. I've tried a solution posted here: Makefile : contains string but in my case it does not seem wot work.

@echo $(findstring 2025, $(basename $(<F)))`

returns 2025, but :

ifeq ($(findstring 2025, $(basename $(<F))),2025)
    @echo $(findstring 2025, $(basename $(<F)))
endif

does not return 2025. Why?

Share Improve this question asked Feb 3 at 18:55 Jeremy L.Jeremy L. 1381 silver badge12 bronze badges 0
Add a comment  | 

2 Answers 2

Reset to default 1

If you want help, especially with makefiles, you have to provide a minimal but fully-functioning example. Makefiles are extremely context dependent, so often how something behaves depends entirely on where in the makefile it appears: is it in a recipe? In a variable assignment? Etc.

In your case, you're using ifeq and since you don't say that you got a syntax error it must be that this is not in a recipe. ifeq is a make keyword not a valid shell command, so it can't be in a recipe.

If you check the documentation for automatic variables like $(<F) you'll find that they are only set in a recipe context. So you can't ever use automatic variables in ifeq conditionals: they will always be the empty string.

Without more information on what you want to do, that's about all we can say.

Your problem has to do with the stages of makefile running. I'm assuming you're running something like this:

file:=file2025.c


all: $(file)
        @echo "building $@ (echo)  F=$(<F)"
        $(info building $@ (info)  F=$(<F))
ifeq ($(findstring 2025, $(basename $(<F))),2025$(info processing ifeq... F=[$(<F)]))
        $(info this is not run, as it is ifeqed out)
        @echo "2: (in ifeq)" $(findstring 2025, $(basename $(<F)))
endif


.PHONY: $(file)

This outputs:

> make
processing ifeq... <F=[]
building all (info)
building all (echo)
1: 2025

Explanation:

Note: $(info)'s are makefile constructs -- they expand to nothing, but they have the side effect of spitting out text to the console at the point they are expanded. (this means I can stick a $(info...) to the end of the ifeq without effecting what it does... It will output something at the point the ifeq is evaluated).

Make will start by parsing everything in the global context (lines that do not start with a tab...). Once it's done this, it decides what recipes to run etc, it will parse the recipe lines right before it runs the recipe, and then execute them.

In this case, notice that the ifeq statement is parsed before the recipe is even being considered to run because it does not start with a tab. At this time $(<F) is blank, and nothing within the ifeq is expanded.

You should also notice that the output from the info is run before the output of the echo, as the $(info) is expanded before the recipe is actually run.

The long and the short of it is, that you should avoid using makefile conditionals within recipes, unless you really know what your doing. A better approach would be to use your makefile variables in a bash conditional within the recipe as so:

all2: $(file)
    @echo building $@ -- F=$(<F)
    @if [ $(findstring 2025, $(basename $(<F))) ]; then \
         echo "file has 2025" \
     fi
发布评论

评论列表(0)

  1. 暂无评论