使用makefile在makefile中编写依赖项

Rub*_*ens 5 c++ dependencies makefile shared-libraries mpic++

基于一些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))))
Run Code Online (Sandbox Code Playgroud)

确切似乎是错误的地方:它似乎是由依赖关系生成步骤引起的,因为当我删除任何空行时,将输出管道输出到grep,如下所示:

define dependencies
$(addprefix $(BIN)/, $(notdir $(1:.cpp=.o))): \
        $(shell $(MPICPP) $(CFLAGS) -MM $(1) | sed 's/^.*\.o:[ ]*//' | \
        grep -v ^$)
endef
Run Code Online (Sandbox Code Playgroud)

错误以某种方式转换为依赖关系的空列表; 我能够看到列表实际上是空的,echo在规则中%.o:- 唯一不变的变量是$@$*.

/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 watershed -L -shared /home/rubens/bin/label.o -o /home/rubens/bin/label.so

有关更好的解决方法的建议是非常非常受欢迎的; 然而,在我开始使用像Cmake或之类的东西之前,我真的想完成这个makefile的编写Scons.

Nic*_*sky 1

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