【发布时间】:2021-01-11 16:38:27
【问题描述】:
我在编译和链接我的项目与目录组织时遇到问题,如下所示。
/project
|
|____/Components (header files and source codes of all components)
| |
| |____/X (header files and source codes of component)
| |
| |____/src (source codes)
| |
| |____/include (header files)
|
|
|____/make
| |
| |____-Makefile (Makefile)
| |____-source.inc (list of directories with header files)
| |____-source.list (list of every source file, .c and .cpp)
|
|____-main.c (main source file)
当我在 cmd 中运行 make 时,我得到了这个错误:
make: *** No rule to make target '../build/obj/main.o', needed by '../build/bin/app'. Stop.
保持这个目录组织对我来说很重要。
这是我的 Makefile
OUTDIR = ../build/
OBJDIR = $(OUTDIR)obj/
BINDIR = $(OUTDIR)bin/
LD = g++
APP = app
INC_DIRS = $(shell cat source.inc)
CFLAGS = -g0
CXXFLAGS = -g0 -Wall
LDFLAGS = -g0
COMPILE.c = $(BUILD_VERBOSE)$(CXX) $(CFLAGS) $(addprefix -I, $(INC_DIRS)) -c $< -o $@
COMPILE.cc = $(BUILD_VERBOSE)$(CXX) $(CXXFLAGS) $(addprefix -I, $(INC_DIRS)) -c $< -o $@
SRCS = $(shell egrep .[ccpp]$$ source.list)
OBJS = $(patsubst %,$(OBJDIR)%.o,$(basename $(notdir $(SRCS))))
$(BINDIR)$(APP): prep_dirs $(OBJS)
@printf "\nBuilding Project $@\n"
$(LD) $(LDFLAGS) $(OBJS) -o $@
$(OBJDIR)%.o: %.c
@printf "\nCompiling: $<\n"
$(COMPILE.c)
$(POSTCOMPILE)
$(OBJDIR)%.o: %.cpp
@printf "\nCompiling: $<\n"
$(COMPILE.cc)
$(POSTCOMPILE)
prep_dirs:
$(BUILD_VERBOSE)mkdir -p $(OUTDIR)
$(BUILD_VERBOSE)mkdir -p $(OBJDIR)
$(BUILD_VERBOSE)mkdir -p $(BINDIR)
.PHONY: clean
clean:
@printf "Cleaning executables...\n"
$(BUILD_VERBOSE)rm -rf $(BINDIR)*.exe
.PHONY: cleanall
cleanall:
@printf "Cleaning all objects...\n"
$(BUILD_VERBOSE)rm -rf $(OUTDIR)
source.inc 和 source.list
source.inc
../Components/X/include
source.list
../Components/X/src/some_source.c
../main.c
你能告诉我我做错了什么吗?如何修复它并将 main.c 留在同一个地方?
【问题讨论】:
-
我个人停止编写 makefile 以支持更高级别的构建系统,例如 cmake。更好的选择
-
“如何为更大的项目正确准备 makefile?” - 不这样做。对小型项目使用手动编写的 makefile,而不是大型项目。
-
您是否考虑过使用其他构建自动化系统,例如ninja ?
-
当源文件和/或目标文件不在当前目录中时,总是很难正确编写 Makefile。在您的情况下,
make不知道../main.c应该是../build/obj/main.o的源,并且找不到可以从现有源文件构建 .o 文件的规则。some_source.c也是如此。也许VPATH或vpath可以提供帮助。您必须将..和../Components/X/src指定为要搜索的目录。如果您在不同的源目录中有同名的文件,这可能会导致歧义。 -
@BasileStarynkevitch Ninja 旨在供更高级别的构建系统或生成器使用。用
ninja替换make在这里可能没有多大帮助。见ninja-build.org