如何为更大的项目正确准备 makefile?
How to properly prepare makefile for bigger project?
我在编译项目并将其与目录组织链接时遇到问题,如下所示。
/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: *** 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 留在同一个地方?
总的来说:
不确定你的问题到底是什么,但这就是我所做的。该项目有一个全局对象目录 (OBJDIR)。每个源目录都有自己的 Makefile,如下所示:
# list of sources in *this* directory
CCSRC = a.cc b.cc etc
OBJS := $(addsuffix .o, $(CCSRC))
VPATH = $(OBJDIR)
.SUFFIXES: .cc .o
.cc.o:
$(CXX) $(CFLAGS) $< -o $(OBJDIR)/$@
项目顶层有一个Makefile,它只是切换到每个src目录并在该目录中运行make:
include $(PROJ_HOME)/top.mk
# this allows sub-makes to find out if they have been invoked from this
# top-level make, or from a local make (from emacs in a source file directory,
# for example).
CALLED_FROM_TOP = true
export CALLED_FROM_TOP
all :
cd dir1/src; $(MAKE)
cd dir2/rtv; $(MAKE) debug=$(debug) etc
'top.mk' 包括全局定义、导出等。
这是一项艰巨的工作,但为您提供了比我所知道的任何构建系统都更好的 fine-grained 控制。
我在编译项目并将其与目录组织链接时遇到问题,如下所示。
/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: *** 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 留在同一个地方?
总的来说: 不确定你的问题到底是什么,但这就是我所做的。该项目有一个全局对象目录 (OBJDIR)。每个源目录都有自己的 Makefile,如下所示:
# list of sources in *this* directory
CCSRC = a.cc b.cc etc
OBJS := $(addsuffix .o, $(CCSRC))
VPATH = $(OBJDIR)
.SUFFIXES: .cc .o
.cc.o:
$(CXX) $(CFLAGS) $< -o $(OBJDIR)/$@
项目顶层有一个Makefile,它只是切换到每个src目录并在该目录中运行make:
include $(PROJ_HOME)/top.mk
# this allows sub-makes to find out if they have been invoked from this
# top-level make, or from a local make (from emacs in a source file directory,
# for example).
CALLED_FROM_TOP = true
export CALLED_FROM_TOP
all :
cd dir1/src; $(MAKE)
cd dir2/rtv; $(MAKE) debug=$(debug) etc
'top.mk' 包括全局定义、导出等。
这是一项艰巨的工作,但为您提供了比我所知道的任何构建系统都更好的 fine-grained 控制。