TBB交叉编译踩坑之旅

文章目录

  • 环境及工具
  • 编译
  • Q&A
    • -m64 参数
    • xxxx.so.x not found
    • ld-linux-aarch64.so.1 not found
    • undefined reference to "__dlsym"
    • Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
  • 测试
    • Qt Demo
      • pro
      • main
    • 目标环境测试
      • 赋予权限
      • 执行
      • Q&A
  • 结束

环境及工具

  • TBB编译环境:Ubuntu18.04
  • TBB版本:oneTBB-2019_U8
  • 交叉编译工具链:gcc-linaro-6.2.1-2016.11-x86_64_aarch64-linux-gnu
  • 测试工程构建环境:Windows7 + 交叉编译工具链 + Qt5.9.3
  • 运行环境:Xilinx Zynq UltraScale+ MPSoC + Ubuntu

编译

交叉编译工具链,请自行下载配置。

在执行以下步骤之前,请先保证以下指令可查看编译链版本,这意味着编译链配置成功:

aarch64-linux-gnu-gcc -v

aarch64-linux-gnu-g++ -v

TBB 给我们提供了 makefile,若是在目标环境下编译,它会根据脚本交互检测环境,再根据环境自动配置编译参数规则等,非常 Reassuring

若是交叉编译,其实也没有想象中的麻烦…

注意:不需要完全看懂 tbb 编译参数及其规则以及如何自动根据环境实现正确的编译,再改写其 makefile,这将是一件费劲且不讨好的事情,特别是对于 makefile初学者 来说。

我们可以通过以下指令实现交叉编译:

make CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++

Q&A

-m64 参数

首先遇到的是 交叉编译工具链 aarch64-linux-gnu-g++ 不存在 -m64 参数

在我的环境下,该部分是在 oneTBB-2019_U8/build/linux.gcc.inc 中,只需做以下修改;当然这和我的环境有关,这里仅供参考:

ifeq (intel64,$(arch))
#    ITT_NOTIFY = -DDO_ITT_NOTIFY
#    CPLUS_FLAGS += -m64 $(RTM_KEY)
    CPLUS_FLAGS += $(RTM_KEY)
#    LIB_LINK_FLAGS += -m64
endif

xxxx.so.x not found

通过 sudo find / -name xxxx.so* 查找,我们发现 xxxx.so 存在于交叉编译工具链中,那么我们 “复制”一份到目标路径在重命名即可。

值得 注意 的是,若直接复制并重命名:

cp xxxxx.so xxxxx.so.x

则在编译过程只又会出现问题 Too many open files

正确的做法应该是建立软链接:

ln -s  xxxxx.so xxxxx.so.x

ld-linux-aarch64.so.1 not found

在交叉编译链中并没有找到 ld-linux-aarch64.so

但它其实是交叉编译工具链中的 ld.so

具体路径在:
gcc-linaro-6.2.1-2016.11-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/libc/lib/ld-2.23.so

同理,建立软链接即可。

随即编译成功~~

TBB交叉编译踩坑之旅_第1张图片
但还是高兴得太早了…

undefined reference to “__dlsym”

编写测试demo的时候发现编译失败,原因是:

undefined reference to "__dlsym"
undefined reference to "__dlopen"

使用 nm -D libtbb.so.2 查看 libtbb.so.2库内容,确实存在 外部定义或未定义的__dlsym 等:

TBB交叉编译踩坑之旅_第2张图片
那么这几个函数定义何在?

在相关的头文件中亦未找到 __dlsym 的定义,仅找到 dlsym 等。

最终还是找不到…于是我去对比可正常使用的 lbbtbb.so.2 ,我发现人家根本没有这玩意!

在这里插入图片描述
那么问题就是出在编译动态库上,难道我要重来了吗?

TBB交叉编译踩坑之旅_第3张图片

Using ‘dlopen’ in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

后来我注意到标题所见的警告,于是我在 linux.gcc.inc 中做以下修改

# PIC_KEY选项加上-ldl
PIC_KEY = -fPIC -ldl
# LIBDL不需要了,注释掉
# LIBDL = -ldl

再次编译后使用 nm -D libtbb.so.2 查看动态库内容

TBB交叉编译踩坑之旅_第4张图片

测试

Qt Demo

环境请参照 大恒智星 Pallas_Qt_mingw32_SDK 开发环境搭建

pro

INCLUDEPATH += xxx\tbb\include
DEPENDPATH += xxx\tbb/lib
LIBS += -Lxxx\tbb/lib \
        -ltbb -ltbbmalloc -ltbbmalloc_proxy -ldl

main

这里使用 parallel_for 验证动态库是否可用,属于一个非常简单的例子。

#include 
#include 
#include 

using namespace tbb;
using namespace std;

int main(int argc, char *argv[])
{
     
    QCoreApplication a(argc, argv);

    tbb::parallel_for(1, 10, [](int i){
     std::cout << i << std::endl; });

    return a.exec();
}

目标环境测试

赋予权限

chmod 777 daheng_tbb_test

执行

./daheng_tbb_test

Q&A

执行时出现以下问题:

error while loading shared libraries: libXXX.so.X: cannot open shared object file: No such file

出现上述问题是原因是,目标环境下找不到我们的 tbb库,我采用的方法是:

  • 将我们的库统一放到某个路径下,例如 /usr/loca/lib

  • 然后修改 ld.so.conf 即执行 vi /etc/ld.so.conf,将我们的路径包含进去

  • 更新,执行 ldconfig

随后再次运行即可:

TBB交叉编译踩坑之旅_第5张图片

结束

终于结束了啊!

TBB交叉编译踩坑之旅_第6张图片

你可能感兴趣的:(嵌入式,Linux,TBB,交叉编译,踩坑)