首页 > 解决方案 > 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 文件。

标签: c++tensorflowmakefile

解决方案


魔鬼在细节中

这是使用静态库的库参数

-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 

推荐阅读