【发布时间】:2016-09-01 02:18:14
【问题描述】:
我希望我的所有构建文件都存储在项目根文件夹内的build 目录中。不过,如果我添加调试标志,我不想重建所有文件。因此,我有两个目录.build_release 和.build_debug。然后我创建一个从build 到正确目录的符号链接。
我希望所有这些都由make 处理。这是我的makefile:
## setup
ifdef DEBUG
BUILDDIR=.build_debug
else
BUILDDIR=.build_release
endif
BLACKLIST:=bayesP obsDataStats test3 test bayesPsamplesBR test2 tuneSp \
toyFeatures2Multi getCov getDist isConnected mergeClusters sample \
toyFeatures0 toyFeatures1 toyFeatures2 toyFeatures3 toyFeatures4 \
toyFeatures6 toyFeatures7 wnsFeatures0 wnsFeatures1 wnsFeatures2
## make code
PROGS:=$(shell find ./src/ -maxdepth 1 -name "*.cpp" -exec grep -l "int main" {} \;)
PROGS:=$(notdir $(basename $(PROGS)))
PROGS:=$(filter-out $(BLACKLIST),$(PROGS))
CPP_SRC:=$(wildcard src/*.cpp)
CPP_SRC:=$(notdir $(basename $(CPP_SRC)))
CPP_SRC:=$(filter-out $(PROGS) $(BLACKLIST),$(CPP_SRC))
PROGS:=$(PROGS:=.bin)
PROGS:=$(PROGS:%=$(BUILDDIR)/%)
CPP_SRC:=$(CPP_SRC:%=src/%.cpp)
CPP_OBJ:=$(CPP_SRC:src/%.cpp=$(BUILDDIR)/%.o)
LIB=$(BUILDDIR)/libspatialDecisionMaking.so
## test code
CPP_SRC_TEST:=$(wildcard src/test/*.cpp)
CPP_SRC_TEST:=$(notdir $(basename $(CPP_SRC_TEST)))
CPP_SRC_TEST:=$(filter-out $(BLACKLIST),$(CPP_SRC_TEST))
PROGS_TEST:=$(CPP_SRC_TEST:%=$(BUILDDIR)/test/%.bin)
CPP_OBJ_TEST:=$(CPP_SRC_TEST:%=$(BUILDDIR)/test/%.o)
CPP_SRC_TEST:=$(CPP_SRC_TEST:%=src/test/%)
## options
CC=g++-4.9
ifdef DEBUG
CPP_FLAGS=-std=c++11 -ggdb
else
CPP_FLAGS=-std=c++11 -O3
endif
LD_FLAGS=-Isrc -L$(BUILDDIR) -lgsl -larmadillo -fPIC -fopenmp
## rules
all: | $(BUILDDIR) $(LIB) $(PROGS) build
test: | $(BUILDDIR)/test $(LIB) $(PROGS_TEST) build
build: $(BUILDDIR)
ln -rfs $(BUILDDIR) build
$(BUILDDIR)/test: $(BUILDDIR)
mkdir $(BUILDDIR)/test
$(BUILDDIR):
mkdir $(BUILDDIR)
$(BUILDDIR)/%.bin: src/%.cpp $(LIB)
$(CC) $(CPP_FLAGS) -o $@ $< $(LD_FLAGS) -l$(LIB:$(BUILDDIR)/lib%.so=%)
ln -rfs $@ $(@:%.bin=%)
$(LIB): $(CPP_OBJ)
$(CC) $(CPP_FLAGS) -o $@ $^ $(LD_FLAGS) -shared
$(BUILDDIR)/%.o: src/%.cpp $(BUILDDIR)/%.d
$(CC) $(CPP_FLAGS) -c $< -o $@ $(LD_FLAGS)
$(BUILDDIR)/%.d: src/%.cpp
$(CC) $(CPP_FLAGS) -MM $< -MT $(@:%.d=%.o) > $@ $(LD_FLAGS)
%.cpp:
%.hpp:
# include dependencies
-include $(CPP_OBJ:%.o=%.d)
clean:
rm -rf $(BUILDDIR)
不过,它似乎跳过了制作$(BUILDDIR)。我在每次运行 make 之前删除目录,它直接根据目标$(BUILDDIR)/%.d 的规则构建依赖生成文件。但是,它在尝试构建依赖项时自然会抱怨,因为 $(BUILDDIR) 不存在。
知道为什么它会跳过制作$(BUILDDIR) 的秘诀吗?
【问题讨论】:
-
构建目录存在,并且根据为其列出的依赖项是最新的(无),因此
make正确地推断出它无事可做并且什么也不做。如果目录不存在,则创建目录;然后就完成了。我可能遗漏了一些东西,但这是我的直接看法。 -
我也是这么理解的。但是我在运行之前明确删除了目录,它仍然跳过了构建目录的配方。
-
所以它不创建目录,或者它不做任何关于在目录中放东西的事情?
-
两者。它跳过制作目录。然后当它尝试将任何内容放入目录中时抱怨它不存在的明显原因哈哈。
-
让我想一想。我可以观察到您创建的示例不是 MCVE (minimal reproducible example)。例如,您可能会在没有黑名单的情况下显示问题,也可能没有测试等——这将使人们更容易模拟您的环境。
标签: makefile