简介:面向P4与SDN实验学习者的环境配置安装包,围绕BMv2软件交换机与p4c编译器的依赖整合,汇集behavioral-model、gmock-1.7.0、protobuf-3.2.0、thrift-0.9.2等常用组件,适合需要搭建P4开发、编译与验证环境,并希望规避依赖版本冲突的读者。压缩包采用gz格式,整体约147.8MB;上游未提供文件总数和类型明细,故不作具体文件清单展开,从组件构成看主要服务于编译依赖、运行时库与测试框架的配套安装。目前已有611人学习下载,在P4入门实验与BMv2环境搭建场景中具有一定参考价值。其价值在于把多个容易冲突的依赖版本集中打包,帮助读者快速对齐BMv2、p4c与protobuf、thrift之间的版本关系,减少逐个查找、编译和排错的时间成本;资源描述中还附有配置教程入口,便于对照核对环境组成与定位常见配置问题。
1. 旧版 P4 环境配置安装包:为什么锁死 protobuf 3.2.0 和 thrift 0.9.2 反而省事
新机器直接追最新版 P4 工具链,常常在 simple_switch 起来之前就被 protobuf 和 thrift 的链接错误拦住。这套 P4 环境配置安装包把 behavioral-model、gmock-1.7.0、p4c、protobuf-3.2.0、thrift-0.9.2 锁在同一条编译链里,解决的不是“功能多”,而是旧实验代码能按原样复现。它适合要复现课程实验、维护老 bmv2 数据面、或者接手一套 p4c 编译脚本的人;新手能按顺序装完,熟手更该关注版本咬合和动态库路径。先把旧版本当作约束条件,不是退步,后面很多坑会少一半。
2. 拆包先看依赖图:bmv2、p4c 与 gmock-1.7.0 的版本咬合关系
2.1 版本咬合关系:protobuf 3.2.0 生成代码与 p4c 旧接口
这套组合里最容易误判的是 protobuf。p4c 编译过程中会调用 protoc 把.proto文件生成 C++ 源码,生成代码会直接调用 protobuf 的运行时接口。protobuf 3.2.0 生成的代码和较新的 protobuf 运行时在 API 上有差异,系统里如果先装了新版 protobuf,protoc --version可能看起来正常,但 p4c 编译到中段才报“没有匹配的函数”或者“版本不匹配”。检索里常把 protobuf 写成 protob,装包时认准目录名和protoc路径即可,不要用系统包管理器里的同名工具顶替。
thrift 0.9.2 的逻辑类似。bmv2 的 Thrift 服务端代码、p4c 里与 Thrift 相关的生成代码,都依赖 thrift 编译器生成的 C++ 头文件和运行时库。thrift 不同版本生成的代码在命名空间、序列化接口上有差别,混用后常见现象是编译能过、链接报未定义符号,或者 simple_switch 启动时找不到libthrift-0.9.2.so。这也是安装包把 thrift 单独放一个前缀目录的原因:路径可控,排查时能一眼看出当前用的是哪一套。
gmock-1.7.0 不参与数据面转发,却是 bmv2 构建系统里的测试依赖。它的版本不需要最新,关键是头文件和静态库路径要能被 behavioral-model 的 configure 找到。gmock 路径传错时,现象通常不是“测试失败”,而是make在链接测试目标时直接断掉,让人误以为 bmv2 主体编译有问题。把 gmock 当成构建依赖而不是运行时依赖,排查方向会清楚很多。
2.2 安装顺序与目录布局:先依赖后编译器
我一般把依赖统一放到一个独立前缀下,比如/opt/p4deps,不往/usr/local里混。这样后面升级或删除时不会污染系统库,出问题也能用ldd和PKG_CONFIG_PATH快速定位。顺序按“protobuf → thrift → gmock → behavioral-model → p4c”走:protobuf 和 thrift 是底层依赖,gmock 供 bmv2 构建使用,bmv2 和 p4c 放最后,避免它们先编到一半再回头补依赖。
目录布局可以固定成下面这样,安装包里各组件目录对应到同一层,脚本里只改DEPS一个变量:
export DEPS=/opt/p4deps sudo mkdir -p "$DEPS" sudo chown "$(id -u):$(id -g)" "$DEPS" # 预期布局 # $DEPS/protobuf-3.2.0 # $DEPS/thrift-0.9.2 # $DEPS/gmock-1.7.0 # $DEPS/bmv2 # $DEPS/p4c这段命令的逻辑是先建统一前缀,再把当前用户设为目录所有者,后面make install不需要反复 sudo。参数上,DEPS是整条链的根路径,id -u和id -g取当前用户和组,避免安装目录归 root 后普通用户无法清理。若实验机要求所有组件装在/usr/local,也可以改,但后面所有--prefix、PATH、LD_LIBRARY_PATH都要同步改,不能只改一处。
安装顺序不要凭感觉调换。先装 p4c 再装 protobuf,configure 阶段可能碰巧过,make 阶段会找不到protoc;先装 bmv2 再装 thrift,simple_switch 可能编出来但 Thrift 服务端缺失。旧工具链的构建脚本默认依赖顺序明确,按顺序走比“先编再说”省时间。
2.3 开工前系统基线检查:编译器、库和解释器
在解压任何源码之前,先确认基础工具齐不齐。旧版 P4 工具链对编译器版本没有夸张要求,但 autoconf、automake、libtool、pkg-config、bison、flex 缺一个,后面就会在奇怪的位置停住。下面的检查命令只做存在性验证,不改系统:
set -e for c in gcc g++ make autoconf automake libtoolize pkg-config bison flex python3; do if ! command -v "$c" >/dev/null 2>&1; then echo "missing: $c" else echo "ok: $c -> $(command -v "$c")" fi done gcc --version | head -n1 g++ --version | head -n1 make --version | head -n1set -e让脚本在明显错误时停下;command -v查命令是否存在;head -n1只取版本首行,避免输出太长。这里没有直接装包,是因为不同发行版的包名有差异。常见做法是先装build-essential autoconf automake libtool pkg-config bison flex libboost-all-dev libssl-dev libffi-dev,再按安装包里的 README 补 Python 绑定依赖。若安装包脚本明确要求 Python2,不要直接把系统python软链改掉,给旧工具链单独准备解释器路径更安全。
还要提前看系统里有没有旧 protobuf:
which protoc || true protoc --version 2>/dev/null || true pkg-config --modversion protobuf 2>/dev/null || true ldconfig -p 2>/dev/null | grep -i protobuf || true这几条命令用来判断“系统 protobuf 会不会抢先命中”。如果protoc已经指向新版,后面编译 p4c 前必须把$DEPS/protobuf-3.2.0/bin放到PATH最前面,并在 configure 时显式传--with-protobuf。不要只看make install成功,构建系统实际用哪套头文件,得靠which、pkg-config和ldd交叉确认。
3. 编译依赖链:protobuf 3.2.0、thrift 0.9.2 与 gmock 1.7.0 的安装命令
3.1 protobuf 3.2.0 源码编译与独立前缀安装
protobuf 是整条链的第一块砖。安装包里通常给的是源码目录,先解压再 configure。若目录里没有configure,先跑./autogen.sh;发布包一般自带 configure,不需要额外生成。
export DEPS=/opt/p4deps cd /path/to/pkg tar -xf protobuf-3.2.0.tar.gz cd protobuf-3.2.0 # 如果当前目录没有 configure,先执行 ./autogen.sh ./configure --prefix="$DEPS/protobuf-3.2.0" --enable-shared make -j"$(nproc)" make check make install这段命令的逻辑是:解压到源码目录,configure 指定独立前缀并开启共享库,make -j并行编译,make check跑自带测试,最后安装。参数上,--prefix决定protoc、头文件和库的落点;--enable-shared让后续 p4c 和 bmv2 链接动态库更方便;-j"$(nproc)"用 CPU 核数并行,内存小的机器改成-j2更稳。make check失败不一定代表库不可用,但至少要确认protoc能生成代码,否则后面 p4c 一定卡住。
安装后立刻验证,不要等 p4c 报错再回头:
export DEPS=/opt/p4deps "$DEPS/protobuf-3.2.0/bin/protoc" --version PKG_CONFIG_PATH="$DEPS/protobuf-3.2.0/lib/pkgconfig" \ pkg-config --modversion protobuf预期protoc输出 3.2.0,pkg-config也输出 3.2.0。若pkg-config找不到,检查前缀下是lib/pkgconfig还是lib64/pkgconfig;若版本不是 3.2.0,说明环境变量或系统路径抢先了,先解决路径再继续。
3.2 thrift 0.9.2 编译参数与语言绑定裁剪
thrift 0.9.2 的编译面比 protobuf 大,默认会尝试多种语言绑定。实验环境里只跑 C++ 数据面时,没必要把所有语言都编上,裁剪掉不需要的绑定能减少 OpenSSL、Python 解释器版本带来的干扰。下面的写法保留 C++ 和 Python 绑定,同时关掉常见但不需要的语言:
export DEPS=/opt/p4deps cd /path/to/pkg tar -xf thrift-0.9.2.tar.gz cd thrift-0.9.2 ./configure --prefix="$DEPS/thrift-0.9.2" \ --with-cpp --with-python \ --without-java --without-php --without-ruby --without-nodejs \ --without-go --without-csharp --without-perl --without-haskell \ --without-erlang make -j"$(nproc)" make install逻辑说明:--prefix仍然指向独立目录;--with-cpp保留 bmv2 和 p4c 需要的 C++ 绑定;--with-python留给 runtime CLI 一类工具;后面的--without-*是裁剪项。参数不是越少越好,如果安装包脚本明确要用 Python 绑定,就不要关;如果只跑 simple_switch,也可以先关掉 Python,等需要 CLI 时再补编。编译中若出现 OpenSSL 头文件相关报错,先不要动系统 OpenSSL,按第 5 章的方式缩小绑定或加--without-openssl再试。
安装后验证 thrift 编译器版本:
export DEPS=/opt/p4deps "$DEPS/thrift-0.9.2/bin/thrift" -version ls "$DEPS/thrift-0.9.2/lib" | grep -i thrift || true第一条确认thrift可执行文件来自 0.9.2,第二条看运行库是否落在前缀目录。若lib下没有库,检查是否在lib64;若版本输出不是 0.9.2,后面 bmv2 的 Thrift 生成代码可能出现 ABI 不一致。
3.3 gmock 1.7.0 的放置方式与 bmv2 引用路径
gmock-1.7.0 一般自带 configure,安装到独立前缀即可。它的头文件在include/gmock,库文件在lib或lib64。bmv2 的 configure 需要能找到这个前缀,所以不建议只解压不安装。
export DEPS=/opt/p4deps cd /path/to/pkg tar -xf gmock-1.7.0.tar.gz cd gmock-1.7.0 ./configure --prefix="$DEPS/gmock-1.7.0" make -j"$(nproc)" make install这段命令没有额外开关,重点是--prefix要和后面 bmv2 的--with-gmock保持一致。make -j可以并行,gmock 本身不大,编译很快。安装后检查头文件和库:
export DEPS=/opt/p4deps ls "$DEPS/gmock-1.7.0/include/gmock/gmock.h" ls "$DEPS/gmock-1.7.0/lib"/libgmock* 2>/dev/null || \ ls "$DEPS/gmock-1.7.0/lib64"/libgmock* 2>/dev/null || true如果头文件存在但库不在lib,大概率在lib64。后面给 bmv2 配CPPFLAGS和LDFLAGS时要把两个路径都考虑进去。gmock 不是运行时库,不需要写进LD_LIBRARY_PATH给 simple_switch 用,但构建 bmv2 测试目标时必须能找到。
3.4 依赖安装后的统一自检
三个依赖装完后,先用一组命令把版本、路径和库位置对齐。这个步骤看着琐碎,但能避免后面在 bmv2 和 p4c 的日志里反复猜。
export DEPS=/opt/p4deps export PATH="$DEPS/protobuf-3.2.0/bin:$DEPS/thrift-0.9.2/bin:$PATH" export PKG_CONFIG_PATH="$DEPS/protobuf-3.2.0/lib/pkgconfig:$DEPS/thrift-0.9.2/lib/pkgconfig:$PKG_CONFIG_PATH" which protoc protoc --version which thrift thrift -version pkg-config --modversion protobuf逻辑上,先把依赖的bin和pkgconfig放到当前 shell 前面,再查which和版本。参数说明:PATH决定命令解析顺序,PKG_CONFIG_PATH决定 configure 查到的.pc文件。若which protoc仍指向/usr/bin/protoc,说明当前 shell 没有生效或路径顺序不对;不要继续编译 p4c,先把这里修正。
4. bmv2 与 p4c 联调:behavioral-model 编译到 simple_switch 跑通
4.1 behavioral-model 编译:configure 参数与 gmock 路径
behavioral-model 是 bmv2 的源码主体,simple_switch 就从这里编出来。进入源码目录后先跑autogen.sh,再 configure。下面这组参数把安装前缀、gmock、thrift 都固定住,同时用环境变量补头文件和库搜索路径:
export DEPS=/opt/p4deps export CPPFLAGS="-I$DEPS/protobuf-3.2.0/include -I$DEPS/thrift-0.9.2/include -I$DEPS/gmock-1.7.0/include" export LDFLAGS="-L$DEPS/protobuf-3.2.0/lib -L$DEPS/thrift-0.9.2/lib -L$DEPS/gmock-1.7.0/lib" export PKG_CONFIG_PATH="$DEPS/protobuf-3.2.0/lib/pkgconfig:$DEPS/thrift-0.9.2/lib/pkgconfig:$PKG_CONFIG_PATH" cd /path/to/pkg/behavioral-model ./autogen.sh ./configure --prefix="$DEPS/bmv2" \ --with-gmock="$DEPS/gmock-1.7.0" \ --with-thrift make -j"$(nproc)" make install逻辑说明:CPPFLAGS和LDFLAGS是给编译器、链接器的兜底路径,防止 configure 查到了包名却找不到具体库;--with-gmock指向前一步安装的 gmock
本文还有配套的精品资源,点击获取