使用makefile在makefile中编写依赖项

Writing dependencies in makefile, with makefile

本文关键字:makefile 依赖 使用      更新时间:2023-10-16

基于一些SO问题-和一些进一步的参考发现-,我试图建立一个makefile能够:

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

make文件应该做的是:

  • 查找$(SRC)目录下需要编译的.cpp文件;
  • 使用-MM编译器的标志为每个.cpp构建依赖列表;
  • 使用$(eval ...)注释/添加每个依赖项;
  • 评估/解决找到的每个依赖项,生成.o.so文件。

目前我有什么:除了让它工作之外,我几乎可以做所有的事情我得到的错误状态是,不知何故,有一个空标签''作为依赖项:

$ make make: * No rule to make target ', 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/鲁本斯/bin/标签。0—[][][/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。/home/rubens/bin/label.so

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

-MM将已经生成对Makefile格式的依赖关系,因此您可以通过将每个*.cpp的依赖关系生成到相同的文件来简化这一点,然后只做-include $(DEPS_FILE)。这可能比eval更容易维护。

在makefile变量SOURCES的定义行,搜索cpp文件,你可能需要这样重写:$(SRC) -name "*.cpp"