本文介紹Ubuntu部署ROS常見編譯報錯的解決方法。對編譯步驟感興趣可以查看上篇文章http://www.asorrir.com/d/6788562.html
文章適用于瑞芯微旗下RK3562、RK3566、RK3568、RK3576、RK3588等Arm64位芯片平臺,各型號觸覺智能均有配套核心板及開發板,實現了百分百全國產。
常見編譯報錯解決方法
編譯主機內存不足
除了增加編譯主機內存配置外,建議將可以開啟交換空間,例如zram:
sudo -i su # modprobe zram # echo 12G > /sys/block/zram0/disksize # echo 6G > /sys/block/zram0/mem_limit # mkswap /dev/zram0 # swapon /dev/zram0 # free -h total used free shared buff/cache available Mem: 14Gi 3.9Gi 5.5Gi 27Mi 5.4Gi 10Gi Swap: 11Gi 2.7Gi 9.3Gi
執行時報`GLIBCXX_3.4.30' not found 錯誤
在主板端執行以上報錯,是因為RK Linux SDK版本較多, 工具鏈版本一直在更新,因此需要使用Linux SDK編譯Rootfs的交叉工具來編譯ROS2。
root@rk3562-buildroot:/opt/ros-foxy# ros2 run demo_nodes_cpp talker /opt/ros-foxy/lib/demo_nodes_cpp/talker: /lib/libstdc++.so.6: version `GLIBCXX_3.4.30' not found (required by /opt/ros-foxy/lib/librclcpp.so) /opt/ros-foxy/lib/demo_nodes_cpp/talker: /lib/libstdc++.so.6: version `GLIBCXX_3.4.30' not found (required by /opt/ros-foxy/lib/libspdlog.so.1)
編譯結果中出現x86_64動態庫
ls /opt/ros/lib/python3.10/site-packages/rclpy/_rclpy_pybind11.cpython-310- x86_64-linux-gnu.so
pybind11在交叉編譯的環境中, 確實是會有一些已知的問題。找到的python是HOST端的可執行文件,因此一系列參數也是根據HOST端生成,如:
PYTHON_MODULE_EXTENSION:INTERNAL=.cpython-310-x86_64-linux-gnu.so
在pybind11/tools/FindPythonLibsNew.cmake較新的代碼中,建議若是Cross Compling,可在外部手動添加python的參數:
1. 修改src/ros2/pybind11_vendor中pybind11升級到v2.10.2。
2. 并在pybind11_verdor/CMakeLists.txt中設置以下2個參數,
指定具體的 PYTHON_MODULE_EXTENSION:
list(APPEND extra_cmake_args "-DPYBIND11_PYTHONLIBS_OVERWRITE=OFF") list(APPEND extra_cmake_args "-DPYTHON_MODULE_EXTENSION=.cpython-310- aarch64-linux-gnu.so")
3. 在cross-compile.mixin中,也聲明:
- "-DPYBIND11_PYTHONLIBS_OVERWRITE=OFF" - "-DPYTHON_MODULE_EXTENSION=.cpython-310-aarch64-linux-gnu.so"
上述修改后, 仍然發現rclpy在編譯時,其CMakeCache.txt文件中得到的
PYTHON_MODULE_EXTENSION仍指向"x86_64",但第二次再編譯時,會被修改成預期的aarch64。有以下原因:
1. 在pybind11/tools/pybind11NewTools.cmake中, 若未設置過
PYBIND11_PYTHON_EXECUTABLE_LAST、或它值被修改了,會直接清空PYTHON_MODULE_EXTENSION。
76 if(NOT ${_Python}_EXECUTABLE STREQUAL PYBIND11_PYTHON_EXECUTABLE_LAST) 77 # Detect changes to the Python version/binary in subsequent CMake runs, and refresh config if needed 78 unset(PYTHON_IS_DEBUG CACHE) 79 unset(PYTHON_MODULE_EXTENSION CACHE) 80 set(PYBIND11_PYTHON_EXECUTABLE_LAST 81 "${${_Python}_EXECUTABLE}" 82 CACHE INTERNAL "Python executable during the last CMake run") 83 endif()
2. 在pybind11 issue #236 也有類似的現象。
3. 修改pybind11解決: 若是PYBIND11_PYTHONLIBS_OVERWRITE="OFF",則不重設上述參數:
commit f7f1f2a927dd785d109833e411325de4c248719f (HEAD -> v2.10.2-fix) Author: cross-build for rk-linux-sdk Date: Fri Sep 22 08:24:58 2023 +0000 Do not override the PYTHON_MODULE_EXTENSION if cross building As suggested in tools/FindPythonLibsNew.cmake, PYBIND11_PYTHONLIBS_OVERWRITE is a flag to indicate that we set python variables manually when cross building. In this case, do not override variables if PYBIND11_PYTHON_EXECUTABLE_LAST changed or is empty. diff --git a/tools/pybind11NewTools.cmake b/tools/pybind11NewTools.cmake index 7d7424a7..91980dad 100644 --- a/tools/pybind11NewTools.cmake +++ b/tools/pybind11NewTools.cmake @@ -73,7 +73,7 @@ if(NOT DEFINED ${_Python}_EXECUTABLE) endif() -if(NOT ${_Python}_EXECUTABLE STREQUAL PYBIND11_PYTHON_EXECUTABLE_LAST) 7.4 google_benchmark工程缺少limits頭文件 編譯foxy時會報如下錯誤, 原因是缺少頭文件: 該修改在ROS2較新版本中已經修復; 補丁包也有包含 7.5 Linux SDK工具鏈中定義_FORTIFY_SOURCE +if(NOT ${_Python}_EXECUTABLE STREQUAL PYBIND11_PYTHON_EXECUTABLE_LAST AND NOT PYBIND11_PYTHONLIBS_OVERWRITE STREQUAL "OFF") # Detect changes to the Python version/binary in subsequent CMake runs, and refresh config if needed unset(PYTHON_IS_DEBUG CACHE) unset(PYTH
google_benchmark工程缺少limits頭文件
編譯foxy時會報如下錯誤:
In file included from /buildroot/build/ros/google_benchmark_vendor/benchmark- 1.5.2-prefix/src/benchmark-1.5.2/src/benchmark_register.cc:15: /buildroot/build/ros/google_benchmark_vendor/benchmark-1.5.2- prefix/src/benchmark-1.5.2/src/benchmark_register.h: In function ‘typename std::vector::iterator benchmark::internal::AddPowers(std::vector*, T, T, int)’: /buildroot/build/ros/google_benchmark_vendor/benchmark-1.5.2- prefix/src/benchmark-1.5.2/src/benchmark_register.h:22:30: error: ‘numeric_limits’ is not a member of ‘std’ 22 | static const T kmax = std::numeric_limits::max(); | ^~~~~~~~~~~~~~
原因是缺少頭文件:
/buildroot/build/ros/google_benchmark_vendor/benchmark-1.5.2- prefix/src/benchmark-1.5.2/src/benchmark_register.h #include
Linux SDK工具鏈中定義_FORTIFY_SOURCE
--- stderr: mimick_vendor Cloning into 'mimick-f171450b5ebaa3d2538c762a059dfc6ab7a01039'... fatal: unable to access 'https://github.com/ros2/Mimick.git/': gnutls_handshake() failed: Error in the pull function. Cloning into 'mimick-f171450b5ebaa3d2538c762a059dfc6ab7a01039'... HEAD is now at f171450 Add armv7l as a 32-bit ARM architecture. (#16) In file included from /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64- buildroot-linux-gnu/sysroot/usr/include/errno.h:25, from /buildroot/build/ros/mimick_vendor/mimickf171450b5ebaa3d2538c762a059dfc6ab7a01039-prefix/src/mimickf171450b5ebaa3d2538c762a059dfc6ab7a01039/include/mimick/mock.h:27, from /buildroot/build/ros/mimick_vendor/mimickf171450b5ebaa3d2538c762a059dfc6ab7a01039-prefix/src/mimickf171450b5ebaa3d2538c762a059dfc6ab7a01039/include/mimick/mimick.h:401, from /buildroot/build/ros/mimick_vendor/mimickf171450b5ebaa3d2538c762a059dfc6ab7a01039-prefix/src/mimickf171450b5ebaa3d2538c762a059dfc6ab7a01039/sample/strdup/test.c:1: 報錯僅在指定了-DCMAKE_TOOLCHAIN_FILE="/opt/aarch64-buildroot-linux-gnu_sdkbuildroot/share/buildroot/toolchainfile.cmake"交叉工具鏈,且該cmake定義了_FORTIFY_SOURCE 可不指定CMAKE_TOOLCHAIN_FILE,或刪除_FORTIFY_SOURCE 7.6 CMake找不到exlibConfig.cmake 編譯ament_cmake_vendor_package報找不到exlib,但實際該exlib庫都被正確指定了。 /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linuxgnu/sysroot/usr/include/features.h:412:4: error: #warning _FORTIFY_SOURCE requires compiling with optimization (-O) [-Werror=cpp] 412 | # warning _FORTIFY_SOURCE requires compiling with optimization (-O) | ^~~~~~~ cc1: all warnings being treated as errors make[5]: *** [sample/strdup/CMakeFiles/strdup_test.dir/build.make:63: sample/strdup/CMakeFiles/strdup_test.dir/test.c.o] Error 1 make[4]: *** [CMakeFiles/Makefile2:302: sample/strdup/CMakeFiles/strdup_test.dir/all] Error 2 make[4]: *** Waiting for unfinished jobs.... In file included from /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64- buildroot-linux-gnu/sysroot/usr/include/errno.h:25, from /buildroot/build/ros/mimick_vendor/mimickf171450b5ebaa3d2538c762a059dfc6ab7a01039-prefix/src/mimickf171450b5ebaa3d2538c762a059dfc6ab7a01039/include/mimick/mock.h:27, from /buildroot/build/ros/mimick_vendor/mimickf171450b5ebaa3d2538c762a059dfc6ab7a01039-prefix/src/mimickf171450b5ebaa3d2538c762a059dfc6ab7a01039/include/mimick/mimick.h:401, from /buildroot/build/ros/mimick_vendor/mimickf171450b5ebaa3d2538c762a059dfc6ab7a01039-prefix/src/mimickf171450b5ebaa3d2538c762a059dfc6ab7a01039/test/test.c:1: /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linuxgnu/sysroot/usr/include/features.h:412:4: error: #warning _FORTIFY_SOURCE requires compiling with optimization (-O) [-Werror=cpp] 412 | # warning _FORTIFY_SOURCE requires compiling with optimization (-O) | ^~~~~~~ cc1: all warnings being treated as errors
報錯僅指定了
-DCMAKE_TOOLCHAIN_FILE="/opt/aarch64-buildroot-linux-gnu_sdkbuildroot/share/buildroot/toolchainfile.cmake"交叉工具鏈,且該cmake定義了_FORTIFY_SOURCE。
可不指定CMAKE_TOOLCHAIN_FILE,或刪除_FORTIFY_SOURCE。
CMake找不到exlibConfig.cmake
編譯ament_cmake_vendor_package報找不到exlib,但實際該exlib庫都被正確指定了。
root@db4be0cd3eca:/buildroot/build/ros/ament_cmake_vendor_package/test# make [ 33%] Built target exlib_bad [ 66%] Built target exlib_good [ 71%] Performing configure step for 'depender' loading initial cache file /buildroot/build/ros/ament_cmake_vendor_package/test/depender-config.cmake CMake Error at CMakeLists.txt:4 (find_package): By not providing "Findexlib.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "exlib", but CMake did not find one. Could not find a package configuration file provided by "exlib" with any of the following names: exlibConfig.cmake exlib-config.cmake Add the installation prefix of "exlib" to CMAKE_PREFIX_PATH or set "exlib_DIR" to a directory containing one of the above files. If "exlib" provides a separate development package or SDK, be sure it has been installed. # strace make 可以看到: [pid 458018] newfstatat(AT_FDCWD, "/opt/aarch64-buildroot-linux-gnu_sdkbuildroot/aarch64-buildroot-linuxgnu/sysroot/buildroot/build/ros/ament_cmake_vendor_package/test/exlib_badprefix/install", 0x7ffca495cf50, 0) = -1 ENOENT (No such file or directory) # : # grep CMAKE_PREFIX_PATH depender-config.cmake set(CMAKE_PREFIX_PATH [= [/buildroot/build/ros/ament_cmake_vendor_package/test/exlib_badprefix/install;/buildroot/build/ros/ament_cmake_vendor_package/test/exlib_goodprefix/install;/buildroot/build/ros/ament_cmake_vendor_package/test/dependerprefix/install]=] CACHE INTERNAL "") 它去找了Toolchain目錄下的sysroot/$CMAKE_PREFIX_PATH,所以找不到。
CMAKE_PREFIX_PATH設置是正確的,有包含exlib庫的路徑。
通過strace make 可以看到工具鏈實際去找的路徑不正確,多加了
/opt/aarch64-buildroot-linuxgnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/
原因: colcon命令中指定了參數
--cmake-args -DCMAKE_TOOLCHAIN_FILE="/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/share/buildroot/toolchainfile.cmake" ,該設置與export環境變量mimix中設置的編譯工具鏈不同導致。
pkg-config找不到
Starting >>> tracetools --- stderr: tracetools CMake Error at /usr/share/cmake- 3.22/Modules/FindPackageHandleStandardArgs.cmake:230(message): Could NOT find PkgConfig (missing: PKG_CONFIG_EXECUTABLE) Reason given by package: The command "/usr/bin/pkg-config" --version failed with output: stderr: /usr/bin/pkg-config: symbol lookup error: /usr/bin/pkg-config: undefined symbol: pkgconf_cross_personality_deinit result: 127 Call Stack (most recent call first): /usr/share/cmake-3.22/Modules/FindPackageHandleStandardArgs.cmake:594 (_FPHSA_FAILURE_MESSAGE) /usr/share/cmake-3.22/Modules/FindPkgConfig.cmake:99 (find_package_handle_standard_args) CMakeLists.txt:35 (find_package)
首先docker中應該有安裝pkgconf(不是pkg-config),cmake中pkg_check_modules()會使用到。
Linux SDK中如果也編譯了pkgconf,也會編譯host-pkgconf,因為與docker的pkgconf版本不同, 在pkgconf.so動態庫搜索時, 找到的是buildroot 編譯的host pkgconf.so,所以失敗。
需要設置PKG_CONFIG_PATH
在編譯src/ros2/ros2_tracing/tracetools/時, 其CMakeLists.txt中指定:
pkg_check_modules(LTTNG REQUIRED lttng-ust)
編譯報錯:
Starting >>> tracetools --- stderr: tracetools CMake Error at /usr/share/cmake-3.22/Modules/FindPkgConfig.cmake:611 (message): A required package was not found Call Stack (most recent call first): /usr/share/cmake-3.22/Modules/FindPkgConfig.cmake:833 (_pkg_check_modules_internal) CMakeLists.txt:36 (pkg_check_modules)
通過strace -f 去抓取log, 發現并未在Linux SDK的sysroot中去查找,因此報錯。
需要設置以下環境變量:
export PKG_CONFIG_PATH=/buildroot/host/aarch64-buildroot-linuxgnu/sysroot/usr/lib/pkgconfig
另一種情況是pkg-config找到了docker中的lttng,而不是target目標的,并報錯如下:
Starting >>> tracetools --- stderr: tracetools /usr/lib/gcc-cross/aarch64-linux-gnu/11/../../../../aarch64-linux-gnu/bin/ld: cannot find -llttng-ust-common: No such file or directory collect2: error: ld returned 1 exit status gmake[2]: *** [CMakeFiles/tracetools.dir/build.make:129: libtracetools.so] Error 1 gmake[1]: *** [CMakeFiles/Makefile2:161: CMakeFiles/tracetools.dir/all] Error 2 gmake[1]: *** Waiting for unfinished jobs.... gmake: *** [Makefile:146: all] Error 2 --- Failed <<< tracetools [4.72s, exited with code 2]
因為找到的是docker的lttng,它的版本與buildroot不同, 前者lttng-ust.pc聲明需要鏈接lttng-ustcommon,但buildroot中缺少lttng-ust-common這個庫。
同樣需要設置環境變量:
export PKG_CONFIG_PATH=/buildroot/host/aarch64-buildroot-linuxgnu/sysroot/usr/lib/pkgconfig
該參數已經在編譯腳本中指定
Docker中可以不安裝lttng包
需要設置CMAKE_INCLUDE_PATH
Starting >>> orocos_kdl_vendor --- stderr: orocos_kdl_vendor Cloning into 'orocos_kdl-507de66'... done. HEAD is now at 507de66 Fix CMake warning on Windows (#392) Submodule 'python_orocos_kdl/pybind11' (https://github.com/pybind/pybind11.git) registered for path 'python_orocos_kdl/pybind11' Cloning into '/buildroot/build/ros/orocos_kdl_vendor/orocos_kdl-507de66- prefix/src/orocos_kdl-507de66/python_orocos_kdl/pybind11'... CMake Error: The following variables are used in this project, but they are set to NOTFOUND. Please set them or make sure they are set and tested correctly in the CMake files: EIGEN3_INCLUDE_DIR (ADVANCED)
因為Linux SDK編譯過程中生成的include文件路徑需要單獨指定, 否則cmake無法搜索得到,如下:
export CMAKE_INCLUDE_PATH='/buildroot/host/aarch64-buildroot-linuxgnu/sysroot/usr/include/'
該參數已經在編譯腳本中指定
unsafe header/library used in cross-compilation --- stderr: action_msgs aarch64-buildroot-linux-gnu-gcc: WARNING: unsafe header/library path used in cross-compilation: '-isystem' '/usr/local/lib/python3.10/distpackages/numpy/core/include' 在交叉編譯過程中, python使用的是host端的/usr/bin/python,當numpy/numpyconfig.h查找不到時, 下列 的獲取include dir無法正確得到目標板子的路徑: # Check if numpy is in the include path find_file(_numpy_h numpy/numpyconfig.h PATHS ${PythonExtra_INCLUDE_DIRS} ) if(APPLE OR WIN32 OR NOT _numpy_h) # add include directory for numpy headers set(_python_code "import numpy" "print(numpy.get_include())" )
明確是由PythonExtra_INCLUDE_DIRS定義查找路徑后, 在pybind11中查找該參數的定義是來自PYTHON_INCLUDE_DIR,因為我們是交叉編譯,可在cross_compile.mimix中預設好該值。該參數已經在編譯腳本中指定,可以指定多個目錄。
END
-
Ubuntu
+關注
關注
5文章
592瀏覽量
31215 -
瑞芯微
+關注
關注
25文章
584瀏覽量
52459 -
ROS
+關注
關注
1文章
288瀏覽量
17738 -
rk3576
+關注
關注
1文章
173瀏覽量
715 -
RK3562
+關注
關注
0文章
80瀏覽量
363
發布評論請先 登錄
ROS讓機器人開發更便捷,基于RK3568J+Debian系統發布!
【米爾RK3576開發板評測】+項目名稱【米爾RK3576開發板評測】一個視頻和你共同認識一下米爾RK3576開發板
米爾RK3576和RK3588怎么選?-看這篇就夠了
米爾瑞芯微RK3576實測輕松搞定三屏八攝像頭
RK3576 vs RK3588:為何越來越多的開發者轉向RK3576?
Mpp支持RK3576么
【米爾RK3576開發板免費體驗】1、開發環境、鏡像燒錄、QT開發環境搭建以及應用部署
【ROS RIKIBOT基礎--使用系列 第一章節】ROS機器人硬件系統 精選資料分享
ROS讓機器人開發更便捷,基于RK3568J+Debian系統發布!
新品體驗 | RK3576開發板

RK3576單板發布倒計時:RK3399與RK3576對比

RK3588與RK3576區別解析

評論