我正在使用GNU makefiles来构建C项目。我想保留一个独立的构建树上的所有构建工件以减少混乱。该项目是这样的:目标文件不匹配隐式规则与模式
$prefix/
include/$tree/program.h
source/$tree/program.c
build/
objects/$tree/program.o
dependencies/$tree/program.d
其中$prefix
表示项目的目录和$tree
表示任意文件夹结构。
我想将source/
目录中的源文件与build/
树中的对象和依赖项文件对应项匹配。所以,我写了下面的规则:
# Remove the built-in rules
%.o : %.c
$(objects_directory)/%.o : $(source_directory)/%.c $(dependencies_directory)/%.d
$(compiler_command_line) $(compiler_option_output) [email protected] $<
$(build_directory)/$(target) : $(objects)
$(compiler_command_line) $(compiler_option_output) [email protected] $^
制作正确地计算出编译target
,并建立它所需的目标文件。然而,让停在此点出现错误:
No rule to make target
'build/objects/project/program.o'
, needed by'build/program.dll'
.
那么,为什么会出现这种情况,如何解决呢?
我通过运行make --print-data-base
调查的问题,它的输出包括:
# Not a target:
build/objects/project/program.o:
# Implicit rule search has been done.
# File does not exist.
# File has not been updated.
这表明如预期的前提是不匹配的隐含规则。但是,我核实,当我试图通过写适合我的方式向后,它并匹配:
object := build/objects/project/program.o
$(object:$(objects_directory)/%.o=$(source_directory)/%.c)
$(object:$(objects_directory)/%.o=%)
这些线导致source/project/program.c
和project/program
,这意味着干被正确计算。
我研究过GNU make文档,我不记得读过任何暗示这种模式匹配不能在隐式规则定义中发生的事情。
这里有变量定义:
include_directory := include
source_directory := source
build_directory := build
objects_directory := $(build_directory)/objects
dependencies_directory := $(build_directory)/dependencies
sources := $(wildcard $(source_directory)/**/*.c)
objects := $(sources:$(source_directory)/%.c=$(objects_directory)/%.o)
# Take the name of the project's directory
target := $(notdir $(CURDIR)).dll
compiler_dependency_file = $(patsubst $(source_directory)/%.c,$(dependencies_directory)/%.d,$<)
compiler_options = -I $(include_directory) -MMD -MF $(compiler_dependency_file)
CC = gcc
compiler_command_line = $(CC) $(compiler_options) $(CFLAGS)
compiler_option_output = -o
链接器(或编译器)不使用'.d'。它们是由编译器生成的makefile,由父Makefile包含, 定义了“foo.o”的依赖关系,该标头否则不会被称为先决条件。当它相对于由'foo.c | cpp'包含的头部过期时,它们会提示* make *重新编译*'foo.o'。 –
请参阅 [this](http://stackoverflow.com/questions/8025766/makefile-auto-dependency-generation) [this](http://make.mad-scientist.net/papers/advanced-auto-依赖生成/) 和[这](http://www.microhowto.info/howto/automatically_generate_makefile_dependencies.html) –
@MikeKinghan,我不认为我理解这个过程,以及我想。根据它们之间的依赖关系,我认为目标文件和库都必须以特定顺序链接。我认为这是问题['pkg-config'](https://www.freedesktop.org/wiki/Software/pkg-config/)旨在解决的问题。这是不正确的?如果不是,请你澄清一下;我会编辑答案。 –