我的项目结构如下:
.
├── build
│ ├── makefile
└── src
├── subsys1
│ ├── includes
│ └── src_1.cpp
└── subsys2
├── includes
└── src_2.cpp
我已经编写了一个makefile来构建可执行文件' myapp'来自上面的源文件:
print-% : ; @echo $* = $($*)
# Application name
APP := myapp
# Set the directory to store the object files in
OBJDIR_R = _gnuRelease
OBJDIR_D = _gnuDebug
# Names of compiler and linker, and their associated switches
CXX:=g++
LINKER:=g++
CXXFLAGS+=-Wall -std=c++11 -pedantic -lpthread -m64
ifeq ($(DEBUG),1)
OBJDIR := $(OBJDIR_D)
CXXFLAGS += -g
else
OBJDIR := $(OBJDIR_R)
CXXFLAGS += -O2
endif
LDFLAGS =
# Set the name of the output executable
EXEFILE := LedaAP
VPATH = ../src/subsys1 ../src/subsys2
CPP_FILES = src_1.cpp src_2.cpp
OBJ_FILES = $(patsubst %.cpp,%.o,$(CPP_FILES))
DEP_FILES = $(patsubst %.cpp,%.d,$(CPP_FILES))
INC_DIRS := ../src/subsys1/includes ../src/subsys2/includes
INC_SWITCHES=$(foreach d, $(INC_DIRS), -I$d)
# This default target builds the executable by linking the object files
$(APP) : $(OBJ_FILES)
$(LINKER) $(CXXFLAGS) $^ -o $@
# A rule to build an .o file from a .cpp file
%.o: %.cpp
$(CXX) $(CXXFLAGS) $(INC_SWITCHES) -c $< -o $@
# Running 'make clean' deletes the executables and all the libraries.
.PHONY: clean
clean:
@echo Deleting executables and libraries. Use make clean_exe to delete just the executables.
@rm -f $(OBJDIR_D)/$(EXEFILE)
@rm -f $(OBJDIR_R)/$(EXEFILE)
@rm -rf $(OBJDIR_D)
@rm -rf $(OBJDIR_R)
结果是构建目录中的目标文件和可执行文件:
build
├── makefile
├── myapp
├── src_1.o
└── src_2.o
我其实想要:
build
├── _gnuRelease
│ ├── myapp
│ └── objects
│ ├── src_1.o
│ └── src_2.o
└── makefile
我怎么能实现这个目标?
答案 0 :(得分:0)
对于行:CPP_FILES = src_1.cpp src_2.cpp
,最好将目录名放在那里(即CPP_FILES = subsys1/src_1.cpp subsys2/src_2.cpp
)。首先,如果两个子系统碰巧有一个具有相同名称的文件,这可以避免问题,其次,它使makefile更简单,更容易维护。
如果您打算按自己的方式做事,可以在OBJ_FILES前添加一个目录:OBJ_FILES=$(SOURCE_FILES:%.cpp=$(OBJ_DIR)/%.o)
,并相应地修改模式规则:$(OBJ_DIR)/%.o : %.cpp
,将.o文件放在正确的目录。
答案 1 :(得分:0)
在Building C-program “out of source tree” with GNU make上记录的并且由@ k-mulier在上面提到的makefile满足了我的要求。