在编译C++例程时,编译过程通过,链接过程出现问题:
libdnn.so: undefined reference to `bpu_mem_phyaddr',可知出现问题的原因在于libdnn.so中并没有这些函数,常见错误原因如下:
提示链接器找不到
libdnn.so
库中引用的cnn_core_wait_fc_done
函数的定义。以下是一些可能的解决方法:
检查缺少的库: 确保所有必要的库都已包含在链接过程中。可能有库文件缺失或路径配置不正确。
检查依赖: 可以使用
ldd libdnn.so
命令检查libdnn.so
所依赖的库,看看是否有任何库缺失或路径问题。库版本问题: 确保所有使用的库版本都是兼容的,有时候不同版本的库之间可能存在不兼容的问题。
符号问题: 确认是否存在符号命名冲突或被优化器移除。可以尝试使用
nm
工具查看libdnn.so
中是否存在cnn_core_wait_fc_done
符号。检查编译选项: 确保在编译和链接时使用了正确的编译选项。特别是,确保所有相关的路径和库都已正确指定。
如果有访问库源码的权限,检查
cnn_core_wait_fc_done
函数的实现以及它的声明是否正确并匹配。如果问题仍然存在,可能需要进一步检查环境配置或联系相关库的维护者获取支持。
可以使用以下命令查看 libdnn.so
中是否存在 cnn_core_wait_fc_done
符号:
nm -D /data/shuzhengwang/gla_sunrise_x3/horizon_toolchain/horizon_xj3_open_explorer_v2.6.4-py38_20240319/ddk/package/host/host_package/xj3_aarch64/dnn/lib/libdnn.so | grep cnn_core_wait_fc_done
该命令将使用 nm
工具列出 libdnn.so
库中的所有符号,然后通过 grep
过滤出与 cnn_core_wait_fc_done
相关的行。
如果输出中有该符号,那么你会看到它的地址和类型。如果没有输出,则表示该符号不在库中。
终端结果为:U cnn_core_wait_fc_done
符号 U cnn_core_wait_fc_done
中的 U
表示这个符号在 libdnn.so
中是未定义的(Undefined),这意味着该库在链接时期希望找到这个符号的定义,但实际的定义不在 libdnn.so
内。
这通常有以下几种可能的情况:
-
缺少依赖库:
cnn_core_wait_fc_done
函数的实现可能存在于某个未被包含的其他库中。你需要找到这个函数的实现库,并确保它在链接过程中被包含进来。 -
未定义符号的导入: 如果
libdnn.so
本身是一个动态库,且这个符号是从另一个动态库导入的,那么你可能需要在运行时确保导入这个库。 -
版本兼容性问题: 可能是库的版本问题导致符号未定义。例如,某些版本中符号可能不存在或者被更名。
可以尝试以下步骤来解决问题:
-
确认
cnn_core_wait_fc_done
函数所在的库,并在链接时包含这个库。 -
如果你知道函数定义的位置,确认是否有正确的头文件和库版本。
-
如果问题依然存在,联系库的维护者或查阅文档以获取更多信息。
再看报错的第一条:
/data/shuzhengwang/gla_sunrise_x3/env/env_install/gcc_cross/gcc-ubuntu-9.3.0-2020.03-x86_64-aarch64-linux-gnu/bin/../lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: warning: libcnn_intf.so.1, needed by /data/shuzhengwang/gla_sunrise_x3/horizon_toolchain/horizon_xj3_open_explorer_v2.6.4-py38_20240319/ddk/package/host/host_package/xj3_aarch64/dnn/lib/libdnn.so, not found (try using -rpath or -rpath-link)
这条警告信息表明链接器在寻找 libcnn_intf.so.1
库时未能找到该文件。这可能是导致 cnn_core_wait_fc_done
符号未定义的原因,因为该符号的定义可能在这个库中。要解决这个问题,你可以尝试以下方法:
-
确认库文件的存在: 检查你的系统或项目中是否存在
libcnn_intf.so.1
文件。你可以使用以下命令在系统中查找该文件:find / -name "libcnn_intf.so.1"
-
设置库路径: 如果找到该文件,确保链接器知道如何找到它。你可以使用
-L
选项来指定库路径,或使用-rpath
选项设置运行时库路径。例如:gcc -L/path/to/dir -Wl,-rpath=/path/to/dir -o output_file source_file.c -ldnn -lcnn_intf
其中
/path/to/dir
是包含libcnn_intf.so.1
的目录路径。 -
安装缺失的库: 如果没有找到
libcnn_intf.so.1
,你可能需要安装它。查阅项目的文档或联系维护者获取库文件和安装指导。 -
使用 rpath 或 rpath-link: 如果你有多个库路径,使用
-rpath
可以指定运行时库搜索路径,或者使用-rpath-link
为链接器指定链接时的库搜索路径。
确保所有依赖的库都正确链接,以避免在编译或运行时遇到类似的问题。
于是我们按照1的指引,去找一下这个缺失的文件在哪里:向终端输入:find / -name "libcnn_intf.so.1"
结果如下,果然找到了这些文件。
/data/shuzhengwang/gla_sunrise_x3/horizon_toolchain/horizon_xj3_open_explorer_v2.6.4-py38_20240319/ddk/samples/ai_toolchain/horizon_runtime_sample/code/deps_gcc9.3/aarch64/appsdk/appuser/lib/libcnn_intf.so.1 /data/shuzhengwang/gla_sunrise_x3/horizon_toolchain/horizon_xj3_open_explorer_v2.6.4-py38_20240319/ddk/samples/ai_benchmark/code/deps_gcc9.3/aarch64/appsdk/appuser/lib/libcnn_intf.so.1 /data/shuzhengwang/gla_sunrise_x3/horizon_toolchain/horizon_xj3_open_explorer_v2.6.4-py38_20240319/ddk/package/board/hrt_tools/src/deps_gcc9.3/aarch64/appsdk/appuser/lib/libcnn_intf.so.1
到这里就可以直到链接错误的原因了,就是CMakeLists.txt中并未能确保链接器一定能找到libdnn.so所需要的库文件,因为我们是这样写的:
link_directories( ${HOST_PACKAGE_DIR}/dnn/lib)
去检查${HOST_PACKAGE_DIR}/dnn/lib文件夹,发现果然没有libdnn.so需要的几个文件,解决办法是将这些文件一一加进该路径下,如下图所示:
再次cmake,make,结果如下:
成功链接通过,生成可执行文件。