我正在尝试建立一个包含调试和发布目标的makefile。
有一些目标特定变量,主要是文件夹名称,它们在不同情况下已正确设置,但不适用于$@
自动变量。以下代码:
SRC_DIR = src
OBJ_ROOT_DIR = obj
REL_DIR = release
DBG_DIR = debug
TGT_DIR = $(REL_DIR)
SRC_LIST = main.cc prime.cc
SRC_SUFF = cc
SRCS = $(patsubst %.cc, $(SRC_DIR)/%.$(SRC_SUFF), $(SRC_LIST))
OBJ_DIR = $(OBJ_ROOT_DIR)/$(TGT_DIR)
OBJS = $(patsubst %.cc, $(OBJ_DIR)/%.o, $(SRC_LIST))
all: $(OBJS)
release: all
debug: TGT_DIR = $(DBG_DIR)
debug: OBJ_DIR = $(OBJ_ROOT_DIR)/$(TGT_DIR)
debug: OBJS = $(patsubst %.cc, $(OBJ_DIR)/%.o, $(SRC_LIST))
debug: $(OBJS)
$(OBJS):$(OBJ_DIR)/%.o: $(SRC_DIR)/%.$(SRC_SUFF)
@echo "TGT_DIR: $(TGT_DIR) OBJ_DIR: $(OBJ_DIR) OBJS: $(OBJS)"
@echo "Compiling $< to $@ ..."
@echo "... done !"
@echo "."
运行 make release 会产生以下预期输出:
TGT_DIR:发布OBJ_DIR:obj /发布OBJS:obj / release / main.o obj / release / prime.o 将src / main.cc编译为obj / release / main.o ... ...完成!
TGT_DIR:发布OBJ_DIR:obj /发布OBJS:obj / release / main.o obj / release / prime.o 将src / prime.cc编译为obj / release / prime.o ... ...完成了!
Wheras使调试线索导致以下意外情况:
TGT_DIR:调试OBJ_DIR:obj / debug OBJS:obj / debug / main.o obj / debug / prime.o 将src / main.cc编译为obj / release / main.o ... ...完成!
TGT_DIR:调试OBJ_DIR:obj / debug OBJS:obj / debug / main.o obj / debug / prime.o 将src / prime.cc编译为obj / release / prime.o ... ...完成了!
我不知道为什么在第二种情况下$@
无法评估为所需的调试版本。尽管变量似乎设置正确。执行配方时如何获得具有正确的目录名称?
预先感谢!
答案 0 :(得分:0)
您有很多选择/方法来做到这一点。
MAKECMDGOALS
的内容(这些词是make
之后的字,例如release或debug)。注意:可以有一个以上的文件-但是,如果您的makefile很简单并且只有一个文件,则可以使用以下文件:例如:
ifneq ($(MAKECMDGOALS),debug)
TGT_DIR = $(DBG_DIR)
OBJ_DIR = $(OBJ_ROOT_DIR)/$(TGT_DIR)
OBJS = $(patsubst %.cc, $(OBJ_DIR)/%.o, $(SRC_LIST))
endif
另一种选择是使用第二个扩展,我只想放置一个链接:secondary expansion
另一种选择是在规则中设置一些变量,然后导出它们并再次(递归)调用make,也许是这样的:
例如(不完整):
# Note you can just export the ones you want but... for ease of the example:
.EXPORT_ALL_VARIABLES
debug: TGT_DIR = $(DBG_DIR)
debug: OBJ_DIR = $(OBJ_ROOT_DIR)/$(TGT_DIR)
debug: OBJS = $(patsubst %.cc, $(OBJ_DIR)/%.o, $(SRC_LIST))
debug:
$(MAKE) do_build
do_build: $(OBJS)
...etc...
在您的第一个调用中,它在调试规则中设置了一些变量。在第二个中,它直接调用do_build,并且变量已经设置。递归生成通常不被接受-但我发现很多次它是完成某些事情的最简单方法。
为简单起见,我可能会选择选项1。还有更多的方法可以执行此操作,但这取决于您的滚动方式-我只是在设置一些选项,使您的makefile结构或多或少都保持相同...