0

I'm using this snippet to get all makefile variables and values:

.PHONY: test
test:
    $(foreach v,                                        \
          $(filter-out $(VARS_OLD) VARS_OLD,$(.VARIABLES)), \
          $(info $(v) = $($(v))))

But I want to write this output to a file.

None of the following works:

...$(info $(v) = $($(v)))) > myfile.txt

...$(info $(v) = $($(v))) >> myfile.txt)

ALL_MAKEFILE_VARS:; $(foreach v, $(filter-out $(VARS_OLD) VARS_OLD,$(.VARIABLES)), $(info $(v)=$($(v))))
.PHONY: test
test:
    $(file > myfile.txt,$(ALL_MAKEFILE_VARS))

echo -e $(foreach v, $(filter-out $(VARS_OLD) VARS_OLD,$(.VARIABLES)), $(info $(v)=$($(v)))) > derp.txt

Its so easy to print them, I just want to redirect that output to a file.

Edit

I'm trying to use the file function but I'm running into a few problems.

First problem isn't the file function its the target itself, this always returns make: Nothing to be done for 'test'.

VARS_OLD:= $(.VARIABLES)
.PHONY: test
test:
    $(foreach v,                                        \
          $(filter-out $(VARS_OLD) VARS_OLD,$(.VARIABLES)), \
          $(file >myfile.txt,$(v) = $($(v))))

If I remove the VARS_OLD:= $(.VARIABLES) I can get it to run but then I see this:

*** Undefined  required by target `test`.  Stop

It does create a file but it only has this content:

% cat myfile.txt 
.LIBPATTERNS = lib%.dylib lib%.a
red888
  • 27,709
  • 55
  • 204
  • 392
  • I've checked all the source code for every version of GNU Make that I have locally (versions 3.81 through 4.4.1) and I can find nothing that would print that error message _Undefined ... required by..._, or anything like it. So I have no idea what that means. – MadScientist May 09 '23 at 20:34
  • 1
    As for the "nothing to be done", that's simply because as I said below, the recipe is expanded by make BEFORE it's passed to the shell. When you use `file` like this the entire recipe expands to the empty string, so there's nothing to pass to the shell, and the message you see "Nothing to be done for test` is what make prints when ask it to build a target and there's nothing to do. If you want it to print something, add in some shell command like `echo Created file myfile.txt` or whatever. – MadScientist May 09 '23 at 20:36

1 Answers1

0

You can't do this because $(info ...) is a make function, and > redirection is a shell feature. When make goes to run a recipe it will first expand the recipe which expands all make macros and functions, then it passes the resulting string to the shell to run.

So, the info functions are all invoked by make and always write to stdout, as they're defined to do, and expand to the empty string, as they're defined to do, then the resulting recipe (just the redirection) is passed to the shell.

You have to use shell commands if you want to use shell redirection. For example:

.PHONY: test
test:
        ( :; $(foreach v,                                       \
              $(filter-out $(VARS_OLD) VARS_OLD,$(.VARIABLES)), \
              echo '$(v) = $($(v))'; ) ) >  myfile.txt

Note I didn't actually try this.

Alternatively if you have a "new enough" version of GNU Make you can investigate the $(file ...) function.

MadScientist
  • 92,819
  • 9
  • 109
  • 136
  • This obviously assumes that none of your variable names or values contain single quotes (`'`). If they do you'll have to get fancier by using `subst`. – MadScientist May 09 '23 at 20:05
  • I get this error: `( ) > myfile.txt /bin/sh: -c: line 0: syntax error near unexpected token `)' /bin/sh: -c: line 0: `( ) > myfile.txt'` – red888 May 09 '23 at 20:10
  • I was trying to find examples of the file function I could make heads or tails of, but not sure how to use it here. – red888 May 09 '23 at 20:20
  • I updated my post with my file attempts – red888 May 09 '23 at 20:25
  • That error means that no variables were returned by your `filter-out` operation. I can't say why that would be given the makefile you show here. I'll update it to avoid this error, in that case – MadScientist May 09 '23 at 20:28