构建内部依赖第三方库的c++静态库
Build a static library for c++ which is internally dependent on third-party libraries
我想让图书馆在 /home/my/library/libmyfoo.a
的位置说 libmyfoo.a
我想以最简单的形式使用这个静态库,如下所示:
假设这是 myProgram.cpp
#include "AAA.h"
int main(void) {
int x = 2;
myFooFunction(x);
return(0);
}
我想运行这个作为g++ -std=c++11 -I/path/to/AAA.h myProgram.c -o myProgram -L/home/my/library/ -lmyfoo
现在:
AAA.h
(和AAA.cc
)依赖第三方framework/libraries,即gstreamer、protobuf和 grpc
/path/to/AAA.h
的等级是
Makefile
AAA.h
AAA.cc
AAA.o
BBB(Folder)
BBB.cc
BBB.h
BBB.o
Makefile 具有以下规则:
GOOGLEAPIS_GENS_PATH ?= $(HOME)/GOOGLE/googleapis/gens
GOOGLEAPIS_API_CCS = $(shell find $(GOOGLEAPIS_GENS_PATH)/google/api \
-name '*.pb.cc')
GOOGLEAPIS_RPC_CCS = $(shell find $(GOOGLEAPIS_GENS_PATH)/google/rpc \
-name '*.pb.cc')
GOOGLEAPIS_SPEECH_CCS = $(shell find \
$(GOOGLEAPIS_GENS_PATH)/google/cloud/speech -name '*.pb.cc')
GOOGLEAPIS_LONGRUNNING_CCS = $(shell find \
$(GOOGLEAPIS_GENS_PATH)/google/longrunning -name '*.pb.cc')
GOOGLEAPIS_CCS = $(GOOGLEAPIS_API_CCS) $(GOOGLEAPIS_RPC_CCS) \
$(GOOGLEAPIS_LONGRUNNING_CCS) $(GOOGLEAPIS_SPEECH_CCS)
OBJS = ./BBB/BBB.o AAA.o
.PHONY: all
all: libmyfoo.a
libmyfoo.a: $(OBJS) $(GOOGLEAPIS_CCS:.cc=.o)
ar rcs $@ $(OBJS) $(GOOGLEAPIS_CCS:.cc=.o)
ranlib $@
echo "build final executable......"
这将构建 libmyfoo.a
,其中包含大量 *.o
文件。
问题: 当我尝试 运行 上面显示的 myProgram.cpp
时,它会抛出对很多东西的未定义引用。这意味着它没有正确链接。
现在 AAA.cc
和 BBB.cc
依赖于 grpc、protobuf 和 gstreamer,正如我所说的。所以我将 myProgram.cpp
中的那些链接为
g++ -std=c++11 -I/path/to/AAA.h myProgram.c -o myProgram -L/home/my/library/ -lmyfoo -L/usr/lib -L/usr/lib64 -L/usr/local/lib64 -L/usr/local/lib -lgrpc++ -lgrpc -lgrpc++_reflection -lprotobuf -lpthread -lglib-2.0 -lgobject-2.0 -lgstreamer-1.0 -ldl -lboost_system -lboost_thread
而这个 绝对没问题。
有人可以解释这是为什么吗?
还有可能 运行 myProgram.cpp
前面提到的方式,即 g++ -std=c++11 -I/path/to/AAA.h myProgram.c -o myProgram -L/home/my/library/ -lmyfoo
此致,
当您使用的静态库依赖于共享库时,您需要针对这些共享库显式 link 您的最终二进制文件。原因是静态库只是目标文件的集合,打包到 "ar" 存档中(这就是 .a
文件。)没有存储有关共享库依赖项的信息。
我想让图书馆在 /home/my/library/libmyfoo.a
libmyfoo.a
我想以最简单的形式使用这个静态库,如下所示:
假设这是 myProgram.cpp
#include "AAA.h"
int main(void) {
int x = 2;
myFooFunction(x);
return(0);
}
我想运行这个作为g++ -std=c++11 -I/path/to/AAA.h myProgram.c -o myProgram -L/home/my/library/ -lmyfoo
现在:
AAA.h
(和AAA.cc
)依赖第三方framework/libraries,即gstreamer、protobuf和 grpc
/path/to/AAA.h
的等级是
Makefile
AAA.h
AAA.cc
AAA.o
BBB(Folder)
BBB.cc
BBB.h
BBB.o
Makefile 具有以下规则:
GOOGLEAPIS_GENS_PATH ?= $(HOME)/GOOGLE/googleapis/gens
GOOGLEAPIS_API_CCS = $(shell find $(GOOGLEAPIS_GENS_PATH)/google/api \
-name '*.pb.cc')
GOOGLEAPIS_RPC_CCS = $(shell find $(GOOGLEAPIS_GENS_PATH)/google/rpc \
-name '*.pb.cc')
GOOGLEAPIS_SPEECH_CCS = $(shell find \
$(GOOGLEAPIS_GENS_PATH)/google/cloud/speech -name '*.pb.cc')
GOOGLEAPIS_LONGRUNNING_CCS = $(shell find \
$(GOOGLEAPIS_GENS_PATH)/google/longrunning -name '*.pb.cc')
GOOGLEAPIS_CCS = $(GOOGLEAPIS_API_CCS) $(GOOGLEAPIS_RPC_CCS) \
$(GOOGLEAPIS_LONGRUNNING_CCS) $(GOOGLEAPIS_SPEECH_CCS)
OBJS = ./BBB/BBB.o AAA.o
.PHONY: all
all: libmyfoo.a
libmyfoo.a: $(OBJS) $(GOOGLEAPIS_CCS:.cc=.o)
ar rcs $@ $(OBJS) $(GOOGLEAPIS_CCS:.cc=.o)
ranlib $@
echo "build final executable......"
这将构建 libmyfoo.a
,其中包含大量 *.o
文件。
问题: 当我尝试 运行 上面显示的 myProgram.cpp
时,它会抛出对很多东西的未定义引用。这意味着它没有正确链接。
现在 AAA.cc
和 BBB.cc
依赖于 grpc、protobuf 和 gstreamer,正如我所说的。所以我将 myProgram.cpp
中的那些链接为
g++ -std=c++11 -I/path/to/AAA.h myProgram.c -o myProgram -L/home/my/library/ -lmyfoo -L/usr/lib -L/usr/lib64 -L/usr/local/lib64 -L/usr/local/lib -lgrpc++ -lgrpc -lgrpc++_reflection -lprotobuf -lpthread -lglib-2.0 -lgobject-2.0 -lgstreamer-1.0 -ldl -lboost_system -lboost_thread
而这个 绝对没问题。
有人可以解释这是为什么吗?
还有可能 运行 myProgram.cpp
前面提到的方式,即 g++ -std=c++11 -I/path/to/AAA.h myProgram.c -o myProgram -L/home/my/library/ -lmyfoo
此致,
当您使用的静态库依赖于共享库时,您需要针对这些共享库显式 link 您的最终二进制文件。原因是静态库只是目标文件的集合,打包到 "ar" 存档中(这就是 .a
文件。)没有存储有关共享库依赖项的信息。