【问题标题】:Pass an argument though makefile linux/unix command line in C通过 C 中的 makefile linux/unix 命令行传递参数
【发布时间】:2013-08-10 20:26:12
【问题描述】:

我的makefile是:

CFLAGS=-g

all:        mcast_client mcast_server

mcast_client:   mcast_client.o $(ARG1)

mcast_server:   mcast_server.o

clean:
        rm -f mcast_client mcast_server mcast_client.o mcast_server.o

在我输入的命令窗口中,

$ make ARG1=hello, world!

这对吗?

【问题讨论】:

  • 你想达到什么目的?就目前而言,您是说 'mcast_client 不是最新的,除非文件 hello,world! 也是最新的,这不太可能是您的想法。

标签: c linux makefile command-line-arguments


【解决方案1】:

用途:

$ make ARG1="hello, world!"

【讨论】:

  • 为什么 env var(可以被 makefile 中的值覆盖)比显式(不可覆盖)命令行分配更好?
  • @JonathanLeffler 好吧,我认为它更具可读性,因为在make 调用之后有一个目标,这会将变量和目标分开。
  • @JonathanLeffler 两者之间是否存在我不知道的语义差异?
  • 是的,有区别。 ARG1=xxx make 表示法使用 shell 功能在 make 命令期间设置环境变量 ARG1。 make 将使用 env var,如果它既没有在命令行上被覆盖,也没有在 makefile 中指定(但你可以使用make -e,这样环境比它在 makefile 中所说的更重要)。 make ARG1=xxx 表示法无条件地设置宏,并且它不能被 makefile 或环境覆盖。很多时候,最终结果是相同的。然而,语义实际上是完全不同的。
  • @JonathanLeffler 好的,感谢您的解释。我删除了第二个命题。
【解决方案2】:

您的调用 make ARG1="hello, world!" 几乎是正确的(但 shell 需要引号),但您的 Makefile 不是。

更现实的方法是将消息作为预处理器宏传递。

假设 hello.c 包含(在某个 C 函数的中间)

  printf("%s\n", MESSAGE);

那么你可以有一个Makefile 规则,比如

  hello.o: hello.c
       $(COMPILE.c) -DMESSAGE=\"$(MSG)\" $< -o $@

引号是反斜杠的,因为预处理器宏 MESSAGE 应该有引号。

最后你可以调用

  make "MSG=hello friend"

请注意,如果MSG 包含引号" 或反斜杠\,这将不起作用...。在上面的命令中,引号由shell 解释...

请注意,您应该每次都使用相同的命令调用 make...(因为如果 MSG 已更改,hello.o 将不会重建)。

顺便说一句,养成总是-Wallso编译的习惯

  CFLAGS= -Wall -g

并查看make -p给出的make的预定义规则

考虑使用remake(尤其是使用-x 调用)来调试棘手或复杂的Makefile-s。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-08
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 2014-05-21
    • 1970-01-01
    • 2017-08-26
    • 1970-01-01
    相关资源
    最近更新 更多