c++ - 在 makefile 中编写依赖项,使用 makefile

标签 c++ makefile dependencies shared-libraries mpic++

基于一些 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'. Stop.

所以,这是我还不能运行的 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 在规则 %.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

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

最佳答案

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

关于c++ - 在 makefile 中编写依赖项,使用 makefile,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16359449/

相关文章:

java - 在 Android Maven 项目中使用纯 Java 库

c++ - 尝试在 C++ 中使用 double 。不确定我哪里出错了

c++ - std type_traits 与 Qt type_traits 冲突

android - 对于 OpenCV4Android,Android.mk 中的 %=% 是什么意思?

c - 对已链接的函数的 undefined reference

grails - 如何排除Grails项目中某个jar依赖的特定包?

c++ - 从 cocos2d 移植到 cocos2d-x

c++ - 如何给 vector 数组一个大小?

gcc - 编译 OpenSSL 时 undefined reference

java - Apache Rampart 的 Maven 依赖项解析失败