Makefile C子目录规则使obj。

时间:2021-08-17 03:59:06

I am running a simple Makefile with no problems:

我正在运行一个简单的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)

The files are in the main project's directory:

文件在主项目的目录中:

./project/Makefile
./project/hellomake.c
./project/hellomake.h

Then I tried to organized the files, and put things like:

然后我试着整理这些文件,然后放了一些东西:

./project/Makefile
./project/src/hellomake.c
./project/include/hellomake.h

and extra subdirectories directories:

和额外的子目录的目录:

./project/lib
./project/obj

Then the new version of the Makefile:

然后新版本的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)/*~ 

I am compiling on Linux using Emacs with the gcc compiler:

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

$ gcc --version
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

Then, I run on Emacs:

然后,我在Emacs上运行:

<Esc> 
x
compile
make

And it gives the message:

它给出了这样的信息:

"./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

What rule should be missing to be included in the Makefile file?

在Makefile文件中应该缺少什么规则?

All comments and suggestions are highly appreciated.

非常感谢您的评论和建议。


Thanks for your suggestion, it is added to the code. Then the compiler complains:

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

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

Some other suggestion?

一些其他的建议吗?

Thanks in advance!

提前谢谢!

2 个解决方案

#1


6  

To fix the error make: *** No rule to make target 'obj/hellomake.o', needed by 'hellomake'. Stop.

修正错误:***没有规则来制定目标的obj/hellomake。o”,需要“hellomake”。停止。

Change this line:

改变这条线:

$(ODIR)/%.o: %.c $(DEPS) 

To:

:

$(OBJ): $(ODIR)/%.o: src/%.c $(DEPS)

This creates a rule for all objects in the $(OBJ) variable. The second parameter ('$(ODIR)/%.o') extracts the file name from the full path in order to pass just the file name to the third parameter ('src/%.c').

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

#2


-1  

Ok. Now I am trying another example found here [ How can I create a Makefile for C projects with SRC, OBJ, and BIN subdirectories? ] and here it goes:

好的。现在,我正在尝试另一个示例(如何为带有SRC、OBJ和BIN子目录的C项目创建Makefile) ?在这里:

TARGET   = hi.sh
CC       = gcc
# compiling flags here
CFLAGS   = -std=c99 -ggdb -Wall -I./src
TARGET   = bin/hi.sh

LINKER   = gcc -o
# linking flags here
LFLAGS   = -Wall -I. -lm

# change these to set the proper directories where each files shoould be
SRCDIR   = src
OBJDIR   = obj
BINDIR   = bin

SOURCES  := $(wildcard $(SRCDIR)/*.c)
INCLUDES := $(wildcard $(SRCDIR)/*.h)
OBJECTS  := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
rm       = rm -f


$(BINDIR)/$(TARGET): $(OBJECTS)
    @$(LINKER) $(TARGETPATH)/$(TARGET) $(LFLAGS) $(OBJECTS)
    @echo "Linking complete!"

OBJECTS  := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)

$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
    $(CC) $(CFLAGS) -c $< -o $@
    @echo "Compiled "$<" successfully!"

.PHONEY: clean
clean:
    @$(rm) $(OBJECTS)
    @echo "Cleanup complete!"

.PHONEY: remove
remove: clean
    @$(rm) $(BINDIR)/$(TARGET)
    @echo "Executable removed!"

The files are organized as:

文件组织为:

./project/bin/ executable
./project/ojb/*.0
./project/src/*.c and *.h
./project/Makefile

The compiler persists giving only one complaint:

编译器坚持只给出一个抱怨:

make -k 
/usr/bin/ld: cannot open output file /bin/hi.sh: Permission denied
collect2: ld returned 1 exit status
make: *** [bin/bin/hi.sh] Error 1

Thanks a lot for all comments and suggestions!

非常感谢您的评论和建议!

#1


6  

To fix the error make: *** No rule to make target 'obj/hellomake.o', needed by 'hellomake'. Stop.

修正错误:***没有规则来制定目标的obj/hellomake。o”,需要“hellomake”。停止。

Change this line:

改变这条线:

$(ODIR)/%.o: %.c $(DEPS) 

To:

:

$(OBJ): $(ODIR)/%.o: src/%.c $(DEPS)

This creates a rule for all objects in the $(OBJ) variable. The second parameter ('$(ODIR)/%.o') extracts the file name from the full path in order to pass just the file name to the third parameter ('src/%.c').

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

#2


-1  

Ok. Now I am trying another example found here [ How can I create a Makefile for C projects with SRC, OBJ, and BIN subdirectories? ] and here it goes:

好的。现在,我正在尝试另一个示例(如何为带有SRC、OBJ和BIN子目录的C项目创建Makefile) ?在这里:

TARGET   = hi.sh
CC       = gcc
# compiling flags here
CFLAGS   = -std=c99 -ggdb -Wall -I./src
TARGET   = bin/hi.sh

LINKER   = gcc -o
# linking flags here
LFLAGS   = -Wall -I. -lm

# change these to set the proper directories where each files shoould be
SRCDIR   = src
OBJDIR   = obj
BINDIR   = bin

SOURCES  := $(wildcard $(SRCDIR)/*.c)
INCLUDES := $(wildcard $(SRCDIR)/*.h)
OBJECTS  := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
rm       = rm -f


$(BINDIR)/$(TARGET): $(OBJECTS)
    @$(LINKER) $(TARGETPATH)/$(TARGET) $(LFLAGS) $(OBJECTS)
    @echo "Linking complete!"

OBJECTS  := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)

$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
    $(CC) $(CFLAGS) -c $< -o $@
    @echo "Compiled "$<" successfully!"

.PHONEY: clean
clean:
    @$(rm) $(OBJECTS)
    @echo "Cleanup complete!"

.PHONEY: remove
remove: clean
    @$(rm) $(BINDIR)/$(TARGET)
    @echo "Executable removed!"

The files are organized as:

文件组织为:

./project/bin/ executable
./project/ojb/*.0
./project/src/*.c and *.h
./project/Makefile

The compiler persists giving only one complaint:

编译器坚持只给出一个抱怨:

make -k 
/usr/bin/ld: cannot open output file /bin/hi.sh: Permission denied
collect2: ld returned 1 exit status
make: *** [bin/bin/hi.sh] Error 1

Thanks a lot for all comments and suggestions!

非常感谢您的评论和建议!