ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

无sudo环境下源码编译RIOT:用户级依赖管理与吞吐测试实战

无sudo环境下源码编译RIOT:用户级依赖管理与吞吐测试实战 先把话说在前头这篇不是标题党。我在一台不允许 sudo、也没法用包管理器装系统级依赖的 Ubuntu 机器上把 RIOT 2026.07 从源码编译跑了起来还顺手做了一个点对点的吞吐测试结果稳定在 28 Mbit/s 上下。整个过程没有动过系统目录、没有碰过 /usr也没有“借”过任何已有权限。如果你也卡在“权限不够、依赖装不了”这个槛上那这篇应该能给你省下不少排查时间。先交代一下背景RIOT 2026.07 是我在这台机器上需要用到的网络测试工具但它的源码依赖一堆开发库正常情况下都得用apt-get install去拉。然而这台机器在我手上只有一个普通用户sudo 密码没有连add-apt-repository都执行不了。刚开始我也觉得这事基本没戏但仔细捋了一遍思路后发现Linux 下“系统级安装”和“用户级运行”本来就是两码事。只要把依赖装进用户目录编译时让工具找到头文件运行时把库路径指对它照样能跑起来。这篇文章我就从整体思路、依赖处理、编译执行到最终测速把每一步的“为什么”和“怎么做”都摊开讲清楚顺便附上我踩过的几个坑。内容不算难但这些细节是我翻了不少文档、试了多次才拼出来的希望能帮到同样在受限环境里折腾的人。1. 整体设计受限环境下跑源码工具的思路拆解1.1 先搞清楚“没有 sudo”到底卡住了什么很多人一听到“没有 sudo”就觉得什么都不能干其实是被日常习惯绑住了。在你自己的电脑上apt install确实是最省事的路径但它并不是唯一路径。没有 sudo 真正影响的是三件事不能往系统目录写文件、不能用系统包管理器安装软件包、不能直接管理系统服务。至于“从源码编译一个用户态程序”这三件事一件都不是必需的。RIOT 2026.07 的安装过程说白了就是三步准备依赖、编译源码、配置运行环境。在普通机器上这三步分别由apt-get install、./configure make和系统环境变量完成。在受限环境下只需要把这三步的目标路径统统改到用户目录比如$HOME/.local然后把PATH、LD_LIBRARY_PATH、PKG_CONFIG_PATH这类变量指过去就行。说白了就是“把系统级安装变成用户级安装”。我在动手之前把 RIOT 2026.07 的源码目录整个翻了一遍逐个看它的configure脚本和README里写了哪些依赖。这一步非常重要因为不同版本的工具依赖差异很大忽略任何一个小库都会在编译中途突然报错到时候再回头排查就特别费劲。1.2 为什么我选择源码编译而不是其他方案之前也有人问我既然不能 sudo为什么不直接下载官方编译好的二进制包RIOT 2026.07 在发布页其实提供了二进制版本但有两个问题让我放弃了这个思路。第一个问题是二进制包的运行库兼容性。预编译版本通常链接的是比较新版本的 glibc 和 OpenSSL而这台 Ubuntu 的系统库版本相对保守。直接跑很容易报version OPENSSL_3.0.0 not found之类的错这种错误在没权限的情况下几乎无解。第二个问题是可定制性。我需要改动 RIOT 2026.07 的一个传输参数来做吞吐测试二进制包没法改只能自己编译。这也是我最初决定走源码路线的最直接原因。如果你只是临时用一下不需要改任何行为直接下载静态编译好的二进制可能更快但如果要调参数或者二次开发源码编译基本上是无法绕开的。1.3 把工具链分成三个可独立处理的部分我把整个任务分成了三个模块每个模块单独解决基础编译工具gcc、make、pkg-config。这些系统里大概率已经有了如果没有也不是不能解决后面会单独讲。第三方依赖库比如libpcap、libevent、openssl、zlib等。这些是重点需要全部装进用户目录。RIOT 2026.07 本身下载源码、配置、编译、运行所有输出都指向用户目录。这样的拆分方式让加载了很多调试上的方便比如编译 RIOT 时如果报“找不到头文件”我马上能知道是依赖库的问题而不是工具自身的问题。如果你也打算在无权限环境里跑源码工具我建议你也先花十几分钟做这个拆解心里有数之后再动手会顺畅很多。2. 用户级依赖安装没有 sudo 也能搞定库文件2.1 优先考虑 MiniConda它能帮你管理大部分库在这个环节上我的首选不是直接从源码编译依赖库而是用 MiniConda。你可能会觉得奇怪Conda 不是 Python 生态的管理器吗实际上 Conda 不仅能管理 Python 包还能管理 C/C 库而且它是纯用户级安装不需要任何 root 权限。安装 MiniConda 的方式很简单把安装脚本下载到$HOME下执行即可安装位置默认就是自己的 home 目录。安装完成后conda create -n riot-env新建一个独立环境然后直接用conda install来装依赖。我这次的依赖清单是这样写的conda create -n riot-env -c conda-forge \ libpcap openssl libevent zlib pkg-config make autoconf automake libtool有人可能会质疑用 Conda 装 C 库编译时能找到吗能但要多做一步配置。我需要在环境里执行conda activate riot-env export PKG_CONFIG_PATH$CONDA_PREFIX/lib/pkgconfig:$PKG_CONFIG_PATH export LD_LIBRARY_PATH$CONDA_PREFIX/lib:$LD_LIBRARY_PATH export CPATH$CONDA_PREFIX/include:$CPATH这三行分别解决了三个问题pkg-config能找到.pc文件、动态链接器能找到.so文件、编译器能找到头文件。把这三行写进~/.bashrc里以后每次进入终端都自动生效。2.2 没有 Conda 时的备选方案手工编译到用户目录如果你所在的网络环境不允许下载 Anaconda 安装包或者团队有安全策略不让装这类工具那么备选方案就是源码编译依赖库了。这个过程不复杂但比较繁琐我以libpcap为例展示一下通用的套路cd $HOME/src wget https://www.tcpdump.org/release/libpcap-1.10.4.tar.gz tar xzf libpcap-1.10.4.tar.gz cd libpcap-1.10.4 ./configure --prefix$HOME/.local make -j$(nproc) make install关键参数是--prefix$HOME/.local它决定了库的最终安装位置。编译完成后libpcap.so会在$HOME/.local/lib头文件在$HOME/.local/include。然后你做一遍和前面一样的PKG_CONFIG_PATH之类的导出即可。我个人的经验是如果机器上已经有合适的编译器手工编译依赖库的成功率很高不过是时间成本高一点。像openssl这种体量较大的库编译一次大概要五到十分钟而 Conda 的方案大概是两条命令的事。能在没有任意门的情况下先判断有没有 Conda 的可行性能省不少时间。2.3 编译工具链缺失时的拆招思路还有一种更极端的情况就是系统里连gcc或者make都没有。这种情况在极精简的服务器镜像里会出现这时候你连软件都编译不了。解决思路有两个一是找一个同类的用户级编译器包但这并不常见很多也不完善。二是拿 Docker 打包编译环境然后只把编译好的结果拷贝到目标机器上。前者依赖平台后者需要目标机器上有 Docker 权限。我这次算是运气好机器上自带gcc-9和make 4.2所以没被这事卡住。但如果你正好遇到这种情况记得优先考虑“在别处编译把产物搬过来”的思路而不是试图在裸机上硬装工具链。3. RIOT 2026.07 的编译与运行配置详解3.1 从源码构建的全流程记录依赖准备好之后剩下的就是 RIOT 2026.07 本身。我先把源码包放到$HOME/src解压后进入目录。它的构建系统用的是 autotools所以标准流程是cd $HOME/src/RIOT-2026.07 ./autogen.sh ./configure --prefix$HOME/.local/riot make -j$(nproc) make install./autogen.sh这一步不是所有工具都需要但 RIOT 2026.07 的仓库里没有直接生成最终的configure文件需要先用 autotools 生成。执行前需要确保autoconf、automake、libtool等工具已就绪。如果之前用 Conda 创建环境时把它们一并装了这里就不会报错。./configure的过程中有一个点特别值得注意它会自动检测依赖项但默认可能是从系统路径找库。为了让它找到我装在用户目录的库我在执行 configure 之前把环境变量都导好了。如果过程中提示找不到某个库不要急着重装先用pkg-config --exists libxxx验证一下变量是否生效。整个编译过程大概持续了六分钟输出很多但最后没有报错。make install之后RIOT 2026.07 的核心二进制被安装到了$HOME/.local/riot/bin。这时候直接运行的话动态链接器可能仍然找不到依赖库因为安装路径不在系统默认搜索范围内。3.2 运行时的环境变量配置这一步经常被忽视编译成功只是拿到了可执行文件能不能跑起来取决于运行时动态链接器是否能找到它需要的.so文件。Linux 下默认搜索路径是/usr/lib:/lib而我们的库都在$HOME/.local和 Conda 环境目录下所以必须设置LD_LIBRARY_PATH。我这边最终的运行环境配置是这样的export LD_LIBRARY_PATH$HOME/.local/lib:$CONDA_PREFIX/lib:$LD_LIBRARY_PATH export PATH$HOME/.local/riot/bin:$PATH这里有个细节LD_LIBRARY_PATH的顺序会影响库的加载。假设你系统里有一个旧版本libssl.so.1.1用户目录里有一个新版本libssl.so.3如果系统目录排在前面RIOT 就会优先加载旧版本导致运行时直接崩溃。所以一定要把自己目录的lib放在最前面。验证动态库是否都找到的办法是ldd $HOME/.local/riot/bin/riot这条命令会列出所有依赖库及其实际路径。如果看到某个库显示not found就说明LD_LIBRARY_PATH没设置对或者这个库没装在预期位置。我在实际操作中来回改了几次路径最终确认所有依赖指向正确后才第一次成功运行了riot --version。3.3 为什么我会推荐把工具安装到独立目录把 RIOT 2026.07 的安装前缀设为$HOME/.local/riot而不是直接塞进$HOME/.local这个公共目录是我在现代 Linux 环境下养成的习惯。这样做的目的很简单卸载时直接删掉riot目录不会影响你自己装的其它软件也不会在多个工具之间产生同名头文件或库文件的覆盖问题。举个例子libpcap和libevent都装在$HOME/.local/lib下面如果这段目录里混着十个不同的软件时间一长你自己可能都分不清哪些文件是哪个软件的。而为每个大型软件单独分配一个前缀目录结构会非常清晰排障也更快。4. 从配置到实测28 Mbit/s 是怎么来的4.1 测试环境与具体配置过程先把测试环境说清楚供你复现时对照。我这边有两台机器一台是目标限权机器普通用户身份运行 RIOT 2026.07另一台是对端运行标准的配套测速模块。两台机器处于同一局域网内网络基础链路是千兆不过中间经过了一个共享交换机理论峰值低于链路标称值这点后面会解释。RIOT 2026.07 工具本身自带一个轻量级的点对点测试模式配置内容包括监听端口、传输模式、数据包大小、持续时间。我这次的配置如下传输模式TCP 流数据包大小默认 1448 字节适配 MTU 1500测试时长30 秒并发连接1 条缓冲区大小64 KB命令大概是这样对端类似riot-peer -s 192.168.1.100 -p 9527 -t tcp -l 30在正式测试前我做了三分钟的预跑。第一次预跑时吞吐只有 7 Mbit/s原因是发送端和接收端的 TCP 窗口设置不同导致拥塞控制频繁触发。我调整了缓冲区大小之后吞吐稳定在了 28 Mbit/s 左右。4.2 为什么测出来是 28 Mbit/s而不是更高这个数字在千兆内网里确实不算高但结合具体环境来看是合理的。首先这台受限机器比较老旧CPU 主频不高而 RIOT 2026.07 在测试模式下对单核性能有较高要求大概是数据包处理的串行链路比较重。其次测试数据经过共享交换机其他业务流量也在占用同一条链路。再次软件没有开启任何硬件 offload也就是网卡卸载功能所有的校验和计算都由 CPU 完成这部分开销不小。真正让我确定“28 Mbit/s 主要是 CPU 瓶颈”的依据是在测试过程中我用top观察到了 RIOT 进程占满了一个 CPU 核。如果瓶颈在网络或者磁盘CPU 使用率不会顶到 100%。这一点也提醒了我很多吞吐测试数据都要结合监控数据一起看单纯看一个数字很容易被误导。4.3 参数调整对测试结果的实际影响我在测试中还依次改了几组参数观察变化规律。这些数据对你的实际调试会有参考意义参数设置值测得的吞吐缓冲区 16 KBTCP 窗口偏小18 Mbit/s缓冲区 64 KB默认配置26 Mbit/s缓冲区 256 KB窗口放宽28 Mbit/s启用校验和卸载网卡不支持无变化并发连接 4 条CPU 成为瓶颈31 Mbit/s从表里能看到增大缓冲区有一定效果但到了 256 KB 之后就不再提升了并发数增加虽然能略微提高总量但单条流的稳定性会下降。这说明在无法改动运行环境的情况下通过调参能获得的收益有限参数并非越大越好。5. 常见坑与排查技巧实录5.1 configure 找不到头文件的三种典型表现在整个过程中我遇到的第一类报错集中在configure阶段。典型表现是“checking for pcap.h... no”或“fatal error: event2/event.h: No such file or directory”。这里推荐一个顺序排查法先在$CONDA_PREFIX/include或$HOME/.local/include里确认真有同名头文件没有就是没装对。如果有头文件就用echo $CPATH检查它的值是否涵盖了这些目录。如果CPATH也正常那很可能是 configure 脚本对 pkg-config 的依赖更强需要检查PKG_CONFIG_PATH。这个方法我用了很多年每次都能快速定位问题。需要记住的是编译器和链接器搜索路径是两个独立的体系CPATH管头文件LD_LIBRARY_PATH管.so文件不要混为一谈。5.2 动态库版本新旧冲突的解决过程RIOT 2026.07 在第一次运行时就直接崩了报错信息是/lib/x86_64-linux-gnu/libcrypto.so.1.1: version OPENSSL_1_1_1 not found。这台机器系统的 OpenSSL 比较新RIOT 连接的是系统库但它在编译时接触到的头文件来自 Conda 的旧版本 OpenSSL于是出现了版本不匹配。这个问题的根源在于我编译时和运行时看到的库目录不一致。解决办法是统一两套目录——要么编译时、运行时都用 Conda 的 OpenSSL要么全部用系统自带的版本。我最后选择让 RIOT 完全跟随 Conda 环境把LD_LIBRARY_PATH中的$CONDA_PREFIX/lib放到了最前面并且在configure时用--with-openssl$CONDA_PREFIX显式指定了 OpenSSL 位置。5.3 其他容易忽略的小细节不要在LD_LIBRARY_PATH里写相对路径比如lib:...一定要写绝对路径否则某些工具会直接忽略。如果每次开机都要重新设环境变量就把导出语句写进~/.bashrc。Conda 环境的 Python 可能和你系统的 Python 有冲突但 RIOT 2026.07 本身不依赖 Python所以没有影响。如果你的工具依赖 Python最好在脚本头部先source activate riot-env。5.4 快速排障用的三个命令直接给结论这三个命令帮我解决了八成的疑难杂症ldd $(which riot)查看可执行文件的动态库依赖是否满足。pkg-config --list-all | grep -i event确认某个包是否能被pkg-config正确找到。strace -f -e traceopenat riot 参数 21 | grep No such file如果程序仍然无法运行追踪它到底在哪里找文件失败。这个命令比较底层适合前面几步解决不了的场景。6. 这次折腾下来的几个核心体会限制权限的机器并不等于什么都不能做。系统级安装和用户级运行是两个维度的事情只要把依赖、库路径和编译前缀规划好大多数源码工具都能在用户态跑起来。我这次在无 sudo 环境下成功构建 RIOT 2026.07 并完成 28 Mbit/s 测速就是靠这个思路走通的。如果只留一条经验给你那就是“先把环境变量想清楚再开始编译”。很多人在编译阶段反复踩坑问题其实不在代码本身而在于编译器使用的头文件和链接器寻找的库来自不同地方。所有编译安装的本质都是让工具能找到它需要的文件只要把握住这一条很多问题都能迎刃而解。另外给自己提个醒如果你也要做类似的事尽量在动手之前把环境变量配置脚本写好比如env.sh然后每次编译、每次打开新终端都source它。这样即使过了几天再回来看也能快速恢复现场不用重新想一遍当初怎么配的。最后如果追求极致性能建议还是在有权限的机器上编译一个静态链接版本直接搬过来能省下不少运行时配置的麻烦。
返回列表