运行 具有第 n 个依赖项的第 n 个目标的命令
Run a command for the nth target with the nth dependancy
我对“$<”和“$@”宏如何与元素列表一起使用有些困惑。我的最终目标是将一个 C 源文件目录编译成同名的 executables,没有扩展名。我也不想制作目标文件。
这是一个简单的 makefile,我想使用宏对其进行升级。
CC = gcc -ansi -std=c99
CCFLAGS = -Wall -pedantic -O3
all : progA progB progC
progA : progA.c
$(CC) $(CCFLAGS) $< -o $@
progB : progB.c
$(CC) $(CCFLAGS) $< -o $@
progC : progC.c
$(CC) $(CCFLAGS) $< -o $@
这很好用,但我不喜欢命令的冗余。我找到了一个可行的解决方法和一个接近的解决方案,但希望可能有一个明确的选择。
解决方法:
CC = gcc -ansi -std=c99
CCFLAGS = -Wall -pedantic -O3
PRGS := $(patsubst %.c,%,$(wildcard *.c))
all :
make $(PRGS)
% : *.c
$(CC) $(CCFLAGS) $@.c -o $@
这里我不喜欢的是在命令中进行的调用。 运行 'make' 在我的终端中发送一条消息,看起来像这样:
make[1]: Entering directory '/path/to/dir'
...actual commands...
make[1]: Leaving directory '/path/to/dir'
我假设这与打开同一个 makefile 有关,[1] 指的是打开文件中的第二个文件描述符 table(或类似的东西)。
接近解:
CC = gcc -ansi -std=c99
CCFLAGS = -Wall -pedantic -O3
SRCS := $(wildcard *.c)
PRGS := $(patsubst %.c,%,$(SRCS))
all : $(PRGS)
$(PRGS) : $(SRCS)
$(CC) $(CCFLAGS) $< -o $@
这几乎可以工作,除了它总是抓住第一个依赖项!
..... progA.c -o progA
..... progA.c -o progB
..... progA.c -o progC
那么,有没有人对我的 'workaround' 有更简洁的方法或者对我的 'near solution' 有解决方案?当 运行 命令时,有没有将第 n 个目标与第 n 个依赖项匹配?
谢谢!
$(PRGS): $(SRCS)
更改不正确。它列出 every 源文件作为 every 目标的先决条件。
您想将 all
目标的先决条件设置为默认情况下要构建的每个程序。为此,您需要使用 all: $(PRGS)
。不是像你原来那样再次调用 make 的方法。
(如果您确实想保留手动递归调用以使您可以在该调用上使用 make --no-print-directory
来避免出现该消息,但这仍然是错误的方法(如果您打算这样做,您我想使用 $(MAKE)
来正确处理原始 make 的参数。)
原始 makefile 的第二个问题是在 %
目标的先决条件列表中使用了 *.c
。这将 every 目标的先决条件设置为目录中的 every *.c
文件。那不是你想要的。您希望每个目标都有自己的 .c
文件作为其先决条件。
你想要:
all: $(PRGS)
%: %.c
$(CC) $(CCFLAGS) $@.c -o $@
据说 make 有一个内置规则,正好用于 foo.c
-> foo
编译,所以你应该只使用它。该规则使用 $(CC)
和 $(CFLAGS)
变量。因此,只需将它们设置为您想要的即可。
所以这个 makefile 应该做你想做的。 (请注意我是如何将一些参数移动到 CFLAGS
而不是 CC
。据我所知,CC
通常应该由编译器本身而不是任何参数移动。)
CC = gcc
CFLAGS = -ansi -std=c99 -Wall -pedantic -O3
PRGS := $(patsubst %.c,%,$(wildcard *.c))
all : $(PRGS)
我对“$<”和“$@”宏如何与元素列表一起使用有些困惑。我的最终目标是将一个 C 源文件目录编译成同名的 executables,没有扩展名。我也不想制作目标文件。
这是一个简单的 makefile,我想使用宏对其进行升级。
CC = gcc -ansi -std=c99
CCFLAGS = -Wall -pedantic -O3
all : progA progB progC
progA : progA.c
$(CC) $(CCFLAGS) $< -o $@
progB : progB.c
$(CC) $(CCFLAGS) $< -o $@
progC : progC.c
$(CC) $(CCFLAGS) $< -o $@
这很好用,但我不喜欢命令的冗余。我找到了一个可行的解决方法和一个接近的解决方案,但希望可能有一个明确的选择。
解决方法:
CC = gcc -ansi -std=c99
CCFLAGS = -Wall -pedantic -O3
PRGS := $(patsubst %.c,%,$(wildcard *.c))
all :
make $(PRGS)
% : *.c
$(CC) $(CCFLAGS) $@.c -o $@
这里我不喜欢的是在命令中进行的调用。 运行 'make' 在我的终端中发送一条消息,看起来像这样:
make[1]: Entering directory '/path/to/dir'
...actual commands...
make[1]: Leaving directory '/path/to/dir'
我假设这与打开同一个 makefile 有关,[1] 指的是打开文件中的第二个文件描述符 table(或类似的东西)。
接近解:
CC = gcc -ansi -std=c99
CCFLAGS = -Wall -pedantic -O3
SRCS := $(wildcard *.c)
PRGS := $(patsubst %.c,%,$(SRCS))
all : $(PRGS)
$(PRGS) : $(SRCS)
$(CC) $(CCFLAGS) $< -o $@
这几乎可以工作,除了它总是抓住第一个依赖项!
..... progA.c -o progA
..... progA.c -o progB
..... progA.c -o progC
那么,有没有人对我的 'workaround' 有更简洁的方法或者对我的 'near solution' 有解决方案?当 运行 命令时,有没有将第 n 个目标与第 n 个依赖项匹配?
谢谢!
$(PRGS): $(SRCS)
更改不正确。它列出 every 源文件作为 every 目标的先决条件。
您想将 all
目标的先决条件设置为默认情况下要构建的每个程序。为此,您需要使用 all: $(PRGS)
。不是像你原来那样再次调用 make 的方法。
(如果您确实想保留手动递归调用以使您可以在该调用上使用 make --no-print-directory
来避免出现该消息,但这仍然是错误的方法(如果您打算这样做,您我想使用 $(MAKE)
来正确处理原始 make 的参数。)
原始 makefile 的第二个问题是在 %
目标的先决条件列表中使用了 *.c
。这将 every 目标的先决条件设置为目录中的 every *.c
文件。那不是你想要的。您希望每个目标都有自己的 .c
文件作为其先决条件。
你想要:
all: $(PRGS)
%: %.c
$(CC) $(CCFLAGS) $@.c -o $@
据说 make 有一个内置规则,正好用于 foo.c
-> foo
编译,所以你应该只使用它。该规则使用 $(CC)
和 $(CFLAGS)
变量。因此,只需将它们设置为您想要的即可。
所以这个 makefile 应该做你想做的。 (请注意我是如何将一些参数移动到 CFLAGS
而不是 CC
。据我所知,CC
通常应该由编译器本身而不是任何参数移动。)
CC = gcc
CFLAGS = -ansi -std=c99 -Wall -pedantic -O3
PRGS := $(patsubst %.c,%,$(wildcard *.c))
all : $(PRGS)