C 为什么先决条件的顺序在makefile中很重要?
我刚刚学习如何创建makefile,并意识到在规则的先决条件中头文件和对象文件的顺序很重要,但我不明白为什么 我调查过我的许多同学,并与他们交谈过,当时有很多猜测,但没有人给出答案 我知道在编译的预处理步骤中,来自头文件和源文件的代码会包含在目标文件中,因此,如果我将目标文件和头文件作为prereq传递,那么这又有什么关系呢 我这样问是因为如果缺少头文件,我的Makefile不应该编译 代码如下:C 为什么先决条件的顺序在makefile中很重要?,c,makefile,C,Makefile,我刚刚学习如何创建makefile,并意识到在规则的先决条件中头文件和对象文件的顺序很重要,但我不明白为什么 我调查过我的许多同学,并与他们交谈过,当时有很多猜测,但没有人给出答案 我知道在编译的预处理步骤中,来自头文件和源文件的代码会包含在目标文件中,因此,如果我将目标文件和头文件作为prereq传递,那么这又有什么关系呢 我这样问是因为如果缺少头文件,我的Makefile不应该编译 代码如下: CC = gcc SRC = main.c file1.c OBJ = $(SRC:.c=.o)
CC = gcc
SRC = main.c file1.c
OBJ = $(SRC:.c=.o)
NAME = my_executable
all: header.h $(OBJ)
$(CC) $(OBJ) -o $(NAME)
我[…]意识到了
规则先决条件中的头文件和对象文件很重要,但我确实很重要
不明白为什么
make
的典型实现按照每个目标在Makefile中出现的顺序处理它们的依赖关系。当这样的make
构建示例Makefile
的“all”目标时,它会在$(OBJ)
中列出的任何文件之前检查hello.h
依赖关系。由于没有构建该文件的规则,make
将在该文件不存在时失败。根据实现和配置的不同,它可能会也可能不会尝试从$(OBJ)
构建先决条件
另一方面,如果标题列在其他先决条件之后,则处理先决条件的make
将尝试在检查标题之前构建任何丢失或过期的对象文件
我这样问是因为如果头文件
他失踪了
见上文。但也要明白,你是在依赖一个混帐。您的Makefile
有缺陷,因为它不能正确表达项目的依赖关系。all
目标是合成的;它本身并不真正依赖于任何标题。我认为是部分或全部$(OBJ)
文件起作用。因此,您应该表示这些依赖关系。如果未执行此操作,则会出现这样的情况:如果生成了项目,然后修改了标题,make
将不会重建对象文件,尽管它会重新链接它们
假设所有对象文件都依赖于头文件,我将修改Makefile,如下所示:
CC = gcc
SRC = main.c file1.c
OBJ = $(SRC:.c=.o)
NAME = my_executable
all: $(NAME)
$(NAME): $(OBJ)
$(CC) $(OBJ) -o $@
$(OBJ): header.h
最后一行表示,$(OBJ)
中命名的每个目标都依赖于header.h
。$(名称)
规则表示真正的目标$(名称)
取决于所有对象。这样,如果header.h
changes,则make将重建目标文件,但同时,如果没有任何更改,则make将不做任何操作,甚至不会重新链接主可执行文件。如果缺少标头,则不会尝试构建任何对象文件,因此也不会构建主可执行文件
我[…]意识到了
规则先决条件中的头文件和对象文件很重要,但我确实很重要
不明白为什么
make
的典型实现按照每个目标在Makefile中出现的顺序处理它们的依赖关系。当这样的make
构建示例Makefile
的“all”目标时,它会在$(OBJ)
中列出的任何文件之前检查hello.h
依赖关系。由于没有构建该文件的规则,make
将在该文件不存在时失败。根据实现和配置的不同,它可能会也可能不会尝试从$(OBJ)
构建先决条件
另一方面,如果标题列在其他先决条件之后,则处理先决条件的make
将尝试在检查标题之前构建任何丢失或过期的对象文件
我这样问是因为如果头文件
他失踪了
见上文。但也要明白,你是在依赖一个混帐。您的Makefile
有缺陷,因为它不能正确表达项目的依赖关系。all
目标是合成的;它本身并不真正依赖于任何标题。我认为是部分或全部$(OBJ)
文件起作用。因此,您应该表示这些依赖关系。如果未执行此操作,则会出现这样的情况:如果生成了项目,然后修改了标题,make
将不会重建对象文件,尽管它会重新链接它们
假设所有对象文件都依赖于头文件,我将修改Makefile,如下所示:
CC = gcc
SRC = main.c file1.c
OBJ = $(SRC:.c=.o)
NAME = my_executable
all: $(NAME)
$(NAME): $(OBJ)
$(CC) $(OBJ) -o $@
$(OBJ): header.h
最后一行表示,
$(OBJ)
中命名的每个目标都依赖于header.h
。$(名称)
规则表示真正的目标$(名称)
取决于所有对象。这样,如果header.h
changes,则make将重建目标文件,但同时,如果没有任何更改,则make将不做任何操作,甚至不会重新链接主可执行文件。如果缺少标头,则不会尝试构建任何目标文件,因此也不会构建主可执行文件。如果header.h
不存在,并且main.c
依赖于它,但是main.o
不会将其列为依赖项,是的,顺序很重要–但是main.o
应该将其作为依赖项,不是所有的。你的声明缺乏证据我不知道你想要知道什么,如果你的源文件.c包含头文件.h,并且它丢失了,那么编译是正确的;如果您想从需求中删除头文件,您必须从makefile中删除header.h
,如下所示:all:$(OBJ)$(CC)$(OBJ)-o$(NAME)请编辑您的问题…如果行为取决于依赖项的顺序,则这是makefile中的错误。您可能一开始并没有注意到这一点,因为gmake通常会按左右顺序考虑依赖项,但事实会如此