使用makefile C子目录规则来生成obj

Thr*_*ash 6 c compiler-errors makefile compilation

我运行一个简单的Makefile没有问题:

CC=gcc
CFLAGS= -std=c99 -ggdb -Wall -I.
DEPS = hellomake.h
OBJ = hellomake.o hellofunc.o 

%.o: %.c $(DEPS)
    $(CC) -c -o $@ $< $(CFLAGS)

hellomake: $(OBJ)
    gcc -o $@ $^ $(CFLAGS)
Run Code Online (Sandbox Code Playgroud)

这些文件位于主项目的目录中:

./project/Makefile
./project/hellomake.c
./project/hellomake.h
Run Code Online (Sandbox Code Playgroud)

然后我尝试组织文件,并把事情如下:

./project/Makefile
./project/src/hellomake.c
./project/include/hellomake.h
Run Code Online (Sandbox Code Playgroud)

和额外的子目录目录:

./project/lib
./project/obj
Run Code Online (Sandbox Code Playgroud)

然后是新版本的Makefile:

IDIR =include
CC=gcc
CFLAGS= -std=c99 -ggdb -Wall -I$(IDIR)

ODIR=obj
LDIR =lib

LIBS=-lm

_DEPS = hellomake.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))

_OBJ = hellomake.o hellofunc.o 
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))


$(ODIR)/%.o: %.c $(DEPS)
    $(CC) -c -o $@ $< $(CFLAGS)

hellomake: $(OBJ)
    gcc -o $@ $^ $(CFLAGS) $(LIBS)

.PHONY: clean

clean:
    rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ 
Run Code Online (Sandbox Code Playgroud)

我正在使用Emacs和gcc编译器在Linux上进行编译:

$ gcc --version
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Run Code Online (Sandbox Code Playgroud)

然后,我在Emacs上运行:

<Esc> 
x
compile
make
Run Code Online (Sandbox Code Playgroud)

它给出了这样的信息:

"./project/src/" -*-
make: *** No rule to make target `obj/hellomake.o', needed by `hellomake'.  Stop.
Compilation exited abnormally with code 2 at Wed Oct  3 17:10:01
Run Code Online (Sandbox Code Playgroud)

应该缺少什么规则才能包含在Makefile文件中?

所有意见和建议都非常感谢.


感谢您的建议,它已添加到代码中.然后编译器抱怨:

make -k 
make: *** No rule to make target `src/hellomake.c', needed by `obj/hellomake.o'.
make: *** No rule to make target `../include/hellomake.h', needed by `obj/hellomake.o'.
make: Target `obj/hellomake.o' not remade because of errors
Run Code Online (Sandbox Code Playgroud)

其他一些建议?

提前致谢!

Kri*_*ina 8

修复错误 make: *** No rule to make target 'obj/hellomake.o', needed by 'hellomake'. Stop.

改变这一行:

$(ODIR)/%.o: %.c $(DEPS) 
Run Code Online (Sandbox Code Playgroud)

至:

$(OBJ): $(ODIR)/%.o: src/%.c $(DEPS)
Run Code Online (Sandbox Code Playgroud)

这将为$(OBJ)变量中的所有对象创建规则.第二个参数(' $(ODIR)/%.o')从完整路径中提取文件名,以便仅将文件名传递给第三个参数(' src/%.c').