Make: 无法为“所有”做任何事情

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

Http://mrbook.org/tutorials/make/

我的文件夹 eg _ make _ create 包含以下文件,

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'.

请帮助我理解编译这个程序。

312294 次浏览

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

all目标依赖于 hello目标。hello目标首先尝试在文件系统中查找相应的文件。如果它找到它,并且它与依赖文件一起是最新的,那么就没有什么可做的了。

当您只给 make 时,它将创建 makefile 中的第一条规则,即“所有”。您已经指定“ all”依赖于“ hello”,后者依赖于 main.o、 factorial.o 和 hello.o。因此,“ make”尝试查看这些文件是否存在。

如果它们存在,‘ make’查看它们的依赖关系是否发生了变化,例如 main.o 有一个依赖关系 main.c。如果它们发生了变化,就重新构建它们,否则就跳过规则。类似地,它递归地继续构建已更改的文件,并最终运行 top most 命令,在您的示例中为“ all”,以便为您提供一个可执行文件,在您的示例中为“ hello”。

如果他们不在场,就盲目地按照规则建造一切。

说到您的问题,它不是一个错误,但是‘ make’表示您的 makefile 中的每个依赖项都是最新的,并且它不需要创建任何东西!

马克表现正常。hello已经存在,并且不比 .c文件旧,因此没有更多的工作要做。Make 需要(重新)构建的情况有四种:

  • 如果修改了一个 .c文件,那么它将比 hello更新,然后在运行 make 时必须重新构建。
  • 如果您删除 hello,那么它显然将不得不重新构建它
  • 您可以强制 make 使用 -B选项重新构建所有内容
  • make clean all将删除 hello,并需要重建。(我建议你看看@Mat 关于 rm -f *.o hello的评论

这不是错误; unix 中的 make 命令基于时间戳工作。比如说,如果你对 factorial.cpp做了某些修改,然后使用 make编译,那么你就可以做节目了 只执行 cc -o factorial.cpp命令的信息。下一次,如果您执行相同的命令即 make,而不对任何扩展名为 .cpp的文件进行任何更改,编译器会说输出文件是最新的。编译器提供这些信息,直到我们对任何 file.cpp进行某些更改。

makefile的优点是,它通过编译唯一被修改的文件和直接使用未修改文件的目标文件(.o)来减少重新编译的时间。

有时候“ Nothing to be done for all”错误可能是由 makefile 规则中的命令前的空格而不是 tab 引起的。请确保在规则中使用制表符而不是空格。

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

而不是

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

有关规则语法描述,请参阅 GNU make 手册: https://www.gnu.org/software/make/manual/make.html#Rule-Syntax

我想你漏掉了第九行的一个标签。 大家好后面的行必须是空的选项卡。确保第9行中有一个空白选项卡。它将使解释器理解您希望使用 makefile 的默认配方。

我通过不同的途径得到了这个特殊的、难以调试的错误。我的麻烦在于,当目标和依赖项位于不同的目录中时,我在构建步骤中使用了模式规则。就像这样:

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


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

我以这种方式设置了几个依赖项,并试图为它们全部使用一个模式菜谱。显然,“%”的单个替换在这里不起作用。我为每个依赖性制定了明确的规则,我发现自己又回到了小狗和独角兽中间!

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

希望这对谁有帮助!

用 Paul R 的评论,我发现

make clean

然后是

make

或者

make all

解决了我的问题。

我试图在 Ubuntu 上安装 libuv,我也得到了错误代码: Nothing to be done for 'all'。在我看来,使用 make 提供了两种解决问题的方法,一种用于检查,另一种用于安装。但我找到了一个解决办法 仍然使用 sudo make check命令-它有助于在决定进一步的操作之前读取所有的错误消息。基本上,我已经引入了一个回归,使更新工作区效率低下。这个错误来自 make,但是,来自 install 的解决方案修复了这个错误,只要尝试运行 sudo make install,看看会发生什么。 Make 命令将是一个本地优化,代价是牺牲 check/install-c’est ma façon de parler 的整体结果。 我相信我已经大大缩小了问题的范围: 在 检查完毕之后的第一个例子中,我有“ FAIL: test/run-tests”,在 安装之后的第二个例子中,我得到了 "specify the full pathname of the library, or use the '-LLIBDIR'"。这个检查/安装的参数可以是一个列表对象,用于存储关于已完成安装的信息。 因此,安装报告部分成功时,实际上什么也没有发生。

尝试从 root 运行命令:

cd your_program
sh autogen.sh
./configure
make
make check
make install

然后他写道,安装是成功的:

Libraries have been installed in:
/usr/local/lib

在你的例子中,我强烈地感觉到你唯一的简单问题是你只预处理了你的应用程序。您通过在 CFLAGS下面设置 -c标志来实现这一点。