【问题标题】:Makefile C subdirectory rule to make objMakefile C子目录规则制作obj
【发布时间】:2012-09-24 12:54:53
【问题描述】:

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

文件在主项目的目录中:

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

然后我尝试整理文件,并放置如下内容:

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

和额外的子目录目录:

./project/lib
./project/obj

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

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

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

然后,我在 Emacs 上运行:

<Esc> 
x
compile
make

它给出了信息:

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

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

非常感谢所有 cmets 和建议。


感谢您的建议,已添加到代码中。然后编译器报错:

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

其他建议?

提前致谢!

【问题讨论】:

  • project/obj 会比project/src/obj 更明智一点
  • 你好史蒂夫-o。谢谢!我做了你建议的改变。

标签: c compilation compiler-errors makefile


【解决方案1】:

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

改变这一行:

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

收件人:

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

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

【讨论】:

  • 你好瑞恩。你是对的..“src/”中的文件丢失了。我还按照您的建议删除了“..”。但是留下一个错误:make: *** No rule to make target /include/hellomake.h', needed by obj/hellomake.o'.
  • 从包含中删除开头/。那 / 告诉 Makefile 查看文件系统的根目录而不是您的项目文件夹。
  • 瑞恩再次感谢!我把“/”去掉了。剩下的一个错误消失了。然后在 (gdb) run ... 中给出:{{ (gdb) run 启动程序:未指定可执行文件。使用“file”或“exec-file”命令。}}
  • 没问题!不过,我认为您最好就您的 gdb 问题发表一篇新文章。
【解决方案2】:

好的。现在我正在尝试在此处找到的另一个示例 [How can I create a Makefile for C projects with SRC, OBJ, and BIN subdirectories?],它就在这里:

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!"

文件组织如下:

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

编译器坚持只给出一个投诉:

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

非常感谢所有 cmets 和建议!

【讨论】:

  • 即使这是多年前的问题,您的问题只是没有定义TARGETPATH,因此链接器中的$(TARGETPATH)/$(TARGET) 将解析为/bin。
【解决方案3】:

我认为你应该改变这一行

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

改成

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

在 %.o. 之后添加一个空格

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-11
  • 1970-01-01
  • 2021-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多