6

基于一些 SO 问题 - 以及一些进一步的参考发现 - 我正在尝试构建一个能够:

  • 给定 中的目录,查找要编译$(SRC)的文件;.cpp
  • 编译.cpp,生成.o对象;
  • 从以前编译的每个生成.so共享对象。.o

为了实现这一目标,make 文件应该做的是:

  • 给定 中的目录,查找要编译$(SRC)的文件;.cpp
  • .cpp使用-MM编译器的标志为每个构建依赖项列表;
  • $(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

该错误以某种方式扩展到一个空的依赖项列表;我可以看到使用echo's in 规则的列表实际上是空的%.o:——唯一不为空的变量是$@and $*

/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 /标签.o

mpic++ -l 分水岭 -L -shared /home/rubens/bin/label.o -o /home/rubens/bin/label.so

非常非常欢迎任何有关解决此问题的更好方法的建议;然而,我真的很想在我开始使用类似Cmakeor的东西之前完成这个 makefile 的编写Scons

4

2 回答 2

1

-MM将已经生成Makefile格式的依赖项,因此您可以通过将每个依赖项生成到同一个文件中来简化这一点*.cpp,然后只需执行-include $(DEPS_FILE). 这可能比使用 eval 更易于维护。

于 2013-05-03T14:27:21.120 回答
0

在 makefile 变量 SOURCES 的定义行,搜索 cpp 文件,您可能必须像这样重写:find $(SRC) -name "*.cpp"

于 2013-05-03T13:11:48.550 回答