使用多个目录中的文件生成文件的问题
Issue with Make file with files in multiple directories
我有下面的制作文件。当我只有一个目录(即 SOURCEDIR)中的文件时,这工作正常。现在我添加了 PROTOSOURCES 和 PROTOSRCDIR。
我将在 SRCDIR 中执行生成文件。
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:源对象符合预期,并列出了 SOURCEDIR 中的所有对象文件。但是,原型对象只列出 *.cc 文件而不是 *.o 文件。我希望它在与 patsubst 一起使用后拥有 PROTOOBJECTS 中的所有对象文件列表。顺便说一句,SOURCEDIR 有 *.cpp 个文件,而 PROTOSRCDIR 有 .pb.cc 个文件。这些是由谷歌协议缓冲区编译器生成的。
问题 2:
这将是我的制作文件的最终目标。
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 进行哪些修改才能创建共享库?
我建议使用make的VPATH
功能。这也告诉人们在其他目录中寻找"来源"。所有目标文件最终都将与共享库一起出现在构建目录中。
# 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 和 p1.pb.cc 中有 s1.cpp 和 s2.cpp,p2.pb.cc 在 PROTOSRCDIR 中,libprotoinf.so 依赖于 s1.o、s2.o、p1.pb.o、p2.pb.o
Make 可以使用其内置的%.o: %.cpp
规则轻松地从 s1.cpp 构建 s1.o,从 s2 构建 s2.o.cpp。当它尝试构建 p1.pb.o 时,它不会在当前目录中找到 p1.pb.cc,但 VPATH 变量告诉它也在 PROTOSRCDIR 中查找。然后make将从$(PROTOSRCDIR)/p1.pb.cc构建p1.pb.o,就好像cc文件存在于当前目录中一样。
使用这种技术,您甚至可以在与 SOURCEDIR 不同的单独构建目录中构建。
- 使用mongocxx驱动程序时包含头文件问题
- 生成文件问题
- 从文件问题加载纹理 Android NDK 和 OpenGL
- Xcode 11 头文件问题
- 使用 c++ ifstream 读取文本文件问题
- 单独的类声明和方法定义文件问题
- C++生成文件问题
- 生成文件问题(体系结构x86_64的未定义符号:"_main",引用自:主可执行文件的隐式入口/启动)
- C++删除未使用的库的生成文件问题
- C++ 使文件问题
- 阅读矩阵市场文件C++问题
- 查找第一个文件问题无法使任何示例正常工作。
- "Recursive Makefile Considered Harmful"样式生成文件问题
- 标题文件问题中的类定义
- 嵌套 while 循环,包含文件 c++ 问题
- 几个制作文件问题
- 生成文件问题,获取"目标'rgbapixel.o'的配方失败"
- 从yaml文件问题opencv读取数据
- 类成员C++标头和 .cc 文件问题
- 添加选项以显示百分比时出现生成文件问题