2013-09-29 58 views
2

我有这个hello-world.c,我想编译为hello-world二进制。但是hello-world.c取决于在../helpers/a.c../helpers/b.c中定义的几个函数,并且这些帮助者中的每一个分别包括../helpers/a.h../helpers/b.hMakefile对于具有多个.c和.h依赖关系的单个目标

我当前的Makefile看起来像

CC  = @gcc 
CFLAGS = -g -Wall -Wextra -Werror 
CFLAGS += 

LDLIBS = 
LDLIBS += 

OBJS = ../helpers/a.o ../helpers/b.o 

SOURCES = hello-world.c 
DESTS = hello-world 

new: clean all 

clean: 
    @rm -rf *.o */*.o $(DESTS) 

all: $(OBJS) $(DESTS) 

%.o: %.c 
    $(CC) $(CFLAGS) -c $< -o [email protected] 

%: %.c 
    $(CC) $(CFLAGS) -o [email protected] $< 

,但它不工作,返回make: *** No rule to make target `../helpers/a.o', needed by `all'. Stop.

我明白,Makefile中似乎没有看到%.o规则,但我没有看到为什么。

编辑:Makefile的调试:

[email protected]:/media/sf_procmon/procmon$ make --debug=b 
GNU Make 3.81 
Copyright (C) 2006 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. 
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A 
PARTICULAR PURPOSE. 

This program built for x86_64-pc-linux-gnu 
Reading makefiles... 
Updating goal targets.... 
File `new' does not exist. 
    File `clean' does not exist. 
    Must remake target `clean'. 
    Successfully remade target file `clean'. 
    File `all' does not exist. 
    File `../helpers/a.o' does not exist. 
    Must remake target `../helpers/a.o'. 
make: *** No rule to make target `../helpers/a.o', needed by `all'. Stop. 
+0

对其他文件夹中的文件使用模式规则适用于我。我运行这个makefile,a.o和b.o是按照预期创建的。你确定你在正确的目录下运行'make all'吗? –

+0

嗯,这很奇怪。我在右侧运行make,但是我得到了这个错误。 – alexandernst

+0

为什么不把你的帮助函数放到一个库中?那么你不必每次都编译它们。 –

回答

0

这是很容易得到,如果你把Makefile文件的父目录的工作。然后,你可以写这样的事情:

CC  = gcc 
CFLAGS = -g -Wall -Wextra -Werror 
CPPFLAGS = -Ihelpers 

DESTS  = hello-world/hello-world 
OBJS  = helpers/a.o helpers/b.o hello-world/hello-world.o 

# Do not make 'all' depend directly on object files. 
all: $(DESTS) 

# Clean rules should always be prefixed with '-' to avoid 
# errors when files do not exist. Do not use 'rm -r' when 
# there shouldn't be directories to delete; do not delete 
# wildcards when you can use explicit lists instead. 
# Never use '@'. 
clean: 
     -rm -f $(OBJS) $(DESTS) 

# An explicit linkage rule is needed for each entry in DESTS. 
hello-world/hello-world: hello-world/hello-world.o \ 
         helpers/a.o helpers/b.o 
     $(CC) $(CFLAGS) $(LDFLAGS) -o [email protected] $^ $(LIBS) 

# The main function of these dependency lists is to prevent 
# Make from deleting object files after each build. We also 
# take the opportunity to specify header dependencies. 
# We rely on the built-in %.o:%.c rule for commands. 
hello-world/hello-world.o: hello-world/hello-world.c \ 
          helpers/a.h helpers/b.h 
helpers/a.o: helpers/a.c helpers/a.h 
helpers/b.o: helpers/b.c helpers/b.h 

# This tells Make that 'all' and 'clean' are not files to be created. 
.PHONY: all clean 

对于这种技术的进一步论述,请参阅本文分水岭“Recursive Make Considered Harmful”和相关的实施注意事项。

+0

我不能把它放在父目录中,因为目录结构代表几个不同的项目,没有任何关系(除了它们共享助手文件夹)。 – alexandernst

+0

1)目录结构代表几个不同的项目并不重要,它们的唯一连接是助手文件夹;他们应该*仍然*全部在父目录中共享相同的生成文件。你会发现这比其他任何形式的组织都少麻烦。 2)'CPPFLAGS'代表C *预处理器*标志。特定于C++的标志变量是'CXXFLAGS'。编译'.c'文件的内置规则使用'CFLAGS'和'CPPFLAGS'; '.cc' /'.cpp'文件的规则使用'CXXFLAGS'和'CPPFLAGS'。 – zwol

+0

顺便说一下,我的答案中的链接中的“实现说明”显示了一种技术,用于在每个目录的Makefiles中保留每个目录的信息,同时仍然获得非递归make的好处。虽然比上述复杂得多,但我不会为小型项目而烦恼。 – zwol

0

我设法解决我的Makefile:

CC  = gcc 
CFLAGS = -g -Wall -Wextra -Werror 
CFLAGS += 

LDLIBS = 
LDLIBS += 

OBJS = ../helpers/a.o ../helpers/b.o hello-world.o 

SOURCES = hello-world.c 
DESTS = hello-world 

new: clean all 

clean: 
    @rm -rf *.o */*.o ../helpers/*.o $(DESTS) 

all: $(DESTS) 

hello-world: $(OBJS) 
    $(CC) $(CFLAGS) $(LDFLAGS) -o [email protected] $^ $(LIBS) 

其中一个问题是,我写了一个坏干净的原则已经摧毁交流转换器和b.c和Makefile是因为这个作用。

相关问题