我有以下的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&amp;中的文件。生成.o文件
2)编译PROTOSRCDIR&amp;中的文件。生成.o文件
3)生成一个共享库libprotointf.so文件,其中包含上述两个步骤中的所有对象文件。
我的图书馆链接和编译命令如下所示,当我只有SRCDIR中的文件时,工作正常。
$(LIBRARY):
$(CC) $(SHFLAGS) $(CFLAGS) $(LDFLAGS) $(SRCOBJECTS) -o $(LIBRARY)
$(SOURCEDIR)/%.o: $(SOURCEDIR)/%.cpp
$(CC) $(CFLAGS) $(LDFLAGS) -c -fPIC $< -o $@
为了制作共享库,我需要对Makefile进行哪些修改?
答案 0 :(得分:0)
我建议使用make的VPATH
功能。这告诉make也在其他目录中查找“sources”。所有目标文件都将与共享库一起在构建目录中结束。
# Note: GNU make syntax
VERSION := 0.0.1
CXX := /usr/bin/g++
CXXFLAGS:= -Wall -fPIC
LDFLAGS := $(shell pkg-config --cflags --libs protobuf)
SHFLAGS := -shared
SOURCEDIR := .
PROTOSRCDIR := ~/depot/Projects/src1/obj/cpp
VPATH := $(SOURCEDIR):$(PROTOSRCDIR)
SOURCES := $(wildcard $(SOURCEDIR)/*.cpp) # full paths
SOURCEFILES := $(notdir $(SOURCES)) # just (source) filenames
OBJECTS := $(SOURCEFILES:.cpp=.o) # all in the current dir
PROTOSOURCES = $(wildcard $(PROTOSRCDIR)/*.cc) # full paths
PROTOSOURCEFILES := $(notdir $(PROTOSOURCES)) # just (source) filenames
PROTOOBJECTS := $(PROTOSOURCEFILES:.cpp=.o) # all in the current dir
LIBRARY = libprotointf.so
.PHONY: all clean
all: $(LIBRARY)
$(LIBRARY): $(OBJECTS) $(PROTOOBJECTS)
$(CC) $(SHFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $^
注意:没有%.o: %.cc
或%.o: %.cpp
规则。 GNU make内置了这些内容。您只需填写CPPFLAGS
,CXXFLAGS
请注意,按惯例,CC
是包含C编译器的变量。 C ++编译器的变量是CXX
。同样,CFLAGS
用于C编译器; CXXFLAGS
是包含C ++编译器标志的变量。
这是如何运作的:
假设您在SOURCEDIR中有s1.cpp和s2.cpp,在PROTOSRCDIR中有p1.pb.cc,p2.pb.cc,libprotoinf.so依赖于s1.o,s2.o,p1.pb.o,p2 .pb.o
Make可以使用其内置的%.o: %.cpp
规则从s2.cpp轻松地从s1.cpp和s2.o构建s1.o。当它试图构建p1.pb.o时,它在当前目录中找不到p1.pb.cc,但VPATH变量告诉它也查看PROTOSRCDIR。然后make将从$(PROTOSRCDIR)/p1.pb.cc构建p1.pb.o,就好像cc文件存在于当前目录中一样。
使用这种技术,您甚至可以构建一个与SOURCEDIR不同的单独构建目录。