简介:这份PDF文档面向需要在Linux平台编译AFSim仿真工具集的开发者与研究人员,针对AFSim 2.9.0版本在Ubuntu 22.04.4 LTS下的完整编译流程进行记录与整理,适合具备一定命令行操作经验、希望从源码构建AFSim的中高级用户参考。资源包内仅含1个PDF文件,大小约694KB,内容涵盖资源目录说明、编译环境配置、编译目录结构、CMake配置与编译步骤以及运行测试等模块,并详细列出gcc/g++、cmake、Qt等工具版本与硬件配置要求。文档还给出AFSIM_HOME等环境变量的设置方法、第三方库路径组织方式及编译结果验证思路,可帮助读者规避路径错误与权限问题,快速完成从环境准备到测试运行的完整链路。目前已有2553人学习下载,适合需要系统掌握AFSim源码编译与排错方法的读者。
1. 从源码到可执行:AFSim 2.9.0 在 Linux 上到底难在哪
如果你手里已经拿到了 AFSim 2.9.0 的源码包,第一反应大概率是找README或者install.sh,然后发现根本没有一键脚本。这个仿真工具集在 Linux 下的编译流程,本质上是一次手工搭环境、手工配依赖、手工跑 CMake 的过程,官方没有提供开箱即用的二进制包,所有第三方库都要从dependencies目录里自己解压、自己挂路径。这也是为什么很多人在第一步source ~/.bashrc之后就卡住了——环境变量没配对,后面 CMake 连 Qt 都找不到。
这份编译指南的价值在于,它把整个链路拆成了可复现的步骤:从资源目录结构、编译环境版本、环境变量配置,到 CMake GUI 的 source/build 路径填写,再到make -j4和make install的完整流程。适合两类人:一是第一次在 Linux 上编译 AFSim、需要一份能照着走的操作手册的开发者;二是之前编译失败过、想排查到底是依赖缺失还是路径写错的从业者。下面我按实际编译顺序,把每一步的参数含义和容易翻车的地方讲清楚。
2. 编译前的资源盘点与环境确认:别急着敲 cmake
2.1 源码包里的六个目录分别干什么
拿到 AFSim 2.9.0 的源码包之后,先别急着解压到随便一个地方。这份资源的目录结构是有约定的,后面环境变量和 CMake 路径都依赖它。我一般会先花两分钟把目录过一遍,确认没有缺失:
| 目录 | 作用 | 编译时是否必须 |
|---|---|---|
afsim/ | 核心源码目录,包含所有仿真工具集 | 必须 |
demos/ | 官方案例,编译成功后用来验证 | 非必须,但建议保留 |
dependencies/3rd_party/ | 第三方库,如 tiff、sqlite、gdal、osg 等 | 必须 |
dependencies/resources/ | 编译所需资源,含 vtk 等 | 必须 |
dependencies/tools.rar | 编译工具包 | 必须解压 |
dependencies/gcc-g++.rar | C++ 编译环境资源包 | 必须解压 |
tools/ | 辅助工具,包括 python 等 | 非必须 |
training/ | 开发者/用户培训资料 | 非必须 |
这里有一个容易忽略的点:dependencies下面有两个.rar包,tools.rar和gcc-g++.rar,它们不是自动解压的。很多人直接跳到 CMake 步骤,结果编译到一半报找不到编译器或者找不到某个工具,回头才发现这两个包根本没解开。常见做法是先把这两个包解压到当前目录,再继续后面的环境变量配置。
2.2 编译环境版本对齐:gcc 4.8.5 不是随便选的
这份指南给出的编译环境是经过验证的组合,不要随意升级或降级:
- AFSim 版本:2.9.0
- 操作系统:Ubuntu 22.04.4 LTS
- 构建工具:cmake-3.22.1-linux-x86_64,配合 cmake-qt-gui(Qt5.15)
- 编译器:gcc-4.8.5 / g++-4.8.5
- 内存:16G 起步
- CPU:13 代 i7 级别
- GPU:NVIDIA RTX 3060 级别
为什么 gcc 要卡在 4.8.5?因为 AFSim 2.9.0 的源码里有一部分老式 C++ 写法,在高版本 gcc 下会触发更严格的语法检查,直接报错。而dependencies/gcc-g++.rar里预置的就是 4.8.5 的环境包,解压后配合myenv_temp.sh脚本使用,能避免自己装编译器带来的版本冲突。内存 16G 是底线,make -j4并行编译时,osg 和 gdal 这两个库的编译单元非常吃内存,8G 的机器大概率会在链接阶段被 OOM kill 掉,现象是终端突然显示Killed,没有任何编译错误提示,这就是典型的血泪经验。
提示:如果你的机器内存只有 8G,把
make -j4改成make -j2甚至make,用时间换空间,否则编译到 70% 左右被系统杀掉,前面的时间全白费。
2.3 编译目录的路径约定与 root 权限说明
指南里明确写了编译目录是/home/sma/AFSIMSrc/,并且所有命令都在 root 账户下执行。这不是随便定的,因为后面~/.bashrc里的AFSIM_HOME和AFSIM_3RDPARTY_PATH都写死了这个路径。如果你把源码放在别的地方,比如/opt/afsim或者/home/yourname/afsim,那环境变量里的每一行路径都要跟着改,漏改一个就会在 CMake configure 阶段报Could NOT find XXX。
我一般会建议:要么完全按照指南的路径来,要么在开始之前就把所有路径替换成自己的,并且用find确认每个第三方库的lib或lib64目录真实存在。root 账户执行的原因也很简单——make install会往系统目录写文件,普通用户权限不够。但注意,CMake GUI 那一步指南里是su sma切回普通用户执行的,因为 cmake-gui 是图形界面,root 下跑 Qt 界面容易出显示问题。这个细节很多人会忽略,直接用 root 开 cmake-gui,结果界面弹不出来或者报cannot connect to X server。
3. 环境变量与依赖安装:把路径写对就成功了一半
3.1 配置 .bashrc 里的 AFSIM_HOME 和 LD_LIBRARY_PATH
环境变量配置是整个编译流程里最容易出错的一步,因为LD_LIBRARY_PATH那一长串路径,少一个冒号、多一个空格,都会导致后面链接失败。指南里的做法是直接编辑~/.bashrc,在文件末尾追加 export 语句。我一般会先备份一份.bashrc,然后再改:
su root cp ~/.bashrc ~/.bashrc.bak vi ~/.bashrc在文件末尾增加以下内容,注意路径中的冒号是 Linux 下LD_LIBRARY_PATH的分隔符,每个库路径后面跟一个冒号,最后一个路径后面直接接${LD_LIBRARY_PATH},不要再加多余的冒号:
export AFSIM_HOME=/home/sma/AFSIMSrc/afsim export AFSIM_3RDPARTY_PATH=/home/sma/AFSIMSrc/dependencies/3rd_party export LD_LIBRARY_PATH=${AFSIM_3RDPARTY_PATH}/tiff-4.4.0-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/sqlite-3.32.3-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/sdl-2.0.16-x64-lnx/lib64:${AFSIM_3RDPARTY_PATH}/tinyxml2-7.1.0-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/gtest-1.8.0-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/openssl-3.1.1-x64-lnx/lib64:${AFSIM_3RDPARTY_PATH}/curl-8.2.0-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/proj-8.1.1-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/geos-3.5.1-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/gdal-3.3.2-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/zlib-1.2.11-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/libpng-1.6.37-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/ffmpeg-4.2.4-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/libjpeg-turbo-2.1.2-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/osg-3.6.3-x64-lnx/lib64:${AFSIM_3RDPARTY_PATH}/osgEarth-2.10.1-x64-lnx/lib64:${AFSIM_3RDPARTY_PATH}/qt-5.12.11-x64-lnx/lib:${LD_LIBRARY_PATH}这段配置的逻辑是:AFSIM_HOME指向源码根目录,AFSIM_3RDPARTY_PATH指向第三方库根目录,然后LD_LIBRARY_PATH把每个第三方库的运行时链接路径串起来。注意sdl、openssl、osg、osgEarth用的是lib64,其余大部分是lib,这个区别不能搞混。写完之后执行source ~/.bashrc让配置生效,然后用echo $LD_LIBRARY_PATH确认输出里包含所有库路径。
注意:如果你在
vi里粘贴这一长串路径时发生了换行,LD_LIBRARY_PATH会被截断,后面 CMake 配置时就会报找不到某个库。建议粘贴后用cat ~/.bashrc | tail -5检查一下,确认整行是连续的。
3.2 执行 myenv_temp.sh 安装编译环境
环境变量配好之后,进入dependencies目录,给myenv_temp.sh加执行权限并运行:
cd /home/sma/AFSIMSrc/dependencies chmod +x myenv_temp.sh ./myenv_temp.sh这个脚本的作用是把gcc-g++.rar和tools.rar里的内容释放到正确位置,并设置编译时需要的临时环境。脚本执行过程中如果提示某个文件已存在,说明之前解压过,可以选择覆盖或跳过。执行完成后,用which gcc和gcc --version确认当前 gcc 版本是 4.8.5。如果显示的是系统自带的更高版本,说明脚本里的环境变量没有生效,需要检查脚本是否在 root 下执行、以及PATH是否被正确修改。
3.3 CMake GUI 的 source 和 build 路径怎么填
指南里用的是 cmake-gui,而不是命令行 cmake,原因是 AFSim 的 CMake 配置项比较多,GUI 里能看到哪些依赖找到了、哪些没找到,方便排查。操作顺序是:
cd /home/sma/AFSIMSrc/dependencies/3rd_party/qt-5.12.11-x64-lnx/bin chmod +x ./* su sma sudo cmake-gui打开 cmake-gui 后,两个路径这样填:
Where is the source code:/home/sma/AFSIMSrc/afsimWhere to build the binaries:/home/sma/AFSIMSrc/afsim/build
填完之后先点Configure。如果之前编译过,Cache 可能没有自动加载,点击File | Reload Cache手动加载。Configure 过程中终端会输出一堆Found XXX和Could NOT find XXX,重点看有没有Could NOT find后面跟着 Qt、OpenSSL、GDAL 这些关键库。如果有,说明LD_LIBRARY_PATH里对应的路径不对,或者那个库的lib目录下根本没有.so文件。
Configure 无报错后,点击Generate生成 Makefile。成功的话底部会提示Generating done。这一步如果报错,常见原因是 CMake 版本和 Qt 版本不匹配,指南指定的是 cmake-3.22.1 配 Qt5.15,如果你系统里装了别的 Qt 版本,cmake-gui 可能会优先找到系统 Qt 而不是3rd_party里的 Qt 5.12.11,导致 Generate 失败。
4. 编译与安装:make -j4 之后发生了什么
4.1 make -j4 的并行度选择与中断处理
Generate 成功后,回到终端,切到 root,进入 build 目录开始编译:
su root cd /home/sma/AFSIMSrc/afsim/build make -j4-j4表示用 4 个并行任务编译。这个数字不是固定的,一般取 CPU 核心数的一半到全部。13 代 i7 有 14 个核心(6 性能核 + 8 能效核),理论上可以开到-j8甚至-j12,但内存只有 16G 的话,开太高会在链接大型库时爆内存。我一般会先看free -h确认可用内存,如果 available 大于 12G,可以尝试-j6;如果只有 8G 左右,老老实实-j2。
编译过程中终端会滚动输出每个编译单元的进度,从 0% 一直到 100%。如果中途出现Killed,基本就是内存不够,降低并行度重新make即可,已经编译好的.o文件不会丢失,make 会从断点继续。如果出现具体的编译错误,比如error: XXX was not declared,那通常是源码和编译器版本不匹配,需要确认 gcc 是不是 4.8.5。
编译到 100% 后,终端会停在命令行状态,没有任何报错,这时候不要以为已经完事了,还需要执行安装:
make install安装完成后,指南里还有一步创建资源目录:
mkdir -p ${AFSIM_HOME}/build/wsf_install/resources/site/mil-std2525d这个目录是 AFSim 运行时需要的标准资源路径,不创建的话后面跑wizard可能会报找不到资源文件。
4.2 wsf_install 目录结构与 wizard 启动验证
make install成功后,会在/home/sma/AFSIMSrc/afsim/build/下生成一个wsf_install文件夹。这个文件夹就是最终的可运行环境,里面包含bin、lib、resources等子目录。验证编译是否成功,最直接的方式是进入bin目录启动wizard:
cd /home/sma/AFSIMSrc/afsim/build/wsf_install/bin su root ./wizardwizard是 AFSim 的图形化入口工具,能正常弹出界面就说明编译和安装都成功了。如果启动时报error while loading shared libraries: libXXX.so.X: cannot open shared object file,说明LD_LIBRARY_PATH里缺少对应的库路径,或者wsf_install/lib没有加到环境变量里。常见做法是在~/.bashrc里再追加一行:
export LD_LIBRARY_PATH=${AFSIM_HOME}/build/wsf_install/lib:${LD_LIBRARY_PATH}然后source ~/.bashrc再启动。如果wizard能打开但界面显示异常,比如按钮错位、字体乱码,那通常是 Qt 插件路径没配好,可以检查QT_PLUGIN_PATH是否指向了3rd_party/qt-5.12.11-x64-lnx/plugins。
4.3 用 demos 案例做一次端到端验证
wizard能启动只说明主程序链接没问题,要确认整个仿真工具集都能用,最好跑一个demos里的案例。进入demos目录,找一个简单的场景文件(通常是.txt或.af格式),用mission或者wizard加载运行。如果案例能正常加载、仿真能跑起来、输出文件能生成,那整个编译链路就算彻底通了。
这一步的意义在于:wizard只调用了部分库,而demos里的案例会触发 gdal、osg、ffmpeg 等更多第三方库的运行时链接。如果某个库的LD_LIBRARY_PATH没配好,wizard可能不报错,但跑案例时就会崩。我一般会把demos里的第一个案例作为编译成功的最终验收标准,跑通了才认为环境没问题。
5. 避坑与排查:五个让编译前功尽弃的细节
5.1 现象:CMake Configure 报 Could NOT find Qt5
原因:cmake-gui启动时优先搜索了系统 Qt,而不是3rd_party里的 Qt 5.12.11。或者LD_LIBRARY_PATH里 Qt 的lib路径写成了lib64,而实际目录是lib。
解决:在 cmake-gui 里手动指定Qt5_DIR为${AFSIM_3RDPARTY_PATH}/qt-5.12.11-x64-lnx/lib/cmake/Qt5,然后重新 Configure。同时确认~/.bashrc里 Qt 路径是lib不是lib64。
5.2 现象:make 到 70% 左右终端突然显示 Killed
原因:并行编译时内存耗尽,系统 OOM killer 杀掉了编译进程。16G 内存开-j4在链接 osg 时可能不够。
解决:改用make -j2或make单线程重新编译,已编译的.o文件会复用,不会从头开始。如果反复被 Kill,检查是否有其他进程占用大量内存,关掉不必要的程序。
5.3 现象:wizard 启动报 cannot open shared object file
原因:LD_LIBRARY_PATH缺少wsf_install/lib,或者某个第三方库的路径拼写错误。
解决:用ldd ./wizard | grep "not found"查看具体缺哪个库,然后对照~/.bashrc里的路径逐条检查。常见的是libtinyxml2.so和libgtest.so找不到,因为这两个库的路径容易被漏写。
5.4 现象:cmake-gui 在 root 下无法启动图形界面
原因:root 用户没有继承当前桌面的 X server 权限,Qt 界面弹不出来。
解决:按照指南,用su sma切回普通用户再执行sudo cmake-gui。如果普通用户也没有显示权限,检查DISPLAY环境变量是否设置,或者用xhost +临时放开权限。
5.5 现象:make install 后 wsf_install 目录为空或缺少 bin
原因:make install没有在 root 下执行,或者 CMake 配置时CMAKE_INSTALL_PREFIX被改到了别的位置。
解决:确认make install是在 root 下执行的,并且 cmake-gui 里CMAKE_INSTALL_PREFIX的值是${AFSIM_HOME}/build/wsf_install。如果之前改过,重新 Configure 和 Generate 再 make install。
6. 编译完成后的进阶用法:把环境固化成一键脚本
编译成功一次之后,最值钱的东西不是wsf_install目录,而是那套环境变量和操作顺序。我一般会把整个流程固化成一个setup_afsim.sh,放在AFSIM_HOME旁边,下次换机器或者重装系统时直接跑一遍,省去翻指南的时间:
#!/bin/bash # AFSim 2.9.0 环境初始化脚本 # 用法:source setup_afsim.sh export AFSIM_HOME=/home/sma/AFSIMSrc/afsim export AFSIM_3RDPARTY_PATH=/home/sma/AFSIMSrc/dependencies/3rd_party # 第三方库运行时路径 export LD_LIBRARY_PATH=${AFSIM_3RDPARTY_PATH}/tiff-4.4.0-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/sqlite-3.32.3-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/sdl-2.0.16-x64-lnx/lib64:${AFSIM_3RDPARTY_PATH}/tinyxml2-7.1.0-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/gtest-1.8.0-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/openssl-3.1.1-x64-lnx/lib64:${AFSIM_3RDPARTY_PATH}/curl-8.2.0-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/proj-8.1.1-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/geos-3.5.1-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/gdal-3.3.2-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/zlib-1.2.11-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/libpng-1.6.37-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/ffmpeg-4.2.4-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/libjpeg-turbo-2.1.2-x64-lnx/lib:${AFSIM_3RDPARTY_PATH}/osg-3.6.3-x64-lnx/lib64:${AFSIM_3RDPARTY_PATH}/osgEarth-2.10.1-x64-lnx/lib64:${AFSIM_3RDPARTY_PATH}/qt-5.12.11-x64-lnx/lib # 安装后的运行时库 export LD_LIBRARY_PATH=${AFSIM_HOME}/build/wsf_install/lib:${LD_LIBRARY_PATH} # Qt 插件路径 export QT_PLUGIN_PATH=${AFSIM_3RDPARTY_PATH}/qt-5.12.11-x64-lnx/plugins echo "AFSim 2.9.0 环境已加载" echo "AFSIM_HOME=${AFSIM_HOME}" echo "wizard 路径:${AFSIM_HOME}/build/wsf_install/bin/wizard"这个脚本比直接改.bashrc更灵活的地方在于:它不会污染全局环境,只在当前终端会话生效。如果你同时维护多个版本的 AFSim,或者需要在同一台机器上切换不同项目,用source加载对应脚本就行,不会互相干扰。脚本里额外加了QT_PLUGIN_PATH,这是指南里没写但实际运行wizard时经常需要的——Qt 程序启动时会去默认插件路径找平台插件,如果找不到就会报This application failed to start because no Qt platform plugin could be initialized。
验证脚本是否生效,可以跑一个组合命令:
source setup_afsim.sh ldd ${AFSIM_HOME}/build/wsf_install/bin/wizard | grep "not found"如果ldd输出里没有任何not found,说明所有动态库都能找到,wizard可以正常启动。这个检查比直接运行wizard更快,因为它不需要图形界面,在纯命令行环境下也能做。
从那以后我每次编译完 AFSim,都会先跑一遍ldd | grep "not found",确认没有缺失库之后再启动wizard,最后用demos里的案例做端到端验证。这套习惯帮我省掉了很多“以为编译成功了、结果跑案例才崩”的后悔药时间。希望帮到你。
本文还有配套的精品资源,点击获取