【问题标题】:Makefile in C - no rule to make targetC中的Makefile - 没有规则来制作目标
【发布时间】:2016-06-17 23:08:43
【问题描述】:

我正在尝试制作一个 Makefile,即使很难,我也可以制作一个简单的 Makefile,当我需要对不同文件夹中的文件进行排序时,我无法让它工作,我需要的是 /translator 文件夹:Makefile, src 文件夹包含所有 .c 和 .h 文件,files 文件夹包含要翻译的文件,bin 文件夹包含所有 .o 文件和可执行文件。

这是我制作的makefile:

CC = gcc
CFLAGS = -Wall -Werror -Wextra -pedantic -std=c99 -g 
OBJECTS = word.o pair.o list.o dict.o set.o

translate : $(OBJECTS)
    mkdir ./files
    mkdir ./bin
    cd ./src; $(CC) $(CFLAGS) -o translate $(OBJECTS) main.c; mv *.o ../bin; mv translate ../bin

word.o: word.c word.h
    cd ./src; $(CC) $(CFLAGS) -c word.c -o word.o

pair.o: pair.c pair.h word.h
    cd ./src; $(CC) $(CFLAGS) -c pair.c -o pair.o

list.o: list.c list.h word.h pair.h
    cd ./src; $(CC) $(CFLAGS) -c list.c -o list.o

dict.o: dict.c dict.h word.h list.h
    cd ./src; $(CC) $(CFLAGS) -c dict.c -o dict.o

set.o: set.c set.h word.h list.h
    cd ./src; $(CC) $(CFLAGS) -c set.c -o set.o

.PHONY : clean

clean  :
    $(RM) ./bin/*.*
    rmdir ./bin

但只要我输入make,终端就会显示:

make: *** No rule to make target `word.c', needed by `word.o'.  Stop.

我之前以这种方式为 Java 制作了一个 Makefile,它确实有效,并且在 src 文件夹中肯定有一个文件 word.h 和 word.c,那为什么找不到呢?

【问题讨论】:

  • 我是用 Java 做的,现在我读到正确的方法是 && 这样你就知道 cd 命令是成功的
  • 即使删除 cd ./src 后仍然找不到要制作 word.o 的目标文件,我假设我站在错误的文件夹中,但它应该如何?

标签: c makefile


【解决方案1】:

您告诉 make translate(在当前目录中)依赖于word.o 等(在当前目录中),它依赖于word.cword.h(在当前目录中)。

src文件夹里面肯定有word.h和word.c文件,为什么找不到呢?

因为你没有告诉它查看src

你可以这样做:

OBJECTS = word.o pair.o list.o dict.o set.o main.o
# main.o is also an object file

bin/translate: $(addprefix bin/,$(OBJECTS))
        $(CC) $(CFLAGS) $+ -o $@

bin/word.o: src/word.c src/word.h
        $(CC) $(CFLAGS) -c $< -o $@

# ... repeat for all source files

(另请参阅 https://www.gnu.org/software/make/manual/html_node/File-Name-Functions.htmlhttps://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html。)

【讨论】:

    【解决方案2】:

    问题在于您的操作与您的依赖项不匹配——您有一条规则说它从word.c 构建word.o,但随后带有它的命令实际上从src/word.c 生成src/word.o。看看其他规则,你甚至不想要src/word.o,你想要bin/word.o

    因此,您需要修复所有规则,以便为您实际要使用的文件提供正确的名称和路径:

    OBJECTS = bin/word.o bin/pair.o bin/list.o bin/dict.o bin/set.o
    
    bin/translate : $(OBJECTS)
            $(CC) $(CFLAGS) -o $@ $(OBJECTS) src/main.c
    bin/word.o: src/word.c src/word.h
            $(CC) $(CFLAGS) -c $< -o $@
    bin/pair.o: src/pair.c src/pair.h src/word.h
            $(CC) $(CFLAGS) -c $< -o $@
    bin/list.o: src/list.c src/list.h src/word.h src/pair.h
            $(CC) $(CFLAGS) -c $< -o $@
    bin/dict.o: src/dict.c src/dict.h src/word.h src/list.h
            $(CC) $(CFLAGS) -c $< -o $@
    bin/set.o: src/set.c src/set.h src/word.h src/list.h
            $(CC) $(CFLAGS) -c $< -o $@
    

    一旦你这样做了,你会发现大部分动作都是一样的,所以你可以使用模式规则和依赖:

    OBJECTS = bin/word.o bin/pair.o bin/list.o bin/dict.o bin/set.o
    
    bin/translate : $(OBJECTS) src/main.c
            $(CC) $(CFLAGS) -o $@ $(OBJECTS) src/main.c
    bin/%.o: src/%.c
            $(CC) $(CFLAGS) -c $< -o $@
    bin/word.o: src/word.h
    bin/pair.o: src/pair.h src/word.h
    bin/list.o: src/list.h src/word.h src/pair.h
    bin/dict.o: src/dict.h src/word.h src/list.h
    bin/set.o: src/set.h src/word.h src/list.h
    

    【讨论】:

      猜你喜欢
      • 2013-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多