【发布时间】:2013-04-27 21:19:58
【问题描述】:
基于一些 SO 问题——以及发现的一些进一步参考——,我正在尝试构建一个能够:
- 给定
$(SRC)中的目录,找到要编译的.cpp文件; - 编译
.cpp,生成.o对象; - 从之前编译的每个
.o生成.so共享对象。
make 文件应该做的是:
- 给定
$(SRC)中的目录,找到要编译的.cpp文件; - 使用
-MM编译器标志为每个.cpp构建依赖关系列表; - 使用
$(eval ...)注释/添加每个依赖项; - 评估/解决找到的每个依赖项,生成
.o和.so文件。
到目前为止我有什么:
我已经能够完成所有的事情,除了让它工作(:
我得到的错误表明,不知何故,有一个空标签 '' 作为依赖项:
$ make make: * 没有规则来制作目标
', needed by/home/rubens/bin/label.o'。停下来。
所以,这是我还无法运行的 makefile:
# Directories
SRC := process init
BIN := $(HOME)/bin
LIB := watershed
LIBPATH := $(WATERSHED)/lib
INC := $(WATERSHED)/include $(XERCES)/include
# Paths
MPICPP := mpic++
SOURCES := $(shell find $(SRC) -name '*.cpp')
OBJECTS := $(addprefix $(BIN)/, $(notdir $(SOURCES:.cpp=.o)))
SHARED := $(OBJECTS:.o=.so)
# Flags
CFLAGS := -std=c++0x -O2 -Wall -fPIC
CFLAGS += $(foreach inc, $(INC), -I $(inc))
LFLAGS :=
LFLAGS += $(foreach lib, $(LIB), -l $(lib))
LFLAGS += $(foreach path, $(LIBPATH), -L $(lib))
# Rules
$(SHARED): | bindir
%.o:
@echo $@ -- [$<][$^][$*]
@echo $(MPICPP) $(CFLAGS) -c $< -o $@
%.so: %.o
@echo $(MPICPP) $(LFLAGS) -shared $< -o $@
bindir:
@mkdir -p $(BIN)
# Utilities
.PHONY: all clean
all: $(SHARED)
clean:
@rm -f $(OBJECTS) $(SHARED)
# Dependencies
define dependencies
$(addprefix $(BIN)/, $(notdir $(1:.cpp=.o))): \
$(shell $(MPICPP) $(CFLAGS) -MM $(1) | sed 's/^.*\.o:[ ]*//')
endef
$(foreach src, $(SOURCES), $(eval $(call dependencies, $(src))))
错误似乎在哪里:
这似乎是由依赖生成步骤引起的,因为当我删除任何空行时,将输出通过管道传输到grep,如下所示:
define dependencies
$(addprefix $(BIN)/, $(notdir $(1:.cpp=.o))): \
$(shell $(MPICPP) $(CFLAGS) -MM $(1) | sed 's/^.*\.o:[ ]*//' | \
grep -v ^$)
endef
错误以某种方式扩展为一个空的依赖项列表;我可以看到列表实际上是空的,规则 %.o: 中的 echo 是空的——唯一不为空的变量是 $@ 和 $*。
/home/rubens/bin/label.o -- [][][/home/rubens/bin/label]
mpic++ -std=c++0x -O2 -Wall -fPIC -I /home/rubens/libwatershed/include -I /home/rubens/xerces-c-3.1.1/include -c -o /home/ rubens/bin/label.o
mpic++ -l 分水岭 -L -shared /home/rubens/bin/label.o -o /home/rubens/bin/label.so
非常非常欢迎任何有关解决此问题的更好方法的建议;然而,我真的很想在使用Cmake 或Scons 之类的东西之前完成这个makefile 的编写。
【问题讨论】:
-
我不建议尝试使用 eval 生成依赖项。这真的很不愉快。您应该使用包含的 makefile。 make.mad-scientist.net/autodep.html 有一个很好的例子说明如何做到这一点,尽管如果你使用 GCC 或具有兼容标志的编译器,你可以使用
-MM选项进行简化。 -
+1 好吧,我想最好的办法是使用包含的 makefile 或使用
cMake/Scons。无论如何,我会留下这个问题,所以有人可能会给它一个解决方案。 -
即使你让它工作了,你也永远不想使用它。效率太低了:每次运行 make 时,无论出于何种原因(甚至是“make clean”),它都会对所有源文件运行预处理器,然后对它们进行处理。一旦您获得多个源文件,它将使您的构建变得非常缓慢。使用包含文件要好得多,因为它将依赖信息保存为文件,以便下次运行 make 时可以直接读取。另外,它只会重新计算更改文件的依赖关系信息,而不是每次运行 make 时对每个文件的依赖信息。
-
+1 好的,兄弟,我要结束这个问题了(:
标签: c++ makefile dependencies shared-libraries mpic++