【发布时间】:2020-07-28 19:08:51
【问题描述】:
我有当前的目录结构:
- ./myFolder/
- 生成文件
- main.c
- ./common/
- 生成文件
- error.c
- error.h
- ./build/
- /常见/
- /myFolder/
/build/common 包含通过编译文件夹common 和build/myFolder 的等效文件获得的对象和依赖文件。
基本上/myFolder/ 包含一个程序,该程序需要common 中包含的某些功能。因此,/myFolder/Makefile 也调用/common/Makefile 进行编译。
./common/Makefile 如下:
CC = gcc
CURRENT_DIR := $(shell basename $(CURDIR))
SOURCEDIR := ./
SOURCES := $(wildcard $(SOURCEDIR)/*.c)
OBJDIR := ../build/$(CURRENT_DIR)
OBJECTS := $(patsubst $(SOURCEDIR)/%.c,$(OBJDIR)/%.o, $(SOURCES))
DEPENDS := $(patsubst $(SOURCEDIR)/%.c,$(OBJDIR)/%.d, $(SOURCES))
# ADD MORE WARNINGS!
WARNING := -Wall -Wextra
all: $(OBJECTS)
clean:
$(RM) $(OBJECTS) $(DEPENDS) $(EXECUTABLE)
-include $(DEPENDS)
$(OBJDIR)/%.o: $(SOURCEDIR)/%.c Makefile | $(OBJDIR)
$(CC) $(WARNING) -MMD -MP -c $< -o $@
$(OBJDIR):
mkdir -p $(OBJDIR)
./myFolder/Makefile 如下:
CC = gcc
INC_PATH := -I../common/
BUILD_DIR_NAME := build
BUILDDIR := ../$(BUILD_DIR_NAME)
CURR_DIR_NAME := $(shell basename $(CURDIR))
SOURCEDIR := ./
SOURCES := $(wildcard $(SOURCEDIR)/*.c)
OBJDIR := $(BUILDDIR)/$(CURR_DIR_NAME)
OBJECTS := $(patsubst $(SOURCEDIR)/%.c,$(OBJDIR)/%.o, $(SOURCES))
DEPENDS := $(patsubst $(SOURCEDIR)/%.c,$(OBJDIR)/%.d, $(SOURCES))
COMMONDIR_NAME := common
COMMONDIR := ../$(COMMONDIR_NAME)
SOURCESCOMMON := $(wildcard $(COMMONDIR)/*.c)
OBJDIRCOMMON := $(BUILDDIR)/$(COMMONDIR_NAME)
OBJECTSCOMMON := $(patsubst $(COMMONDIR)/%.c,$(OBJDIRCOMMON)/%.o, $(SOURCESCOMMON))
DEPENDSCOMMON := $(patsubst $(COMMONDIR)/%.c,$(OBJDIRCOMMON)/%.d, $(SOURCESCOMMON))
# ADD MORE WARNINGS!
WARNING := -Wall -Wextra
EXECUTABLE := ../out_file
# .PHONY means these rules get executed even if
# files of those names exist.
.PHONY: all clean
# The first rule is the default, ie. "make",
# "make all" and "make parking" mean the same
all: $(EXECUTABLE)
clean:
$(RM) $(OBJECTS) $(DEPENDS) $(EXECUTABLE)
+$(MAKE) -C $(COMMONDIR) clean
# Linking the executable from the object files
# $^ # "src.c src.h" (all prerequisites)
$(EXECUTABLE): $(OBJECTS) $(OBJECTSCOMMON)
$(CC) $(WARNING) $^ -o $@
-include $(DEPENDS) $(DEPENDSCOMMON)
$(OBJDIR):
mkdir -p $(OBJDIR)
$(OBJDIR)/%.o: $(SOURCEDIR)/%.c Makefile | $(OBJDIR)
$(CC) $(WARNING) -MMD -MP -c $(INC_PATH) $< -o $@
$(OBJDIRCOMMON):
mkdir -p $(OBJDIRCOMMON)
$(OBJDIRCOMMON)/%.o: $(COMMONDIR)/%.c $(COMMONDIR)/Makefile| $(OBJDIRCOMMON)
+$(MAKE) -C $(COMMONDIR)
如果我第一次进入文件夹myFolder 并使用make 编译,一切正常。
如果然后我再试一次,我会收到以下错误:
make: *** No rule to make target `error.c', needed by `../build/common/error.o'. Stop.
如果我先make clean 然后make 就可以了。
导致问题的行如下:
-include $(DEPENDS) $(DEPENDSCOMMON)
尤其是$(DEPENDSCOMMON)。用-include $(DEPENDS) 代替它,它可以完美运行。
现在,- 告诉 Makefile 在文件不存在时不要抱怨。如果它们存在,它们将被包含并根据依赖关系正确重新编译您的源代码。出于这个原因,我不希望在第一次尝试时编译,但如果它在第一次尝试时编译,也不会产生这样的错误(因为所有文件都存在)。
谁能告诉我我错过了什么?
为了完整起见,这里只是示例的其他文件:
main.c
#include "../common/error.h"
#include <stdio.h>
int main(int argc, char *argv[])
{
if (argc<1) err_sys("some error");
printf("Hello world\n");
return 0;
}
error.c
#include <stdio.h>
void err_sys(const char *fmt, ...)
{
printf("some err\n");
}
error.h
#ifndef _ERROR_H_
#define _ERROR_H_
#endif
/*Fatal error related to a system cal1.
* Print a message and terminate*/
void err_sys(const char *fmt,...);
【问题讨论】:
标签: c makefile dependencies include