make:什么都做不了


97

我正在通过一个例如pgm创建一个make文件。

http://mrbook.org/tutorials/make/

我的文件夹eg_make_creation包含以下文件,

desktop:~/eg_make_creation$ ls
factorial.c  functions.h  hello  hello.c  main.c  Makefile

生成文件

# I am a comment, and I want to say that the variable CC will be
# the compiler to use.
CC=gcc
# Hwy!, I am comment no.2. I want to say that CFLAGS will be the
#options I'll pass to the compiler
CFLAGS=-c -Wall

all:hello

hello:main.o factorial.o hello.o
  $(CC) main.o factorial.o hello.o -o hello

main.o:main.c
  $(CC) $(CFLAGS) main.c

factorial.o:factorial.c
  $(CC) $(CFLAGS) factorial.c

hello.o:hello.c
  $(CC) $(CFLAGS) hello.c

clean:
  rm -rf *o hello

错误:

desktop:~/eg_make_creation$ make all
make: Nothing to be done for `all'.

请帮助我理解编译该程序。


12
尝试先进行“清洁”,然后进行“全部清洁”
Paul R

11
这不是一个错误,只是意味着它hello是最新的。在执行意外操作之前先更改cleanrm -f *.o hello,然后运行make clean all并查看是否可行。

1
您还应该添加.phony: all clean,因为allclean不是文件名。
Kerrek SB 2011年

3
不要将-c放在CFLAGS中。
wildplasser 2011年

Answers:


121

有时,makefile规则(而不是tab)中命令前的空格可能会导致“无所事事”错误。请确保您使用制表符,而不是规则中的空格。

all:
<\t>$(CC) $(CFLAGS) ...

代替

all:
    $(CC) $(CFLAGS) ...

请参阅GNU make手册以获取规则语法说明:https : //www.gnu.org/software/make/manual/make.html#Rule-Syntax


obj-m + = hello.o all:</ t> make -C / lib / modules / $(shell uname -r)/ build M = $(PWD)modules clean:make -C / lib / modules / $( shell uname -r)/ build M = $(PWD)clean
Narendra Jaggi 2015年

上面的文件是有效文件吗?
Narendra Jaggi

在父子Makefile文件的上下文中,有时“子项不做所有事情”错误可能是由于子目标在父Makefile中被错误地标记为声明的.PHONY而引起的。
donhector

我有all : src/server/mod_wsgi.la,后来我改成了all : </t> src/server/mod_wsgi.la。我现在得到错误:make: execvp: src/server/mod_wsgi.la: Permission denied Makefile:29: recipe for target 'all' failed make: *** [all] Error 127之后sudo make。有什么帮助吗?
Mooncrater

@Mooncrater参见gnu.org/software/make/manual/make.html#Rule-Syntax。内容如下:配方行以制表符(或.RECIPEPREFIX变量值的第一个字符;请参阅特殊变量)开头。第一条配方行可以在先决条件之后显示,并带有一个制表符,也可以在同一行显示,并使用分号。无论哪种方式,效果都是一样的。因此,您的先决条件就成了食谱。在这种情况下,您不需要任何标签。
VirtualVDX

31

hello文件夹中删除文件,然后重试。

all目标依赖于hello目标。该hello目标首先尝试找到文件系统中的相应文件。如果找到它,并且它是最新的从属文件,则无需执行任何操作。


obj-m + = hello.o all:</ t> make -C / lib / modules / $(shell uname -r)/ build M = $(PWD)modules clean:make -C / lib / modules / $( shell uname -r)/ build M = $(PWD)clean
Narendra Jaggi 2015年

以上是一个有效的make文件吗?
Narendra Jaggi

21

当您只提供make时,它将在您的makefile中制定第一个规则,即“全部”。您已指定“全部”取决于“ hello”,后者取决于main.o,factorial.o和hello.o。因此,“ make”会尝试查看这些文件是否存在。

如果存在它们,“ make”将查看其依赖项(例如main.o具有依赖项main.c)是否已更改。如果它们已更改,请make重建它们,否则跳过规则。同样,它以递归方式继续构建已更改的文件,最后运行最上面的命令(在您的情况下为“ all”)以提供可执行文件,在您的情况下为“ hello”。

如果不存在,请根据规则盲目构建所有内容。

谈到您的问题,这不是一个错误,但是“ make”表示您的makefile中的每个依赖项都是最新的,不需要执行任何操作!


16

Make行为正确。hello已经存在并且不早于.c文件,因此没有更多的工作要做。在以下四种情况下,make将需要(重新)构建:

  • 如果您修改其中一个.c文件,则它会比hello,并且在运行make时必须重新构建。
  • 如果删除 hello,则显然必须重新构建它
  • 您可以使用该-B选项强制make重建所有内容。make -B all
  • make clean all将删除hello并需要重建。(我建议您看看@Mat关于rm -f *.o hello

4

我认为您错过了第9行中的标签。all:hello之后的行必须为空白标签。确保第9行中有一个空白标签。它将使解释器了解您要对Makefile使用默认配方。


4

那不是错误;Unix中的make命令根据时间戳起作用。即,如果您对进行了某些更改factorial.cpp并进行了编译,make则make显示仅cc -o factorial.cpp执行命令的信息。下次,如果您执行相同的命令,即make不对具有.cpp扩展名的任何文件进行任何更改,则编译器会说输出文件是最新的。直到我们对any进行某些更改之前,编译器都会提供此信息file.cpp

的优点makefile是,通过仅编译已修改.o的文件并直接使用未修改文件的object()文件,它减少了重新编译的时间。


0

我通过另一条路线遇到了这个独特的,难以调试的错误。我的麻烦最终是当目标和依赖项位于不同的目录中时,我在构建步骤中使用了模式规则。像这样:

foo/apple.o: bar/apple.c $(FOODEPS)

%.o: %.c
    $(CC) $< -o $@

我以这种方式设置了几个依赖项,并试图对它们全部使用一种模式配方。显然,单个替换“%”在这里行不通。我为每种依赖关系制定了明确的规则,然后我又回到了幼犬和独角兽之中!

foo/apple.o: bar/apple.c $(FOODEPS)
    $(CC) $< -o $@

希望这对某人有帮助!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.