ifeq problem?

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

ifeq problem?

S Tao
Hi, I wrote a make target "test-test" as below. my intention is to assign 1/2 to v1/v2 respectively.  However, when I run command "make test-test", I am getting "v1 == v2". Why? What workaround is available to achieve what I want to do here? Thank you very much for your helps.

test-test:
    $(eval v1=$(shell sh -c "echo 1"))
    $(eval v2=$(shell sh -c "echo 2"))
    @echo "v1=$(strip $(v1))="
    @echo "v2=$(strip $(v2))="
ifeq ("$(strip $(v1))", "$(strip $(v2))")
    @echo "v1 == v2"
endif
.PHONY: test-test



_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: ifeq problem?

Philip Guenther-2
On Mon, Oct 1, 2018 at 8:17 PM S Tao <[hidden email]> wrote:

> Hi, I wrote a make target "test-test" as below. my intention is to assign
> 1/2 to v1/v2 respectively.

However, when I run command "make test-test", I am getting "v1 == v2". Why?


You should read GNU make info pages, section 3.7 "How `make' Reads a
Makefile".  It describes there how GNU make processing is a two phase
process and how various places in the makefile syntax are handled in one
phase, the other, or both.  Your makefile tries to have something done in
phase 2 (all expansion processing from a recipe) affect processing in stage
1 (ifeq directives) which cannot work.  Do read that section so you
understand these phases and how that affects these limitations.


> What workaround is available to achieve what I want to do here? Thank you
> very much for your helps.
>

You have three options:
A) set v1 and v2 outside of the recipes, so that the ifeq directive can
test them.  Only works if they're the same for all recipes.

B) instead of an ifeq directive which happens in phase 1, use $(if) with
text functions like $(findstring) to perform the equality comparison.
Depending on what v1 and v2 might contain in the full setup, testing
equality can be easy or difficult.

C) do what everyone has done for 40 years: use shell conditionals, ala @ if
[ "$(v1)" = "$(v2)" ]; then echo...; fi


Philip Guenther
_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: ifeq problem?

Paul Smith-20
In reply to this post by S Tao
On Tue, 2018-10-02 at 03:23 +0000, S Tao wrote:
> test-test:
>     $(eval v1=$(shell sh -c "echo 1"))
>     $(eval v2=$(shell sh -c "echo 2"))
>     @echo "v1=$(strip $(v1))="
>     @echo "v2=$(strip $(v2))="
> ifeq ("$(strip $(v1))", "$(strip $(v2))")
>     @echo "v1 == v2"
> endif
> .PHONY: test-test

Using 'eval' and 'shell' functions inside a recipe is an anti-pattern.

It can be useful in advanced situations that you likely won't run into
until you've been writing complex makefiles for a long time.  You
should avoid it until that time.

Philip's answer is right on as to where you should go to read more
about why this doesn't work, but for this:

> C) do what everyone has done for 40 years: use shell conditionals,
> ala @ if [ "$(v1)" = "$(v2)" ]; then echo...; fi

I would go farther and say the ENTIRE rule should be rewritten using
the shell without any 'eval' or 'shell' make functions, as in:

  test-test:
        @v1=1; \
         v2=2; \
         if [ $$v1 = $$v2 ]; then echo 'v1 == v2'; fi

Of course when written this way this recipe isn't really useful, so it
would be better if instead you asked us about the problem you're really
trying to solve.

Cheers!


_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: ifeq problem?

S Tao
Thank you very much Paul and Philip. I still need to read what you pointed out.

What I want is very straightforward. during make/build process, I want to run a shell command to extract two numbers from two different files. If they are same(or different), then I do something.

That is why my prototype uses echo to get the number?

$(eval v1=$(shell sh -c "echo 1"))

________________________________
From: Paul Smith <[hidden email]>
Sent: Tuesday, October 2, 2018 7:04 AM
To: S Tao; [hidden email]
Subject: Re: ifeq problem?

On Tue, 2018-10-02 at 03:23 +0000, S Tao wrote:
> test-test:
>     $(eval v1=$(shell sh -c "echo 1"))
>     $(eval v2=$(shell sh -c "echo 2"))
>     @echo "v1=$(strip $(v1))="
>     @echo "v2=$(strip $(v2))="
> ifeq ("$(strip $(v1))", "$(strip $(v2))")
>     @echo "v1 == v2"
> endif
> .PHONY: test-test

Using 'eval' and 'shell' functions inside a recipe is an anti-pattern.

It can be useful in advanced situations that you likely won't run into
until you've been writing complex makefiles for a long time.  You
should avoid it until that time.

Philip's answer is right on as to where you should go to read more
about why this doesn't work, but for this:

> C) do what everyone has done for 40 years: use shell conditionals,
> ala @ if [ "$(v1)" = "$(v2)" ]; then echo...; fi

I would go farther and say the ENTIRE rule should be rewritten using
the shell without any 'eval' or 'shell' make functions, as in:

  test-test:
        @v1=1; \
         v2=2; \
         if [ $$v1 = $$v2 ]; then echo 'v1 == v2'; fi

Of course when written this way this recipe isn't really useful, so it
would be better if instead you asked us about the problem you're really
trying to solve.

Cheers!

_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: ifeq problem?

thutt
F L writes:
 > Thank you very much Paul and Philip. I still need to read what you pointed out.
 >
 > What I want is very straightforward. during make/build process, I
 > want to run a shell command to extract two numbers from two
 > different files. If they are same(or different), then I do
 > something.
 >
 > That is why my prototype uses echo to get the number?
 >
 > $(eval v1=$(shell sh -c "echo 1"))
 >

 I think you could do what you want with standard utilities without
 resorting to $(shell).

  o Make recipe to extract number from first file.

    Write to intermediate file.

  o Make recipe to extract number from second file.

    Write to intermediate file.

  o Compare two files.

  For example, something like this:

  extract-1 extract-2:
      <command> >$@

  comparison:  extract-1 extract-2
     if diff extract-1 extract-2 ; then
       echo "Files same";
     else
       echo "Files differ";
     fi

_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make
Reply | Threaded
Open this post in threaded view
|

Re: ifeq problem?

Paul Smith-20
In reply to this post by S Tao
On Tue, 2018-10-02 at 15:20 +0000, F L wrote:

> Thank you very much Paul and Philip. I still need to read what you
> pointed out.
>
> What I want is very straightforward. during make/build process, I
> want to run a shell command to extract two numbers from two different
> files. If they are same(or different), then I do something.
>
> That is why my prototype uses echo to get the number?
>
> $(eval v1=$(shell sh -c "echo 1"))

OK, but you don't need to set make variables, or use make shell
functions.  A recipe is run by the shell already and the shell is a
complete programming language (more complete than makefile language!)
so you can just use shell commands directly and set shell variables.

Also, $(shell sh -c "echo 1") is redundant because the make shell
function starts a shell, then you are asking that shell to run another
shell ("sh -c") and asking that second shell to run the "echo 1"
command.

You can get rid of one shell by just saying: $(shell echo 1) rather
than starting a new shell with "sh -c".

But it's simpler by far (IMO) to simply use the recipe, which is
already in a shell, and write shell syntax:

  testrule:
          v1=`echo 1`; \
          v2=`echo 2`; \
          if [ "$$v1" = "$$v2" ]; then echo "v1 == v2"; fi



_______________________________________________
Help-make mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-make