我对于' $<'和' $ @'宏可以与元素列表一起使用。我的最终目标是将C源文件的目录编译成具有相同名称但没有扩展名的可执行文件。我也不想制作目标文件。
这是一个简单的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 $@
我在这里不喜欢的是在命令中打电话。跑步&#39;制作&#39;在我的终端中发送一条看起来像这样的消息:
make[1]: Entering directory '/path/to/dir'
...actual commands...
make[1]: Leaving directory '/path/to/dir'
我假设这与打开相同的makefile有关,[1]引用打开文件表中的第二个文件描述符(或沿着这些行的东西)。
接近解决方案:
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
那么,有没有人有一个更清洁的方法来解决我的问题&#39;或者也许是我近乎解决方案的解决方案&#39;?无论如何,在运行命令时,是否将第n个目标与第n个依赖项匹配?
谢谢!
答案 0 :(得分:1)
$(PRGS): $(SRCS)
更改不正确。它列出每个源文件作为每个目标的先决条件。
您希望将all
目标的先决条件设置为您希望默认构建的每个程序。为此,您需要使用all: $(PRGS)
。不像你原来那样再次调用make的方法。
(如果您确实希望保留手动递归调用,以便可以在该调用上使用make --no-print-directory
来避免该消息,但这仍然是错误的方法(如果您打算这样做,那么你会想要使用$(MAKE)
来正确处理原始make的参数。)
原始makefile的第二个问题是在*.c
目标的先决条件列表中使用%
。这将每个目标的先决条件设置为目录中的每个 *.c
文件。那不是你想要的。您希望每个目标都有自己的.c
文件作为先决条件。
你想:
all: $(PRGS)
%: %.c
$(CC) $(CCFLAGS) $@.c -o $@
据说make有一个内置规则,正是foo.c
- &gt; foo
编译所以你应该使用它。该规则使用$(CC)
和$(CFLAGS)
变量。所以,只需将它们设置为您想要的就可以完成。
所以这个makefile应该做你想要的。 (注意我是如何将一些参数移到CFLAGS
而不是CC
。CC
一般来说,据我所知,编译器本身而不是任何参数。)
CC = gcc
CFLAGS = -ansi -std=c99 -Wall -pedantic -O3
PRGS := $(patsubst %.c,%,$(wildcard *.c))
all : $(PRGS)