【发布时间】:2015-02-03 22:08:48
【问题描述】:
我有下面的 make 文件。当我只有一个目录是 SOURCEDIR 时,这工作正常。现在我添加了 PROTOSOURCES 和 PROTOSRCDIR。
我将在 SRCDIR 中执行 makefile。
VERSION = 0.0.1
CC = /usr/bin/g++
CFLAGS = -Wall
LDFLAGS = `pkg-config --cflags --libs protobuf`
SHFLAGS = -shared
SOURCEDIR = .
PROTOSRCDIR = ~/depot/Projects/src1/obj/cpp
SOURCES = $(wildcard $(SOURCEDIR)/*.cpp)
PROTOSOURCES = $(wildcard $(PROTOSRCDIR)/*.cc)
SRCOBJECTS = $(patsubst $(SOURCEDIR)/%.cpp, $(SOURCEDIR)/%.o, $(SOURCES))
PROTOOBJECTS = $(patsubst $(PROTOSRCDIR)/%.cc, $(PROTOSRCDIR)/%.o, $(PROTOSOURCES))
LIBRARY = libprotointf.so
.PHONY: all clean
all: $(LIBRARY)
$(LIBRARY):
$(CC) $(SHFLAGS) $(CFLAGS) $(LDFLAGS) $(SRCOBJECTS) $(PROTOOBJECTS) -o $(LIBRARY)
$(SOURCEDIR)/%.o: $(SOURCEDIR)/%.cpp
$(CC) $(CFLAGS) $(LDFLAGS) -c -fPIC $< -o $@
$(PROTOSRCDIR)/%.o: $(PROTOSRCDIR)/%.cc
$(CC) $(CFLAGS) $(LDFLAGS) -c -fPIC $< -o $@
clean:
rm -f libprotointf.so
我遇到以下问题。
问题 1:SOURCEOBJECTS 符合预期并列出了 SOURCEDIR 中的所有目标文件。然而,PROTOOBJECTS 只列出 *.cc 文件而不是 *.o 文件。我希望它在与 patsubst 一起使用后拥有 PROTOOBJECTS 中的所有目标文件列表。顺便说一句,SOURCEDIR 有 *.cpp 文件,而 PROTOSRCDIR 有 .pb.cc 文件。这些是由 Google Protocol Buffer 编译器生成的。
问题 2:
这将是我的 make 文件的最终目标。
1) 编译 SRCDIR 中的文件并生成 .o 文件
2) 编译 PROTOSRCDIR 中的文件并生成 .o 文件
3) 生成一个共享库 libprotointf.so 文件,其中包含上述两步中的所有对象文件。
当我只有 SRCDIR 文件时,我的库链接和编译命令如下,效果很好。
$(LIBRARY):
$(CC) $(SHFLAGS) $(CFLAGS) $(LDFLAGS) $(SRCOBJECTS) -o $(LIBRARY)
$(SOURCEDIR)/%.o: $(SOURCEDIR)/%.cpp
$(CC) $(CFLAGS) $(LDFLAGS) -c -fPIC $< -o $@
为了制作共享库,我需要对我的 Makefile 做哪些修改?
【问题讨论】:
-
我不确定这是否与这些变量有关。这可能与您没有将
$(SRCOBJECTS) $(PROTOOBJECTS)列为$(LIBRARY)的先决条件有关。 -
与您的问题无关,但您不需要在
$(patsubst)调用中使用$(SOURCEDIR)和$(PROTOSRCDIR),您可以将它们作为%通配符的一部分吞下。以SRCOBJECTS = $(patsubst %.cpp, $%.o, $(SOURCES))为例。 -
不要使用
~使用$HOME。~是一个外壳,外壳不涉及在任何地方扩展$(PROTOSRCDIR)。 -
同样,您对
LDFLAGS的分配在您分配时不会被执行。 (它将在配方行中使用时执行,因为 shell 会看到反引号并运行命令,但这不一定是您希望发生的情况。)对于命令的 make-parse-time 运行,您需要使用$(shell)(和:=简单扩展的变量赋值让 make 只在解析时执行一次,而不是每次使用变量时执行一次)。 -
并且支持@user657267 在他们的评论中所说的
$(LIBRARY)目标并没有告诉make 构建它需要链接的对象,所以make 不会为你这样做。因此,即使您以前的 makefile 也只有在您预先构建了所有.o文件时才能正常工作。删除它们,它应该无法链接。