lld 在交叉编译情况下无法打开/lib/x86_64-linux-gnu/libm.so.6

问题描述 投票:0回答:1

我正在使用 Clang++ 进行从

x86_64-pc-windows-msvc
x86_64-pc-linux-gnu
的交叉编译。

演示程序只是一个 C++ Hello World 程序,使用

iostream

为了在我的 Windows 主机上提供 Linux 环境,我将环境(头文件、.a、.so、...)从 WSL2 复制到主机。

你可以看到我在Powershell中使用的命令和输出,我的lld链接器无法打开这个

libm.so.6
动态库。

C:/wsl2/
是我创建的用于存储从wsl2手动复制的Linux环境的文件夹。

PS C:\Users\xxx\Desktop\cmake_demo\simple> clang++ --target=x86_64-pc-linux-gnu --sysroot="C:/wsl2" -o main ./main.cpp -fuse-ld=lld -LC:/wsl2/usr/lib/x86_64-linux-gnu

ld.lld: error: cannot open /lib/x86_64-linux-gnu/libm.so.6: no such file or directory
clang++: error: linker command failed with exit code 1 (use -v to see invocation)

我遇到了

libc_nonshared.a
的“类似”问题,当时,我将相关
.a
文件从 wsl2 复制到主机 Linux 环境并且它有效。

不幸的是,这次这个方法不起作用,我尝试将

libm.so.6
复制到
C:/wsl2
文件夹。您可以看到它们不是符号链接,因为它们的
Length
不是
0

PS C:\wsl2\usr\lib> ls C:\wsl2\usr\aarch64-linux-gnu\lib | findstr libm
-a----         2/23/2022  12:26 PM        1445378 libm.a
-a----         2/23/2022  12:26 PM         551064 libm.so
-a----         4/16/2024   3:40 PM         940560 libm.so.6
    Directory: C:\wsl2\usr\aarch64-linux-gnu\lib
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         4/16/2024   3:40 PM         940560 libm.so.6
    Directory: C:\wsl2\usr\lib
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         4/16/2024   3:40 PM         940560 libm.so.6
    Directory: C:\wsl2\usr\lib\x86_64-linux-gnu
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         4/16/2024   3:40 PM         940560 libm.so.6
    Directory: C:\wsl2\usr\lib64\x86_64-linux-gnu
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         4/16/2024   3:40 PM         940560 libm.so.6

我猜这是因为Windows平台上缺少动态链接器。 (

.a
是静态库,但
.so
似乎是动态库)在Clang++中添加
-v
选项后,下面列出了更多详细信息的输出:

...
 C:/wsl2/usr/include/x86_64-linux-gnu
 C:/wsl2/usr/include
End of search list.
 "C:\\Program Files\\LLVM\\bin\\ld.lld" --sysroot=C:/wsl2 --eh-frame-hdr -m elf_x86_64 
        -dynamic-linker /lib64/ld-linux-x86-64.so.2 
        -o main "C:/wsl2/usr/lib/gcc/x86_64-linux-gnu/11/../../..\\crt1.o" 
                "C:/wsl2/usr/lib/gcc/x86_64-linux-gnu/11/../../..\\crti.o" 
                "C:/wsl2/usr/lib/gcc/x86_64-linux-gnu/11\\crtbegin.o" 
        -LC:/wsl2/usr/lib/x86_64-linux-gnu 
        -LC:/wsl2/usr/lib/gcc/x86_64-linux-gnu/11 
        -LC:/wsl2/usr/lib/gcc/x86_64-linux-gnu/11/../../../../lib64 
        -LC:/wsl2/usr/lib/../lib64 
        -LC:/wsl2/usr/lib/x86_64-linux-gnu/../../lib64 
        -LC:/wsl2/usr/lib/gcc/x86_64-linux-gnu/11/../../.. 
        -LC:/wsl2/usr/lib "C:\\Users\\hzhang3\\AppData\\Local\\Temp\\main-61818f.o" 
        -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc "C:/wsl2/usr/lib/gcc/x86_64-linux-gnu/11\\crtend.o" "C:/wsl2/usr/lib/gcc/x86_64-linux-gnu/11/../../..\\crtn.o"
ld.lld: error: cannot open /lib/x86_64-linux-gnu/libm.so.6: no such file or directory
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
...

我注意到

/lib64/ld-linux-x86-64.so.2
被分配给
ld.lld
作为动态链接器,这是一个 Unix 动态链接器。

ld.lld
尝试在我的Windows主机上查找但找不到
/lib/x86_64-linux-gnu/libm.so.6
这个类似Unix的东西,这并不奇怪。

我有几个问题要在这里讨论:

  1. 用 clang++ 从 Windows 交叉编译到 Linux 真的很蠢吗?

  2. 在这种情况下应该使用哪个动态链接器?因为在 Windows 主机上使用 Linux 动态链接器似乎是不可能的。 (路径不正确且动态链接器不存在)

  3. 我如何破解

    lld
    并让它绕过这个奇怪的动态链接器,以便它可以在特定路径(放置
    libm.so.6
    的位置)上找到它需要的东西?

  4. 从Windows到Linux x64进行交叉编译时,推荐使用哪种Linux环境?我尝试了 Cygwin,但无法通过其安装应用程序安装某些库。看起来 Cygwin 是一个用于构建本机 Windows 应用程序的环境(也称为从 Linux 到 Windows)。

windows linker clang shared-libraries cross-compiling
1个回答
0
投票

libm.so
替换为
libm.so.6
即可解决此问题。

虽然链接器说找不到

libm.so.6
,但它寻找的真正文件是
libm.so

顺便说一句,使用 Ubuntu docker 镜像有助于简化库结构,并避免在安装 Linux 环境时弄乱无用的文件,例如驱动程序。

这就是我的做法,不使用重型 wsl2。

© www.soinside.com 2019 - 2024. All rights reserved.