You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MacOS下使用Ada运行时库时缺失libgnat-2020.dylib的问题求助

macOS下Ada动态库移动后无法加载的问题分析与解决

问题现象

用Ada构建FCS Middleware动态库供Flight Control Software主项目调用,库与主项目编译正常,在原目录可正常运行主程序。但将包含可执行文件和动态库的FlightControlSoftware/dist文件夹移动到其他位置(如下载文件夹)后,主程序启动报错:

dyld[15596]: Library not loaded: @rpath/libgnat-2020.dylib
  Referenced from: <9DD7BB9F-4BC0-3F80-9642-36D5228B5867> /Users/robert/Downloads/dist/fcs_software
  Reason: tried: '/Users/robert/Downloads/dist//lib/libgnat-2020.dylib' (no such file), '/Users/robert/Downloads//.obj/libgnat-2020.dylib' (no such file), '/Users/../../..//opt/gnat/2020/lib/gcc/x86_64-apple-darwin17.7.0/8.4.1/adalib/libgnat-2020.dylib' (no such file), '/Users/../../..//opt/gnat/2020/lib/libgnat-2020.dylib' (no such file), '/Users/robert/Downloads/dist//lib/libgnat-2020.dylib' (no such file), '/Users/robert/Downloads//.obj/libgnat-2020.dylib' (no such file), '/Users/../../..//opt/gnat/2020/lib/gcc/x86_64-apple-darwin17.7.0/8.4.1/adalib/libgnat-2020.dylib' (no such file), '/Users/../../..//opt/gnat/2020/lib/libgnat-2020.dylib' (no such file), '/usr/local/lib/libgnat-2020.dylib' (no such file), '/usr/lib/libgnat-2020.dylib' (no such file, not in dyld cache)
zsh: abort      ./fcs_software

项目配置详情

1. 项目结构

.
├── FCS_Middleware
│   ├── dist
│   │   ├── fcsm-math.ads
│   │   ├── fcsm-math.ali
│   │   ├── fcsm.ads
│   │   ├── fcsm.ali
│   │   └── libfcs_middleware.dylib
│   ├── fcs_middleware.gpr
│   └── src
│       ├── fcsm
│       │   ├── fcsm-math.adb
│       │   ├── hidden_package.adb
│       │   └── hidden_package.ads
│       ├── fcsm-math.ads
│       └── fcsm.ads
└── FlightControlSoftware
    ├── dist
    │   ├── fcs_software **executable**
    │   └── lib
    │       ├── fcsm-math.ali
    │       ├── fcsm.ali
    │       └── libfcs_middleware.dylib
    ├── fcs_middleware.gpr
    ├── flight_control_software.gpr
    ├── include
    │   ├── fcsm-math.ads
    │   └── fcsm.ads
    └── src
        └── main.adb

2. FCS_Middleware主项目文件

project FCS_Middleware is

    for Source_Dirs use ("src/**");
    for Object_Dir use ".obj";
    for Library_Dir use "dist";
    for Library_Src_Dir use "dist";
    for Library_Name use "fcs_middleware";
    for Library_Kind use "dynamic";

    for Library_Interface use ("FCSM", "FCSM.Math");

end FCS_Middleware;

3. Flight Control Software项目文件

with "fcs_middleware.gpr";

project Flight_Control_Software is

    for Source_Dirs use ("src/**");
    for Object_Dir use ".obj";
    for Exec_Dir use "dist";
    for Main use ("main.adb");

    package Binder is
        for Switches ("ada") use ("-Es");
    end Binder;

    package Builder is
        for Executable ("main.adb") use "fcs_software";
    end Builder;

end Flight_Control_Software;

4. FlightControlSoftware内的FCS_Middleware项目文件

project FCS_Middleware is
    for Source_Dirs use ("include");
    for Library_Name use "fcs_middleware";
    for Library_Dir use "dist/lib";
    for Library_Kind use "dynamic";
    for Externally_Built use "true";
end FCS_Middleware;

问题原因

这不是macOS的Bug,核心原因是依赖的GNAT运行时库libgnat-2020.dylib的查找路径配置错误:

  • 编译时生成的rpath包含了相对于原编译目录的路径,移动dist文件夹后这些相对路径失效
  • 可执行文件和动态库未配置基于自身位置的相对查找路径,导致dyld无法在新位置定位到libgnat-2020.dylib
  • 报错信息显示,dyld尝试的路径要么是原编译目录的残留相对路径,要么是系统默认路径,均找不到目标库

解决方案

方案一:修改项目配置,配置相对rpath

通过在项目文件中添加链接器参数,设置基于自身位置的rpath,确保移动后能正确查找依赖:

  1. 更新FCS_Middleware.gpr:
project FCS_Middleware is
    for Source_Dirs use ("src/**");
    for Object_Dir use ".obj";
    for Library_Dir use "dist";
    for Library_Src_Dir use "dist";
    for Library_Name use "fcs_middleware";
    for Library_Kind use "dynamic";

    for Library_Interface use ("FCSM", "FCSM.Math");

    -- 添加链接器配置
    package Linker is
        for Switches ("ada") use ("-Wl,-rpath,@loader_path/../lib");
    end Linker;
end FCS_Middleware;
  1. 更新Flight_Control_Software.gpr:
with "fcs_middleware.gpr";

project Flight_Control_Software is
    for Source_Dirs use ("src/**");
    for Object_Dir use ".obj";
    for Exec_Dir use "dist";
    for Main use ("main.adb");

    package Binder is
        for Switches ("ada") use ("-Es");
    end Binder;

    package Builder is
        for Executable ("main.adb") use "fcs_software";
    end Builder;

    -- 添加链接器配置
    package Linker is
        for Switches ("ada") use ("-Wl,-rpath,@loader_path/lib");
    end Linker;
end Flight_Control_Software;
  • @loader_path是macOS dyld的特殊变量,代表当前可执行文件/动态库所在目录
  • 配置后,可执行文件会从自身目录的lib子目录查找动态库,动态库会从上级目录的lib子目录查找依赖

方案二:打包GNAT运行时库并修改依赖路径

将GNAT运行时库复制到dist目录,再修改可执行文件和动态库的依赖路径:

  1. 找到libgnat-2020.dylib的位置,通常在/opt/gnat/2020/lib/下,将其复制到FlightControlSoftware/dist/lib目录
  2. 执行以下命令修改依赖路径:
# 修改可执行文件的libgnat依赖路径
install_name_tool -change @rpath/libgnat-2020.dylib @loader_path/lib/libgnat-2020.dylib ./dist/fcs_software

# 修改动态库的libgnat依赖路径
install_name_tool -change @rpath/libgnat-2020.dylib @loader_path/../lib/libgnat-2020.dylib ./dist/lib/libfcs_middleware.dylib

移动dist目录后,dyld会从dist/lib目录找到所需的运行时库

方案三:静态编译(彻底消除动态依赖)

如果不需要动态库的特性,可改为静态编译,将所有依赖打包进可执行文件:

  1. 修改FCS_Middleware.gpr中的库类型:
for Library_Kind use "static";
  1. 更新Flight_Control_Software.gpr的链接器配置:
package Linker is
    for Switches ("ada") use ("-static");
end Linker;

静态编译后的可执行文件可在任意位置直接运行,无需依赖外部动态库


内容的提问来源于stack exchange,提问作者Robert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 04:45:56