为c ++构建一个静态库,该库内部依赖第三方库

时间:2019-02-22 06:30:18

标签: c++ makefile g++ gnu static-linking

我想在位置libmyfoo.a上让图书馆说/home/my/library/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)依赖于第三方框架/库,即 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.ccBBB.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

此致

1 个答案:

答案 0 :(得分:1)

当您使用的静态库取决于共享库时,您需要将最终的二进制文件与这些共享库明确链接。这样做的原因是静态库只是一个目标文件的集合,打包到一个“ ar”归档文件中(这就是.a文件。)没有存储有关共享库依赖项的信息。

相关问题