gpt4 book ai didi

c - 为什么这个 makefile 不适用于所有对象?

转载 作者:太空宇宙 更新时间:2023-11-04 00:54:42 25 4
gpt4 key购买 nike

此生成文件的行为与我预期的不同。我希望它为当前目录和子目录中的每个 .c 文件构建 .o 文件,并将它们放入静态库中。但是,它在第​​一个或第二个文件之后停止应用我的 $(INCS) 。当它尝试构建第二个 .o 文件时,我没有在构建行中看到 -I 路径,并且它提示没有在其中找到头文件。名称已被通用化以简化事情。我在 Windows XP 上使用 cygwin。我正在使用不在 cygwin 树下的 ARM 交叉编译器。我根据这个 makefile 的答案 here .只有大约两打 .c 文件,因此以这种方式创建依赖文件的开销不是什么大问题。

# Project specific options
CC = my-cross-gcc
INCS := -I. -Iinc
INCS += -Imy/inc/path

CFLAGS := -Wall -fPIC -static -cross-compiler-specific-options

OUT := bin/libmylib.a

MKDIR:=mkdir -p

### Generic C makefile items below:

# Add .d to Make's recognized suffixes.
SUFFIXES += .d

NODEPS:=clean
#Find all the C files in this directory, recursively
SOURCES:=$(shell find . -name "*.c")

#These are the dependency files
DEPFILES:=$(patsubst %.c,%.d,$(SOURCES))
OBJS:= $(patsubst %.c,%.o,$(SOURCES))

#Don't create dependencies when we're cleaning, for instance
ifeq (0, $(words $(findstring $(MAKECMDGOALS), $(NODEPS))))
-include $(DEPFILES)
endif

#This is the rule for creating the dependency files
%.d: %.c
$(CC) $(INCS) $(CFLAGS) -MM -MT '$(patsubst %.c, %.o,$(patsubst %.c,%.o,$<))' $< > $@

#This rule does the compilation
%.o: %.c %.d %.h
$(CC) $(INCS) $(CFLAGS) -o $@ -c $<

# Now create a static library
all: $(OBJS)
@$(MKDIR) bin
ar rcsvq $(OUT) $(OBJS)

clean:
rm -rf $(OBJS) $(OUT) $(DEPFILES)

为什么这个 makefile 在构建后续的 .o 文件时应用 $(INCS)?我如何解决它?输出类似于:

$ make all
my-cross-gcc -I. -Iinc -Imy/inc/path -<compiler options> -o firstfile.o -c firstfile.c
my-cross-gcc -I. -Iinc -Imy/inc/path -<compiler options> -o secondfile.o -c secondfile.c
my-cross-gcc -<compiler flags> -o thirdfile.o -c thirdfile.c
thirdfile.c:23:18: fatal error: myinc.h: No such file or directory
compilation terminated.

当我转到命令行并在 gcc 行中键入以构建 thirdfile.o 并使用 -I 路径时,目标文件已成功构建。

最佳答案

这里有两种不同的处理头文件的机制:

编译器尝试从foo.c构建foo.o时,在foo.c中> 它遇到 #include "foo.h",它会寻找 foo.h-I 标志告诉它去哪里找。如果在没有找到 foo.h 所需的标志的情况下调用它,它将提示并死掉。

Make 尝试构建 foo.o 并考虑使用哪个规则时,它会查看先决条件。您的规则的先决条件是 foo.c foo.d foo.h,因此它会寻找这些先决条件。 如何知道 foo.h 在哪里?请注意,其中一个命令中的编译器标志是没有用的——它不会对此做出任何推论.如果它找不到(并且不知道如何做)先决条件,它将拒绝该规则并寻找另一个规则,例如隐式 %.o 规则,它对您的规则一无所知$(INCS) 变量,这会导致您遇到上述问题。

如果这是问题所在(您可以通过查看 header 的位置并进行一些实验来检查),您有几个选择:

A) 您可以使用隐式规则,它是变量。只需将 INCS 添加到 CFLAGS 中,您可能会得到想要的结果。这会告诉编译器要做什么,但它仍然让 Make 对依赖关系一无所知,因此您可能需要仔细检查您的依赖关系处理是否正确。

B) 你可以告诉 Make 去哪里找头文件:

vpath %.h inc my/inc/path

(您可能会注意到,这对于您的 INCS 变量来说是多余的,并且冗余是不好的——您可以消除这种冗余,但我强烈建议您先让它工作。)

关于c - 为什么这个 makefile 不适用于所有对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6588615/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com