将参数传递给“make run”

发布于 2024-08-21 01:07:54 字数 291 浏览 3 评论 0原文

我使用 Makefile。

我有一个名为 run 的目标,它运行构建目标。简单来说,它看起来像下面这样:

prog: ....
  ...

run: prog
  ./prog

有什么方法可以传递参数吗?以便

make run asdf --> ./prog asdf
make run the dog kicked the cat --> ./prog the dog kicked the cat

I use Makefiles.

I have a target called run which runs the build target. Simplified, it looks like the following:

prog: ....
  ...

run: prog
  ./prog

Is there any way to pass arguments? So that

make run asdf --> ./prog asdf
make run the dog kicked the cat --> ./prog the dog kicked the cat

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(17

无尽的现实 2024-08-28 01:07:54

我不知道有什么方法可以准确地完成您想要的操作,但解决方法可能是:

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

然后:

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

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"
沧笙踏歌 2024-08-28 01:07:54

如果您使用 GNU make,这很容易做到。唯一的问题是 make 会将命令行中的非选项参数解释为目标。解决方案是将它们变成不执行任何操作的目标,因此 make 不会抱怨:

# If the first argument is "run"...
ifeq (run,$(firstword $(MAKECMDGOALS)))
  # use the rest as arguments for "run"
  RUN_ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
  # ...and turn them into do-nothing targets
  $(eval $(RUN_ARGS):;@:)
endif

prog: # ...
    # ...

.PHONY: run
run : prog
    @echo prog $(RUN_ARGS)

运行此命令会给出:

$ make run foo bar baz
prog foo bar baz

If you're using GNU make, this is easy to do. The only problem is that make will interpret non-option arguments in the command line as targets. The solution is to turn them into do-nothing targets, so make won't complain:

# If the first argument is "run"...
ifeq (run,$(firstword $(MAKECMDGOALS)))
  # use the rest as arguments for "run"
  RUN_ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
  # ...and turn them into do-nothing targets
  $(eval $(RUN_ARGS):;@:)
endif

prog: # ...
    # ...

.PHONY: run
run : prog
    @echo prog $(RUN_ARGS)

Running this gives:

$ make run foo bar baz
prog foo bar baz
复古式 2024-08-28 01:07:54

TL;DR 不要尝试这样做,

$ make run arg

而是创建脚本 build_and_run_prog.sh

#! /bin/sh
# rebuild prog if necessary
make prog
# run prog with some arguments
./prog "$@"

并执行以下操作:

$ ./build_and_run_prog.sh arg

继续阅读以了解为什么这是最合理的选择以及原因最好避免其他替代方案


回答所述问题:如何将参数传递给 make 目标

您可以在配方中使用变量

run: prog
    ./prog $(var)

,然后传递变量赋值作为参数以使其

$ make run var=arg

执行./prog arg.

这是“将参数传递给菜谱”的最正确和最直接的方法。 gnu make 手册

请参阅 关于覆盖变量的 可以用于运行带有参数的程序,但它当然不应该这样使用。

让我详细说明一些问题,

您想要做的是使用参数 arg 运行 prog。但不是写:

$ ./prog arg

你需要写:

$ make run var=arg

当尝试传递多个参数或包含空格的参数时,这会变得更加尴尬。

写而不是写

$ ./prog foo "bar baz"

你需要

$ make run var="foo bar\ baz"

,否则

$ make run var="foo \"bar baz\""

我希望你看到除了最简单的论点之外的任何事情都会变得非常尴尬。

另请注意,不应将 $(var) 放在 makefile 中的引号中:

run: prog
    ./prog "$(var)"

因为这样 prog 将始终只获得一个参数。


回答您的问题背后的假定意图:您希望使用一些参数运行 prog,但如果需要,请在运行之前重建它。

创建一个脚本,必要时进行重建,然后使用参数运行 prog

build_and_run_prog.sh

#! /bin/sh
# rebuild prog if necessary
make prog
# run prog with some arguments
./prog "$@"

该脚本的意图非常明确。它使用 make 来做它擅长的事情:构建/编译。它使用 shell 脚本来做它擅长的事情:批处理。

另外,您可以利用 shell 脚本的完全灵活性和表现力来完成您可能需要的任何其他操作,而无需 makefile 的所有注意事项。

此外,调用语法现在实际上是相同的:

$ ./build_and_run_prog.sh foo "bar baz"

相比:

$ ./prog foo "bar baz"

$ make run var="foo bar\ baz"

ma​​ke 如何处理参数的背景说明相比:

Make 的设计目的不是将参数传递给目标。命令行上的所有参数都被解释为目标(也称为目标)、选项或变量赋值。

因此,如果您运行此命令:

$ make run foo --wat var=arg

make 会将 runfoo 解释为目标(targets),以根据其配方进行更新。 --wat 作为 make 的选项。以及 var=arg 作为 make 的变量赋值。

我希望您能看到从命令行传递信息以在配方中使用(无需黑客)的唯一方法是通过变量赋值。

更多详细信息,请参阅有关如何运行 make 的 gnu 手册


有关 完整性这里是一些“传递参数以运行”的技巧。

方法一

run: prog
    ./prog $(filter-out $@, $(MAKECMDGOALS))

%:
    @true

超简短说明:从目标列表中过滤掉当前目标。然后将目标列表作为参数传递给 prog。还创建一个捕获所有目标(%),它不执行任何操作来默默地忽略所有其他“目标”。

这将允许您编写类似

$ make run arg1 arg2

方法 1 的问题的内容:

  • 以破折号开头的参数将由 make 解释,并且不会作为目标传递。

     $ make run --foo --bar
    

    解决方法

     $ make run -- --foo --bar
    
  • 带有等号的参数将由make解释并且不会被传递

     $ make run foo=bar
    

    没有解决办法

  • 带有空格的参数很尴尬

     $ make run foo "bar\ baz"
    

    没有解决办法

  • 如果一个参数恰好被运行(等于目标),它也将被删除

    <代码> $ make run foo bar run
    

    将运行./prog foo bar而不是./prog foo bar run

    可以使用方法 2 来解决

  • 如果参数是合法目标,它也将运行。

     $ make run foo bar clean
    

    将运行./prog foo bar clean,但也会运行目标clean的配方(假设它存在)。

    可以使用方法 2 来解决

  • 当您错误输入合法目标时,由于捕获所有目标,该目标将被静默忽略。

    <前><代码> $ make celan

    只会默默地忽略celan

    解决方法是让一切变得冗长。所以你看看会发生什么。但这会给合法输出带来很多噪音。

方法2

ifeq (run, $(firstword $(MAKECMDGOALS)))
  runargs := $(wordlist 2, $(words $(MAKECMDGOALS)), $(MAKECMDGOALS))
  $(eval $(runargs):;@true)
endif

run:
    ./prog $(runargs)

超简短说明:如果目标是run,则处理目标列表并保存在变量中。还可以使用eval为剩余的“目标”创建不执行任何操作的目标。稍后在运行 prog 时将准备好的变量作为参数传递。

方法 2 的问题

  • 如果参数与现有目标同名,那么 make 将打印一条警告,指出它正在被覆盖。

    据我所知,没有解决方法

  • 带有等号的参数仍将被 make 解释并且不会被传递

    没有解决办法

  • 带有空格的参数仍然很尴尬

    没有解决办法

  • 带空格的参数eval尝试创建不执行任何操作的目标。

    解决方法:创建全局捕获所有目标,如上所述,不执行任何操作。对于上述问题,它会再次默默地忽略输入错误的合法目标。

  • 它使用eval在运行时修改makefile。在可读性和可调试性以及最小惊讶原则方面你还能差多少。

    解决方法:不要!

我只使用 gnu make 进行了测试。其他品牌可能有不同的行为。


gnu make 手册

https://www.gnu.org/software/make/手册/html_node/index.html

TL;DR don't try to do this

$ make run arg

instead create script build_and_run_prog.sh:

#! /bin/sh
# rebuild prog if necessary
make prog
# run prog with some arguments
./prog "$@"

and do this:

$ ./build_and_run_prog.sh arg

Read on for some explanation of why this is the most reasonable choice and why the other alternatives are best avoided


Answer to the stated question: how to pass arguments to a make target

you can use a variable in the recipe

run: prog
    ./prog $(var)

then pass a variable assignment as an argument to make

$ make run var=arg

this will execute ./prog arg.

this is the most correct and straightforward way to "pass arguments to a recipe". see the gnu make manual on overriding variables

but while it can be used to run a program with arguments it is certainly not meant to be used that way.

Let me elaborate on some problems

what you want to do is run prog with argument arg. but instead of writing:

$ ./prog arg

you need to write:

$ make run var=arg

this gets even more awkward when trying to pass multiple arguments or arguments containing spaces.

instead of writing

$ ./prog foo "bar baz"

you need to write

$ make run var="foo bar\ baz"

or

$ make run var="foo \"bar baz\""

i hope you see how this will get quite awkward for anything but the simplest arguments.

also note that you should not put $(var) in quotes in the makefile:

run: prog
    ./prog "$(var)"

because then prog will always get just one argument.


Answer to the assumed intention behind your question: You want to run prog with some arguments but have it rebuild before running if necessary.

Create a script which rebuilds if necessary then runs prog with args

build_and_run_prog.sh:

#! /bin/sh
# rebuild prog if necessary
make prog
# run prog with some arguments
./prog "$@"

This script makes the intention very clear. It uses make to do what it is good for: building/compiling. It uses a shell script to do what it is good for: batch processing.

Plus you can do whatever else you might need with the full flexibility and expressiveness of a shell script without all the caveats of a makefile.

Also the calling syntax is now practically identical:

$ ./build_and_run_prog.sh foo "bar baz"

compared to:

$ ./prog foo "bar baz"

contrast to

$ make run var="foo bar\ baz"

Background explanation of how make handles arguments:

Make is not designed to pass arguments to a target. All arguments on the command line are interpreted either as a goal (a.k.a. target), as an option, or as a variable assignment.

so if you run this:

$ make run foo --wat var=arg

make will interpret run and foo as goals (targets) to update according to their recipes. --wat as an option for make. And var=arg as a variable assignment for make.

i hope you can see the only method you have to pass information from the command line to use inside a recipe (without hacks) is via variable assignment.

for more details see the gnu manual on how to run make


For completeness here are some of the hacks to "pass arguments to make run".

Method 1:

run: prog
    ./prog $(filter-out $@, $(MAKECMDGOALS))

%:
    @true

super short explanation: filter out current goal from list of goals. then pass list of goals as arguments to prog. also create a catch all target (%) which does nothing to silently ignore all the other "goals".

this will allow you to write something like this

$ make run arg1 arg2

problems of method 1:

  • Arguments that start with a dash will be interpreted by make and not passed as a goal.

      $ make run --foo --bar
    

    workaround

      $ make run -- --foo --bar
    
  • Arguments with an equal sign will be interpreted by make and not passed

      $ make run foo=bar
    

    no workaround

  • Arguments with spaces is awkward

      $ make run foo "bar\ baz"
    

    no workaround

  • If an argument happens to be run (equal to the target) it will also be removed

      $ make run foo bar run
    

    will run ./prog foo bar instead of ./prog foo bar run

    workaround possible with method 2

  • If an argument is a legitimate target it will also be run.

      $ make run foo bar clean
    

    will run ./prog foo bar clean but also the recipe for the target clean (assuming it exists).

    workaround possible with method 2

  • When you mistype a legitimate target it will be silently ignored because of the catch all target.

      $ make celan
    

    will just silently ignore celan.

    workaround is to make everything verbose. so you see what happens. but that creates a lot of noise for the legitimate output.

Method 2:

ifeq (run, $(firstword $(MAKECMDGOALS)))
  runargs := $(wordlist 2, $(words $(MAKECMDGOALS)), $(MAKECMDGOALS))
  $(eval $(runargs):;@true)
endif

run:
    ./prog $(runargs)

super short explanation: if the target is run then process the goal list and save in variable. also create do nothing targets for the remaining "goals" using eval. later when running prog pass the prepared variable as arguments.

problems of method 2:

  • If an argument has same name as an existing target then make will print a warning that it is being overwritten.

    no workaround that I know of

  • Arguments with an equal sign will still be interpreted by make and not passed

    no workaround

  • Arguments with spaces is still awkward

    no workaround

  • Arguments with space breaks eval trying to create do nothing targets.

    workaround: create the global catch all target doing nothing as above. with the problem as above that it will again silently ignore mistyped legitimate targets.

  • it uses eval to modify the makefile at runtime. how much worse can you go in terms of readability and debugability and the Principle of least astonishment.

    workaround: don't!

I have only tested using gnu make. other makes may have different behaviour.


gnu make manual

https://www.gnu.org/software/make/manual/html_node/index.html

阿楠 2024-08-28 01:07:54

对于标准 make,您可以通过像这样定义宏来传递参数,

make run arg1=asdf

然后像这样使用它们

run: ./prog $(arg1)
   etc

make
Microsoft 的 NMake

for standard make you can pass arguments by defining macros like this

make run arg1=asdf

then use them like this

run: ./prog $(arg1)
   etc

References for make
Microsoft's NMake

别再吹冷风 2024-08-28 01:07:54

您可以将变量传递给 Makefile,如下所示:

run:
    @echo ./prog $FOO

用法:

$ make run FOO="the dog kicked the cat"
./prog the dog kicked the cat

或:

$ FOO="the dog kicked the cat" make run
./prog the dog kicked the cat

或者使用 Beta 提供的解决方案:

run:
    @echo ./prog $(filter-out $@,$(MAKECMDGOALS))
%:
    @:

%: - 匹配任意任务名称的规则;
@: - 空食谱=什么也不做

用法:

$ make run the dog kicked the cat
./prog the dog kicked the cat

You can pass the variable to the Makefile like below:

run:
    @echo ./prog $FOO

Usage:

$ make run FOO="the dog kicked the cat"
./prog the dog kicked the cat

or:

$ FOO="the dog kicked the cat" make run
./prog the dog kicked the cat

Alternatively use the solution provided by Beta:

run:
    @echo ./prog $(filter-out $@,$(MAKECMDGOALS))
%:
    @:

%: - rule which match any task name;
@: - empty recipe = do nothing

Usage:

$ make run the dog kicked the cat
./prog the dog kicked the cat
那片花海 2024-08-28 01:07:54

这是另一个可以帮助解决其中一些用例的解决方案:

test-%:
    $(PYTHON) run-tests.py $@

换句话说,选择一些前缀(在本例中为 test-),然后将目标名称直接传递给程序/运行程序。我想如果涉及一些运行程序脚本可以将目标名称解包为对底层程序有用的内容,那么这非常有用。

Here's another solution that could help with some of these use cases:

test-%:
    $(PYTHON) run-tests.py $@

In other words, pick some prefix (test- in this case), and then pass the target name directly to the program/runner. I guess this is mostly useful if there is some runner script involved that can unwrap the target name into something useful for the underlying program.

风轻花落早 2024-08-28 01:07:54

否。从 GNU make 的手册页查看语法

make [ -f makefile ] [ 选项 ] ... [ 目标 ] ...

您可以指定多个目标,因此“否”(至少没有按照您指定的确切方式)。

No. Looking at the syntax from the man page for GNU make

make [ -f makefile ] [ options ] ... [ targets ] ...

you can specify multiple targets, hence 'no' (at least no in the exact way you specified).

全部不再 2024-08-28 01:07:54

您可以在命令行中显式提取每个第 n 个参数。为此,您可以使用变量 MAKECMDGOALS,它保存提供给“make”的命令行参数列表,并将其解释为目标列表。如果要提取第 n 个参数,可以将该变量与“word”函数结合使用,例如,如果想要第二个参数,可以将其存储在变量中,如下所示:

second_argument := $(word 2, $(MAKECMDGOALS) )

You can explicitly extract each n-th argument in the command line. To do this, you can use variable MAKECMDGOALS, it holds the list of command line arguments given to 'make', which it interprets as a list of targets. If you want to extract n-th argument, you can use that variable combined with the "word" function, for instance, if you want the second argument, you can store it in a variable as follows:

second_argument := $(word 2, $(MAKECMDGOALS) )
那一片橙海, 2024-08-28 01:07:54

run: ./prog 看起来有点奇怪,因为正确的部分应该是先决条件,所以 run: prog 看起来更好。

我简单地建议:

.PHONY: run

run:
    prog $(arg1)

我想补充一点,可以传递参数:

  1. 作为参数: make arg1="asdf" run
  2. 或定义为环境: arg1="asdf" make运行

run: ./prog looks a bit strange, as right part should be a prerequisite, so run: prog looks better.

I would suggest simply:

.PHONY: run

run:
    prog $(arg1)

and I would like to add, that arguments can be passed:

  1. as argument: make arg1="asdf" run
  2. or be defined as environment: arg1="asdf" make run
看透却不说透 2024-08-28 01:07:54

对此并不太自豪,但我不想传递环境变量,因此我颠倒了运行预设命令的方式:

run:
    @echo command-you-want

这将打印您想要运行的命令,因此只需在子 shell 中对其进行评估即可:

$(make run) args to my command

Not too proud of this, but I didn't want to pass in environment variables so I inverted the way to run a canned command:

run:
    @echo command-you-want

this will print the command you want to run, so just evaluate it in a subshell:

$(make run) args to my command
雨落□心尘 2024-08-28 01:07:54

这是我的例子。注意,我是在Windows 7下编写的,使用Dev-Cpp自带的mingw32-make.exe。 (我有 c:\Windows\System32\make.bat,所以该命令仍然称为“make”。)

clean:
    $(RM) $(OBJ) $(BIN) 
    @echo off
    if "${backup}" NEQ "" ( mkdir ${backup} 2> nul && copy * ${backup} )

定期清理的用法:

make clean

在 mydir/ 中清理和创建备份的用法:

make clean backup=mydir

Here is my example. Note that I am writing under Windows 7, using mingw32-make.exe that comes with Dev-Cpp. (I have c:\Windows\System32\make.bat, so the command is still called "make".)

clean:
    $(RM) $(OBJ) $(BIN) 
    @echo off
    if "${backup}" NEQ "" ( mkdir ${backup} 2> nul && copy * ${backup} )

Usage for regular cleaning:

make clean

Usage for cleaning and creating a backup in mydir/:

make clean backup=mydir
溇涏 2024-08-28 01:07:54

idelic答案上进行一些构建
您可以创建一个通用“函数”来获取参数
使用以下内容:

define fetch_parameter
    $(eval target_name:= $(firstword $(MAKECMDGOALS)))
    $(eval varname := $(target_name)_value)
    $(eval $(varname) := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)))
    $(eval $($(varname))::;@:)
endef

然后您可以像这样在目标中使用它:

my-target: res := $(call fetch_parameter)
my-target: ## Example target. Usage: make my-target <value>
    echo The value: $($@_value)

这样您就可以在要从中检索值的任何目标上使用 res := $(call fetch_parameter)

注意:我在这段代码上添加了一个额外的 : $(eval $($(varname))::;@:) 因为如果您有多个目标调用fetch_parameter,它也会被触发。
因此,如果您有:

my-target: res := $(call fetch_parameter)
my-target: ## Example target. Usage: make my-target <value>
    echo The value: $($@_value)

my-target2: res := $(call fetch_parameter)
my-target2: ## Example target. Usage: make my-target2 <value>
    echo The value: $($@_value)

并且您调用 make my-target2 hello(Make 的工作方式),则两个 $(call fetch_parameter) 将被触发,导致创建 2 个伪造的 hello 目标,但使用额外的 : (hello::) Make 不会抱怨您正在覆盖目标。

Building a bit on idelic answer.
You can create a generic "function" to fetch parameters
using the following:

define fetch_parameter
    $(eval target_name:= $(firstword $(MAKECMDGOALS)))
    $(eval varname := $(target_name)_value)
    $(eval $(varname) := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)))
    $(eval $($(varname))::;@:)
endef

You can then user it in your target like so:

my-target: res := $(call fetch_parameter)
my-target: ## Example target. Usage: make my-target <value>
    echo The value: $($@_value)

This way you can just use res := $(call fetch_parameter) on any target you want to retrieve values from.

Note: I've added an extra : on this bit of code $(eval $($(varname))::;@:) because if you have more than one target with a call to fetch_parameter it will also be triggered.
So if you have:

my-target: res := $(call fetch_parameter)
my-target: ## Example target. Usage: make my-target <value>
    echo The value: $($@_value)

my-target2: res := $(call fetch_parameter)
my-target2: ## Example target. Usage: make my-target2 <value>
    echo The value: $($@_value)

and you call make my-target2 hello, the way Make works, both $(call fetch_parameter) will be triggered causing the creation of 2 bogus hello targets, but with the extra : (hello::) Make won't complain that you are overriding a target.

昨迟人 2024-08-28 01:07:54

我找到了一种方法来获取带有等号=的参数!答案尤其是对 @lesmana 的答案 的补充(因为它是这里最完整和解释的答案),但它会太大了,无法将其写为评论。我再次重复他的信息:TL;DR 不要尝试这样做!

我需要一种方法来处理我的参数 --xyz-enabled=false (因为默认值为 true),我们现在都知道这不是 make 目标,因此不是 的一部分>$(MAKECMDGOALS)

在通过回显 $(.VARIABLES) 来查看 make 的所有变量 时,我得到了这些有趣的输出:

[...] -*-command-variables-*- --xyz-enabled [...]

这使我们可以采取两种方式:要么从 -- 开始(如果这适用于您的情况),要么查看 GNU 制定特定(可能不适合我们使用) 变量-*-command-variables-*-。 ** 有关其他选项,请参阅页脚 ** 在我的情况下,此变量保持:

--xyz-enabled=false

通过此变量,我们可以将其与 $(MAKECMDGOALS) 的现有解决方案结合起来,从而通过定义:

# the other technique to invalidate other targets is still required, see linked post
run:
    @echo ./prog $(-*-command-variables-*-) $(filter-out $@,$(MAKECMDGOALS))`

并将其与 (显式混合参数的顺序):

make run -- config --xyz-enabled=false over=9000 --foo=bar show  isit=alwaysreversed? --help

返回:

./prog isit=alwaysreversed? --foo=bar over=9000 --xyz-enabled=false config show --help

如您所见,我们失去了参数的总顺序。带有“赋值”参数的部分似乎已颠倒,“目标”参数的顺序保持不变。我将“赋值”-args 放在开头,希望您的程序不关心参数放置在哪里。


以下 make 变量看起来也很有希望:

MAKEFLAGS =  -- isit=alwaysreverse? --foo=bar over=9000 --xyz-enabled=false
MAKEOVERRIDES = isit=alwaysreverse? --foo=bar over=9000 --xyz-enabled=false

I found a way to get the arguments with an equal sign =! The answer is especially an addition to @lesmana 's answer (as it is the most complete and explained one here), but it would be too big to write it as a comment. Again, I repeat his message: TL;DR don't try to do this!

I needed a way to treat my argument --xyz-enabled=false (since the default is true), which we all know by now that this is not a make target and thus not part of $(MAKECMDGOALS).

While looking into all variables of make by echoing the $(.VARIABLES) i got these interesting outputs:

[...] -*-command-variables-*- --xyz-enabled [...]

This allows us to go two ways: either getting all starting with a -- (if that applies to your case), or look into the GNU make specific (probably not intended for us to use) variable -*-command-variables-*-. ** See footer for additional options ** In my case this variable held:

--xyz-enabled=false

With this variable we can combine it with the already existing solution with $(MAKECMDGOALS) and thus by defining:

# the other technique to invalidate other targets is still required, see linked post
run:
    @echo ./prog $(-*-command-variables-*-) $(filter-out $@,$(MAKECMDGOALS))`

and using it with (explicitly mixing up order of arguments):

make run -- config --xyz-enabled=false over=9000 --foo=bar show  isit=alwaysreversed? --help

returned:

./prog isit=alwaysreversed? --foo=bar over=9000 --xyz-enabled=false config show --help

As you can see, we loose the total order of the args. The part with the "assignment"-args seem to have been reversed, the order of the "target"-args are kept. I placed the "assignment"-args in the beginning, hopefully your program doesn't care where the argument is placed.


following make variables looks promising as well:

MAKEFLAGS =  -- isit=alwaysreverse? --foo=bar over=9000 --xyz-enabled=false
MAKEOVERRIDES = isit=alwaysreverse? --foo=bar over=9000 --xyz-enabled=false
堇色安年 2024-08-28 01:07:54

已经有一段时间了,但我将提供我在生产中使用的版本。

我希望有人会发现它有用。

示例:

.PHONY: greeting
greeting:
    echo $(if $s,$s,)

命令:

makegreeting s="hello world"

输出:

hello world

It's been for a while, but I'll provide mine version which I use in production.

I'll hope that someone will find it useful.

Example:

.PHONY: greeting
greeting:
    echo $(if $s,$s,)

Command:

make greeting s="hello world"

Output:

hello world

如果没有 2024-08-28 01:07:54

我常用的Makefile

SHELL := /bin/bash 
args := $(filter-out $@,$(MAKECMDGOALS))
Command := $(word 1,$(args))
arg1 := $(word 2,$(args))
arg2 := $(word 3,$(args))
arg3 := $(word 4,$(args))

My usual Makefile

SHELL := /bin/bash 
args := $(filter-out $@,$(MAKECMDGOALS))
Command := $(word 1,$(args))
arg1 := $(word 2,$(args))
arg2 := $(word 3,$(args))
arg3 := $(word 4,$(args))
十年九夏 2024-08-28 01:07:54

我喜欢这个:

run\:%:
  @docker run $(subst run:,,$@)

结果:

make run:start # will run `docker run start`

I like this one:

run\:%:
  @docker run $(subst run:,,$@)

Result:

make run:start # will run `docker run start`
巴黎盛开的樱花 2024-08-28 01:07:54

我使用的另一个技巧是 -n 标志,它告诉 make 进行试运行。例如,

$ make install -n 
# Outputs the string: helm install stable/airflow --name airflow -f values.yaml
$ eval $(make install -n) --dry-run --debug
# Runs: helm install stable/airflow --name airflow -f values.yaml --dry-run --debug

Another trick I use is the -n flag, which tells make to do a dry run. For example,

$ make install -n 
# Outputs the string: helm install stable/airflow --name airflow -f values.yaml
$ eval $(make install -n) --dry-run --debug
# Runs: helm install stable/airflow --name airflow -f values.yaml --dry-run --debug
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文