我可以在独立的C++程序中使用静态C++tensorflow库,但不能在依赖于C++tensorflow库的qmake
项目中使用静态库。我正在使用-Wl,--allow-multiple-definition, -Wl,--whole-archive
的链接器选项,但没有效果。我能够构建独立程序和qmake项目,但qmake目标引发运行时错误。
我使用以下命令编译我的独立程序(test.cpp):
g++ -std=c++11 -Wl,--whole-archive -Wl,--allow-multiple-definition
-Wl,-O1 -Wl,-rpath,'$ORIGIN/lib' -Iinclude -Llib infer.o test.cpp
-ltensorflow_cc -ltensorflow_framework -o exec
在我的qmake项目中,目标(具有多个依赖项的test)是用构建的
g++ -m64 -Wl,--allow-multiple-definition -Wl,--whole-archive -Wl,
-O1 -Wl,-rpath,'$ORIGIN/lib' $(OBJECTS)/*.o
-L../lib/debugL../quackleio/lib/debug -L../lib/release
-L../quackleio/lib/release -L/usr/lib/86_64-linux-gnu -lquackleio -lquackle
-L../'$ORIGIN/lib' -ltensorflow_framework -ltensorflow_cc -lQtxGui -lQtCore
-lpthread -o test
这两个都成功编译,没有任何错误。但是,当qmake
抛出以下错误时,独立的C++程序运行时没有任何错误:
E tensorflow/core/common_runtime/session.cc:69] Not found: No session factory registered for the given session options: {target: "" config: } Registered factories are {}.
F inference/infer.cpp:16] Non-OK-status: NewSession(opts, &session) status: Not found: No session factory registered for the given session options: {target: "" config: } Regisstered factories are {}.
Aborted (core dumped)
在更深入的挖掘中,在test
上执行命令ldd会给出输出(经过简化,仅显示相关库):
ldd ./test
linux-vdso.so.1 => (0x00007ffda65de000)
libtensorflow_framework.so => /home/rishabh/quackle/inference/lib/libtensorflow_framework.so (0x00007f85d34fb000)
当在独立C++程序(exec)的可执行文件上运行相同的命令时,我得到了输出(同样只显示了相关的库):
ldd ./exec
linux-vdso.so.1 => (0x00007ffd8e09e000)
libtensorflow_cc.so => /home/rishabh/quackle/rishabh_code/inference/./lib/libtensorflow_cc.so (0x00007f8e45873000)
libtensorflow_framework.so => /home/rishabh/quackle/rishabh_code/inference/./lib/libtensorflow_framework.so (0x00007f8e44cbb000)
从这些输出中,可以观察到libtensorflow_cc.so不是测试可执行文件的依赖项,而是exec
文件的依赖性。然而,它们都使用相同的类infer.h
作为依赖项(qmake目标间接依赖于infer.h
,即它包括使用infer.h
中定义的类的头文件,而独立C++程序包括infer.h
作为直接依赖项)。
文件infer.h
的代码如下:
#include "tensorflow/core/public/session.h"
#include "tensorflow/core/graph/default_device.h"
#include "tensorflow/core/platform/env.h"
using namespace tensorflow;
class NNInference
{
private:
std::string graph_definition;
Session* session;
std::vector<Tensor> outputs;
Tensor input_tensor;
public:
NNInference(const string &, int);
~NNInference();
float getOutput(std::vector<float> &);
};
有人能帮我解决一下这里可能出现的问题吗?如何在qmake项目中成功使用libtensorflow_cc.so
?提前谢谢。
错误是因为qmake
目标的构建命令中包含的库的顺序!使用g++
命令中的顺序-ltensorflow_framework -ltensorflow_cc
即可工作。
如果订单对修复没有帮助。在二进制文件上使用ldd来确定是否添加了lib依赖项。
这是根据您使用的linux风格而变化的,但ld的某些版本不会链接库,除非使用它。
在tf的情况下,tensorflow_cc没有链接到我的二进制文件,尽管我指定了-l tensorflow_cc。
解决方案是根据需要向gcc添加-Wl、-no标志。GCC从左到右处理标志,因此在添加-lensorflow*之前指定此标志
ldd|grep tensorflow
一个相关的问题似乎是xcode上的力加载tf的要求。使用force_load选项。(对于静态库)