使用 Opencv 和 Tensorflow c++ 时冲突 Protobuf 版本

Conflict Protobuf version when using Opencv and Tensorflow c++

我目前正在尝试在非 bazel 项目中使用 Tensorflow 的共享库,因此我使用 bazel 从 tensorflow 创建了一个 .so 文件。

但是当我启动一个同时使用 Opencv 和 Tensorflow 的 c++ 程序时,它使我出现以下错误:

[libprotobuf FATAL external/protobuf/src/google/protobuf/stubs/common.cc:78] This program was compiled against version 2.6.1 of the Protocol Buffer runtime library, which is not compatible with the installed version (3.1.0). Contact the program author for an update. If you compiled the program yourself, make sure that your headers are from the same version of Protocol Buffers as your link-time library. (Version verification failed in "/build/mir-pkdHET/mir-0.21.0+16.04.20160330/obj-x86_64-linux-gnu/src/protobuf/mir_protobuf.pb.cc".) terminate called after throwing an instance of 'google::protobuf::FatalException'

what(): This program was compiled against version 2.6.1 of the Protocol Buffer runtime library, which is not compatible with the installed version (3.1.0). Contact the program author for an update. If you compiled the program yourself, make sure that your headers are from the same version of Protocol Buffers as your link-time library. (Version verification failed in "/build/mir-pkdHET/mir-0.21.0+16.04.20160330/obj-x86_64-linux-gnu/src/protobuf/mir_protobuf.pb.cc".) Abandon (core dumped)

你能帮帮我吗?

谢谢

该错误表明该程序是使用来自 protobuf 2.6.1 的 headers(.h 个文件)编译的。这些 headers 通常位于 /usr/include/google/protobuf/usr/local/include/google/protobuf 中,但它们可能位于其他位置,具体取决于您的 OS 以及程序的构建方式。您需要将这些 headers 更新到版本 3.1.0 并重新编译程序。

这确实是一个很严重的问题!我收到与您类似的以下错误:

$./ceres_single_test 
[libprotobuf FATAL google/protobuf/stubs/common.cc:78] This program was compiled against version 2.6.1 of the Protocol Buffer runtime library, which is not compatible with the installed version (3.1.0).  Contact the program author for an update.  If you compiled the program yourself, make sure that your headers are from the same version of Protocol Buffers as your link-time library.  (Version verification failed in "/build/mir-pkdHET/mir-0.21.0+16.04.20160330/obj-x86_64-linux-gnu/src/protobuf/mir_protobuf.pb.cc".)
terminate called after throwing an instance of 'google::protobuf::FatalException'
Aborted

我的解决方法:

cd /usr/lib/x86_64-linux-gnu
sudo mkdir BACKUP
sudo mv libmirprotobuf.so* ./BACKUP/

现在,正在测试的可执行文件可以运行了,太棒了。然而,不酷的是,如果没有 shell 中的 运行 将 BACKUP 路径添加到 LD_LIBRARY_PATH,像 gedit 这样的东西就不再工作了:-(
希望那里有更好的解决办法?

您应该使用链接描述文件重建 TensorFlow,以避免在 Bazel 创建的共享库中使第三方符号成为全局符号。这就是 TensorFlow 的 Android Java/JNI 库能够与设备上预安装的 protobuf 库共存的方式(查看 tensorflow/contrib/android 中的构建规则以获得工作示例)

这是我从 Android 库中改编的用于执行此操作的构建文件:

package(default_visibility = ["//visibility:public"])

licenses(["notice"])  # Apache 2.0

exports_files(["LICENSE"])

load(
    "//tensorflow:tensorflow.bzl",
    "tf_copts",
    "if_android",
)

exports_files([
    "version_script.lds",
])

# Build the native .so.
# bazel build //tensorflow/contrib/android_ndk:libtensorflow_cc_inference.so \
#   --crosstool_top=//external:android/crosstool \
#   --host_crosstool_top=@bazel_tools//tools/cpp:toolchain \
#   --cpu=armeabi-v7a
LINKER_SCRIPT = "//tensorflow/contrib/android:version_script.lds"

cc_binary(
    name = "libtensorflow_cc_inference.so",
    srcs = [],
    copts = tf_copts() + [
        "-ffunction-sections",
        "-fdata-sections",
    ],
    linkopts = if_android([
        "-landroid",
        "-latomic",
        "-ldl",
        "-llog",
        "-lm",
        "-z defs",
        "-s",
        "-Wl,--gc-sections",
        "-Wl,--version-script",  # This line must be directly followed by LINKER_SCRIPT.
        LINKER_SCRIPT,
    ]),
    linkshared = 1,
    linkstatic = 1,
    tags = [
        "manual",
        "notap",
    ],
    deps = [
        "//tensorflow/core:android_tensorflow_lib",
        LINKER_SCRIPT,
    ],
)

以及version_script.lds的内容:

{
  global:
    extern "C++" {
        tensorflow::*;
    };
  local:
    *;
};

这将使 tensorflow 命名空间中的所有内容都全局化并可通过库使用,同时隐藏重置并防止它与 protobuf 冲突。

(为此浪费了大量时间,希望对您有所帮助!)

错误提示Protocol Buffer运行时库与安装的版本不兼容。此错误来自 GTK3 库。 GTK3 使用 Protocol Buffer 2.6.1。如果你使用 GTK3 来支持 Opencv,你会得到这个错误。解决此问题的最简单方法是使用 QT 而不是 GTK3。

如果您使用 Cmake GUI 安装 Opencv,只需 select QT 支持而不是使用 GTK3。您可以使用以下命令安装QT。

sudo apt install qtbase5-dev 

-Dprotobuf_BUILD_SHARED_LIBS=ON

重建libprotobuf

然后make install覆盖旧版本