c++ - libtensorflow_core.a 缺少符号(tensorflow::port::InitMain(char const*, int*, char***)
问题描述
我已经使用 tensorflow/contrib/makefiles/gen/lib 文件夹编译了静态库 libtensorflow_core.a
./tensorflow/contrib/makefile/build_all_linux.sh
脚本
对 CentOS 6.10 进行一些小的调整以包含 libstdc++ 的 LD_LIBRARY_PATH,因为 CentOS 6 附带的 gcc 是 gcc 4.4,而 C++11 需要 gcc 4.8
我已经通过使用我的模型测试基准二进制文件来测试编译是否成功
./tensorflow/contrib/makefile/gen/bin/benchmark etc
这一切都按预期工作。
现在我在我的应用程序中托管 Tensorflow,该应用程序以前动态链接到 libtensorflow_cc.so 和 libtensorflow_framework.so
相反,我静态链接到 libtensorflow_core.a
我的插件的编译和链接成功。
At runtime the following error occurs:
/usr/local/Nuke11.3v1/Nuke11.3: symbol lookup error: /usr/OFX/Plugins/rotobot.ofx.bundle/Contents/Linux-x86-64/rotobot.ofx: undefined symbol: _ZN10tensorflow4port8InitMainEPKcPiPPPc
我们可以看到缺少的符号是
tensorflow::port::InitMain(char const*, int*, char***)
我的代码确实包含这个功能
[samh@apollo-centos6 Rotobot-CPU-static]$ grep -rn InitMain rotobot.cpp
130: tensorflow::port::InitMain(&usage[0], &argc, NULL);
我需要对我的 libtensorflow_core.a Makefile 进行哪些调整以包含 InitMain?
山姆
我可以看到这个函数在可以工作的基准二进制文件中
我还可以看到基准源如下
BENCHMARK_SRCS := \
tensorflow/core/util/reporter.cc \
tensorflow/tools/benchmark/benchmark_model.cc \
tensorflow/tools/benchmark/benchmark_model_main.cc
我编译的 LIBS 标志是 libprotobuf.a 和 libtensorflow_core.a 以及我的应用程序所需的其他东西
我想如果你有以下
#include <tensorflow/core/platform/init_main.h>
#include <tensorflow/core/public/session.h>
int main(int argc, char* argv[]){
char usage[] = "iLikeTurtles";
tensorflow::port::InitMain(&usage[0], &argc, NULL);
}
触发错误就足够了
我希望该程序的功能与链接到 libtensorflow_cc.so 和 libtensorflow_framework.so 的代码相同
调查
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/tools/benchmark/BUILD
deps = select({
"//tensorflow:android": [
"//tensorflow/core:android_tensorflow_lib",
"//tensorflow/core:android_tensorflow_test_lib",
],
"//conditions:default": [
"//tensorflow/core:core_cpu",
"//tensorflow/core:lib",
"//tensorflow/core:framework",
"//tensorflow/core:framework_internal",
"//tensorflow/core:framework_lite",
"//tensorflow/core:protos_all_cc",
"//tensorflow/core:tensorflow",
"//tensorflow/core:test",
],
}),
看起来我们可能需要 framework、framework_internal 和 framework_lite 的 .o 文件。
解决方案
魔鬼在细节中
这是使用静态库的库参数
-Wall -L$(TENSORFLOW)/tensorflow/contrib/makefile/gen/protobuf-host/lib -Wl,--allow-multiple-definition -Wl,--whole-archive $(TENSORFLOW)/tensorflow/contrib/makefile/gen/lib/libtensorflow-core.a -Wl,--no-whole-archive $(TENSORFLOW)/tensorflow/contrib/makefile/downloads/nsync/builds/default.linux.c++11/nsync.a -lstdc++ -l:libprotobuf.a -lz -lm -ldl -lpthread -lrt
然后一切正常
这是通过在执行 build_all_linux.sh 时查看 make VERBOSE=true 来破译的
并查看用于构建和链接基准可执行文件的最后一个命令
你可能不需要 -lrt 但我在 CentOS 6.10 上需要
我仍然需要在 OSX 上做同样的事情
在 OSX 上构建仍然使用 build_all_linux.sh 脚本,因为 OSX 足够接近 Linux
TENSORFLOW_LIBS = -Wl,-force_load,$(TENSORFLOW)/tensorflow/contrib/makefile/gen/lib/libtensorflow-core.a -Wl,-force_load,$(TENSORFLOW)/tensorflow/contrib/makefile/downloads/nsync/builds/default.macos.c++11/nsync.a -Wl,-force_load,$(TENSORFLOW)/tensorflow/contrib/makefile/gen/protobuf-host/lib/libprotobuf.a -lstdc++ -lz -lpthread
推荐阅读
- javascript - 如何在 HTML Canvas 上获取由 fillText() 填充的像素?
- c# - 如何从 asp.net mvc 中的视图文件(.cshtml)中的时间戳解析日期和时间?
- python - 如何检查一个项目是否是列表中的第一个项目
- asp.net-mvc - 在 MVC 中隐藏 URL 中的用户 ID
- python - 如何将图像分类为噪声图像和无噪声图像?
- django - Dango bootstrap 样式在 dev-box 上显示很好,而不是在生产中
- c# - 使用 FireFox 而非 Chrome 时发生双重回发
- python - Django - 注册重定向到登录页面不起作用
- javascript - 从 Microsoft Graph API(测试版)通信 API 获取实时更新
- android - 如何将图像放在文本中间的文本下方?