How to Capture Values in Command Line and Add to Recipe

How I can capture values in command line and add to recipe?

When you provision the machine by running

chef-solo

or

chef-client

you cannot provide any arguments to these commands that can be visible to recipes. Chef recipes work only with attributes. Good thing (or not so good) is that attributes can be set from many different places: roles, nodes, environments and json file.

The workaround that is nearest to your request is

  • Create a json-file on the machine
  • Pass it when running chef-client or chef-solo
  • Use attributes in the recipe

For example: apache config.

create json file: my_attrs.json

{ 
"apache": {
"listen_port": "81",
"listen_path": "/myapp"
}
}

and then use them in your recipe:

node[:apache][:listen_port]
node[:apache][:listen_path]

Run chef-client or chef-solo with -j flag.

chef-solo -j my_attrs.json

If my_attrs.json is on some remote server, then you can provide a url.

chef-solo -j http://remote.host/path/my_attrs.json

Passing additional variables from command line to make

You have several options to set up variables from outside your makefile:

  • From environment - each environment variable is transformed into a makefile variable with the same name and value.

    You may also want to set -e option (aka --environments-override) on, and your environment variables will override assignments made into makefile (unless these assignments themselves use the override directive . However, it's not recommended, and it's much better and flexible to use ?= assignment (the conditional variable assignment operator, it only has an effect if the variable is not yet defined):

    FOO?=default_value_if_not_set_in_environment

    Note that certain variables are not inherited from environment:

    • MAKE is gotten from name of the script
    • SHELL is either set within a makefile, or defaults to /bin/sh (rationale: commands are specified within the makefile, and they're shell-specific).
  • From command line - make can take variable assignments as part of his command line, mingled with targets:

    make target FOO=bar

    But then all assignments to FOO variable within the makefile will be ignored unless you use the override directive in assignment. (The effect is the same as with -e option for environment variables).

  • Exporting from the parent Make - if you call Make from a Makefile, you usually shouldn't explicitly write variable assignments like this:

    # Don't do this!
    target:
    $(MAKE) -C target CC=$(CC) CFLAGS=$(CFLAGS)

    Instead, better solution might be to export these variables. Exporting a variable makes it into the environment of every shell invocation, and Make calls from these commands pick these environment variable as specified above.

    # Do like this
    CFLAGS=-g
    export CFLAGS
    target:
    $(MAKE) -C target

    You can also export all variables by using export without arguments.

How to pass macro definition from make command line arguments (-D) to C source code?

Call make command this way:

make CFLAGS=-Dvar=42

And be sure to use $(CFLAGS) in your compile command in the Makefile. As @jørgensen mentioned , putting the variable assignment after the make command will override the CFLAGS value already defined the Makefile.

Alternatively you could set -Dvar=42 in another variable than CFLAGS and then reuse this variable in CFLAGS to avoid completely overriding CFLAGS.

How to pass argument to Makefile from command line?

You probably shouldn't do this; you're breaking the basic pattern of how Make works. But here it is:

action:
@echo action $(filter-out $@,$(MAKECMDGOALS))

%: # thanks to chakrit
@: # thanks to William Pursell

EDIT:

To explain the first command,

$(MAKECMDGOALS) is the list of "targets" spelled out on the command line, e.g. "action value1 value2".

$@ is an automatic variable for the name of the target of the rule, in this case "action".

filter-out is a function that removes some elements from a list. So $(filter-out bar, foo bar baz) returns foo baz (it can be more subtle, but we don't need subtlety here).

Put these together and $(filter-out $@,$(MAKECMDGOALS)) returns the list of targets specified on the command line other than "action", which might be "value1 value2".

How to assign the output of a command to a Makefile variable

Use the Make shell builtin like in MY_VAR=$(shell echo whatever)

me@Zack:~$make
MY_VAR IS whatever

me@Zack:~$ cat Makefile 
MY_VAR := $(shell echo whatever)

all:
@echo MY_VAR IS $(MY_VAR)

Makefile: How can I store and manipulate the current target/recipe/rule's value?

Thanks to Etan for pointing out that I messed up the syntax. It should be $(eval ...) instead of @(eval ...). This is the most direct solution to my problem.

The relevant part of my recipe now looks like this:

$(CLEANLIST):
$(eval REALTARGET=$(@:clean-%=%))
#...derive some exported variable values from REALTARGET for use by secondary.mk...
$(MAKE) -f secondary.mk clean

Can I pass variables to be rendered by erb from the command line?

As of Ruby 2.2 you can set local variables in Erb from the command line.

You would need to change your code to use local variables rather than instance variables. For example if you had (stripped down from your code):

<VirtualHost <%= http_host %>:<%= http_port %>>

You could then call it with:

$ erb http_host=http://example.com http_port=1234 my_file.erb

and the result would be:

<VirtualHost http://example.com:1234>

Passing arguments to make run

I don't know a way to do what you want exactly, but a workaround might be:

run: ./prog
./prog $(ARGS)

Then:

make ARGS="asdf" run
# or
make run ARGS="asdf"


Related Topics



Leave a reply



Submit