Linux 16.04下TensorFlow v2.3编译label_wav.cc报错求助
我之前处理TensorFlow C++编译问题时经常碰到这类错误,本质都是protobuf版本不匹配或者系统里的protobuf头文件/库冲突导致的。你遇到的ArenaStringPtr找不到成员方法、feed_devices_被识别成int类型而非map这些问题,都是因为TensorFlow 2.3依赖的protobuf版本和你当前环境里的版本不兼容。
核心前提:TensorFlow 2.3要求的protobuf版本
TensorFlow 2.3官方指定依赖的是protobuf 3.9.2,高版本或低版本的protobuf都会出现API差异,导致你看到的编译错误。接下来一步步解决:
步骤1:清理冲突的protobuf版本
首先检查当前系统里的protobuf版本:
protoc --version
如果输出不是3.9.2,先卸载系统自带的或者其他版本的protobuf:
sudo apt remove -y libprotobuf-dev protobuf-compiler sudo apt autoremove -y
步骤2:编译安装指定版本的protobuf(3.9.2)
下载源码并编译安装到独立路径,避免和系统库冲突:
# 下载源码包 wget https://github.com/protocolbuffers/protobuf/releases/download/v3.9.2/protobuf-all-3.9.2.tar.gz # 解压 tar -xzf protobuf-all-3.9.2.tar.gz && cd protobuf-all-3.9.2 # 配置编译参数(指定安装路径) ./configure --prefix=/usr/local/protobuf-3.9.2 # 编译并安装(-j后面是CPU核心数,加快编译速度) make -j$(nproc) && sudo make install
步骤3:配置环境变量,让编译优先使用新安装的protobuf
临时生效(仅当前终端):
export PATH=/usr/local/protobuf-3.9.2/bin:$PATH export LD_LIBRARY_PATH=/usr/local/protobuf-3.9.2/lib:$LD_LIBRARY_PATH export CPLUS_INCLUDE_PATH=/usr/local/protobuf-3.9.2/include:$CPLUS_INCLUDE_PATH
如果要永久生效,把这些命令写入~/.bashrc:
echo 'export PATH=/usr/local/protobuf-3.9.2/bin:$PATH' >> ~/.bashrc echo 'export LD_LIBRARY_PATH=/usr/local/protobuf-3.9.2/lib:$LD_LIBRARY_PATH' >> ~/.bashrc echo 'export CPLUS_INCLUDE_PATH=/usr/local/protobuf-3.9.2/include:$CPLUS_INCLUDE_PATH' >> ~/.bashrc # 生效配置 source ~/.bashrc
验证配置是否成功:
protoc --version # 应该输出libprotoc 3.9.2
步骤4:重新编译label_wav.cc
确保你的CMakeLists.txt正确关联了TensorFlow和protobuf的依赖,示例配置如下:
cmake_minimum_required(VERSION 3.10) project(speech_recog) # 查找TensorFlow和protobuf find_package(TensorFlow REQUIRED) find_package(Protobuf REQUIRED) # 添加头文件路径 include_directories(${TensorFlow_INCLUDE_DIRS} ${PROTOBUF_INCLUDE_DIRS}) # 生成可执行文件 add_executable(speech_recog label_wav.cc) # 链接依赖库 target_link_libraries(speech_recog ${TensorFlow_LIBRARIES} ${PROTOBUF_LIBRARIES})
然后重新执行编译:
# 清理之前的编译缓存 make clean rm -rf CMakeCache.txt CMakeFiles # 重新编译 cmake . && make
错误原因补充
你看到的这些错误,比如struct google::protobuf::internal::ArenaStringPtr has no member named 'UnsafeArenaRelease',是因为不同版本的protobuf对ArenaStringPtr的API定义不同;而feed_devices_被识别成int类型,是因为TensorFlow的config.pb.h是用3.9.2版本的protoc生成的,如果你用其他版本的protobuf头文件,会导致map类型被错误解析成int,进而调用size()、Clear()等方法时失败。
内容的提问来源于stack exchange,提问作者sbojja

