How to pass argument to Makefile from command line?

后端 未结 5 997
慢半拍i
慢半拍i 2020-11-28 00:52

How to pass argument to Makefile from command line?

I understand I can do

$ make action VAR=\"value\"
$ value

with Makefile

相关标签:
5条回答
  • 2020-11-28 01:25

    Few years later, want to suggest just for this: https://github.com/casey/just

    action v1 v2=default:
        @echo 'take action on {{v1}} and {{v2}}...'
    
    0 讨论(0)
  • 2020-11-28 01:30

    don't try to do this

    $ make action value1 value2
    

    instead create script:

    #! /bin/sh
    # rebuild if necessary
    make
    # do action with arguments
    action "$@"
    

    and do this:

    $ ./buildthenaction.sh value1 value2
    

    for more explanation why do this and caveats of makefile hackery read my answer to another very similar but seemingly not duplicate question: Passing arguments to "make run"

    0 讨论(0)
  • 2020-11-28 01:35

    Much easier aproach. Consider a task:

    provision:
            ansible-playbook -vvvv \
            -i .vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory \
            --private-key=.vagrant/machines/default/virtualbox/private_key \
            --start-at-task="$(AT)" \
            -u vagrant playbook.yml
    

    Now when I want to call it I just run something like:

    AT="build assets" make provision

    or just:

    make provision in this case AT is an empty string

    0 讨论(0)
  • 2020-11-28 01:50

    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".

    0 讨论(0)
  • 2020-11-28 01:51

    Here is a generic working solution based on @Beta's

    I'm using GNU Make 4.1 with SHELL=/bin/bash atop my Makefile, so YMMV!

    This allows us to accept extra arguments (by doing nothing when we get a job that doesn't match, rather than throwing an error).

    %:
        @:
    

    And this is a macro which gets the args for us:

    args = `arg="$(filter-out $@,$(MAKECMDGOALS))" && echo $${arg:-${1}}`
    

    Here is a job which might call this one:

    test:
        @echo $(call args,defaultstring)
    

    The result would be:

    $ make test
    defaultstring
    $ make test hi
    hi
    

    Note! You might be better off using a "Taskfile", which is a bash pattern that works similarly to make, only without the nuances of Maketools. See https://github.com/adriancooney/Taskfile

    0 讨论(0)
提交回复
热议问题