为什么我的 makefile 没有成为目标之一?

Why is my makefile not making one of the targets?

我需要将我的程序连同一个 makefile 一起提交以进行分配,但由于某种原因它没有生成目标 helper.o,即使该步骤的命令 (gcc -Wall -std=c99 -c helper.c) 有效当我手动将其键入命令行时。当我输入 make 命令时,出现此错误:

gcc -Wall -std=c99 -c createTweet.c
gcc -Wall -std=c99 -c displayTweets.c
gcc -Wall -std=c99 -c searchTweetsByKeyword.c
gcc -Wall -std=c99 -c countStopWords.c
gcc -Wall -std=c99 -c deleteTweet.c
gcc -Wall -std=c99 -c saveTweetsToFile.c
gcc -Wall -std=c99 -c loadTweetsFromFile.c
gcc -Wall -std=c99 -c sortID.c
gcc -Wall -std=c99 -c addNodeToList.c
cc    -c -o mainA3.o mainA3.c
gcc -Wall -std=c99 createTweet.o displayTweets.o searchTweetsByKeyword.o countStopWords.o deleteTweet.o saveTweetsToFile.o loadTweetsFromFile.o sortID.o addNodeToList.o helper.o mainA3.o -o matiwosEyoelA3
gcc: error: helper.o: No such file or directory
make: *** [makefile:2: outputA3] Error 1 '''

这里:是我的 makefile:

outputA3: createTweet.o displayTweets.o searchTweetsByKeyword.o countStopWords.o deleteTweet.o saveTweetsToFile.o loadTweetsFromFile.o sortID.o addNodeToList.o mainA3.o
    gcc -Wall -std=c99 createTweet.o displayTweets.o searchTweetsByKeyword.o countStopWords.o deleteTweet.o saveTweetsToFile.o loadTweetsFromFile.o sortID.o addNodeToList.o helper.o mainA3.o -o outputA3
helper.o: helper.h headerA3.h helper.c
    gcc -Wall -std=c99 -c helper.c
createTweet.o: createTweet.c helper.h headerA3.h
    gcc -Wall -std=c99 -c createTweet.c
displayTweets.o: displayTweets.c helper.h headerA3.h
    gcc -Wall -std=c99 -c displayTweets.c
searchTweetsByKeyword.o: searchTweetsByKeyword.c helper.h headerA3.h
    gcc -Wall -std=c99 -c searchTweetsByKeyword.c
countStopWords.o: countStopWords.c helper.h headerA3.h
    gcc -Wall -std=c99 -c countStopWords.c
deleteTweet.o: deleteTweet.c helper.h headerA3.h
    gcc -Wall -std=c99 -c deleteTweet.c
saveTweetsToFile.o: saveTweetsToFile.c helper.h headerA3.h
    gcc -Wall -std=c99 -c saveTweetsToFile.c
loadTweetsFromFile.o: loadTweetsFromFile.c helper.h headerA3.h
    gcc -Wall -std=c99 -c loadTweetsFromFile.c
sortID.o: sortID.c helper.h headerA3.h
    gcc -Wall -std=c99 -c sortID.c
addNodeToList.o: addNodeToList.c helper.h headerA3.h
    gcc -Wall -std=c99 -c addNodeToList.c
clean: 
    rm *.o outputA3

为什么会发生这种情况?

您的目标 outputA3: 不依赖于 helper.o

将第一行改为-

outputA3: createTweet.o displayTweets.o searchTweetsByKeyword.o countStopWords.o deleteTweet.o saveTweetsToFile.o loadTweetsFromFile.o sortID.o addNodeToList.o mainA3.o helper.o
    gcc -Wall -std=c99 createTweet.o displayTweets.o searchTweetsByKeyword.o countStopWords.o deleteTweet.o saveTweetsToFile.o loadTweetsFromFile.o sortID.o addNodeToList.o helper.o mainA3.o -o outputA3

(注意最后多出来的helper.o

将来避免此类问题的一种方法是使用 $^ 引用所有依赖项而不是列出它们。

所以你可以把目标改成-

outputA3: createTweet.o displayTweets.o searchTweetsByKeyword.o countStopWords.o deleteTweet.o saveTweetsToFile.o loadTweetsFromFile.o sortID.o addNodeToList.o mainA3.o helper.o
    gcc -Wall -std=c99 $^ -o $@

这样您就不必再次编写依赖项,如果您遗漏了某些内容,您会收到一个链接器错误,告诉您缺少哪个文件。

您的 matiwosEyoelA3: ... 没有将 helper.o 列为依赖项。

这是个问题,因为您重复了很多文件名并且违反了“不要写两次”的规则。使用变量和 make 的内置变量,如 $^.

例如

OBJECTS = createTweet.o displayTweets.o searchTweetsByKeyword.o \
          countStopWords.o deleteTweet.o saveTweetsToFile.o \
          loadTweetsFromFile.o sortID.o addNodeToList.o \
          mainA3.o helper.o
outputA3: $(OBJECTS)
      gcc -Wall -std=c99 -o $@ $^

helper.o 不在 outputA3 目标的依赖项列表中,而在必备条件的链接列表中。这使得 make 不编译它,但链接器指责你,因为它没有找到。

一个好主意是使用 outputA3 的对象集创建一个 make 变量,如:

outputA3_objs = createTweet.o displayTweets.o searchTweetsByKeyword.o countStopWords.o deleteTweet.o saveTweetsToFile.o loadTweetsFromFile.o sortID.o addNodeToList.o helper.o mainA3.o
outputA3: $(outputA3_objs)
    gcc -Wall -std=c99 $(outputA3_objs) -o $@

这样一来,如果您需要更改列表,您只需在一个地方进行,使您的 Makefile 更能适应变化。

make 比你想象的要强大得多。感谢您修复了 Makefile 的其他答案。这是一个更简单且不易出错的 Makefile(针对 GNU make):

SRC := $(wildcard *.c)
OBJ := $(patsubst %.c,%.o,$(SRC))
CC := gcc
CFLAGS := -Wall -std=c99

outputA3: $(OBJ)
    $(CC) $(CFLAGS) $^ -o $@

%.o: %.c helper.h headerA3.h
    $(CC) $(CFLAGS) -c $< -o $@

.PHONY: clean
clean:
    rm -f $(OBJ) outputA3

这假定可执行文件是 outputA3(如在您自己的 Makefile 中)而不是 matiwosEyoelA3(如您显示的错误消息),并且所有 C 文件都是项目的一部分.根据需要进行调整。

注意:GNU make 已经知道如何编译和link。如果您接受将可执行文件命名为 mainA3 而不是 outputA3matiwosEyoelA3,则以下内容也应该有效:

CC := gcc
CFLAGS := -Wall -std=c99

mainA3: $(patsubst %.c,%.o,$(wildcard *.c))
%.o: helper.h headerA3.h

.PHONY: clean
clean:
    rm -f *.o mainA3