为啥 Rust 无法在 Windows 上链接?

     2023-02-22     87

关键词:

【中文标题】为啥 Rust 无法在 Windows 上链接?【英文标题】:Why does Rust fail to link on Windows?为什么 Rust 无法在 Windows 上链接? 【发布时间】:2014-10-22 05:35:28 【问题描述】:

我在我的机器上下载并安装了 Rust 和 Cargo nightlies,并使用 Cargo 生成了一个新的二进制项目:

Cifram@Valyria ~
$ cargo new test --bin

然后我尝试运行这个原始项目,再次使用全新的、未损坏的 Rust 和 Cargo 安装,并得到这个:

Cifram@Valyria ~/test
$ cargo run --verbose
   Compiling test v0.0.1 (file:///C:/cygwin64/home/Cifram/test)
     Running `rustc C:\cygwin64\home\Cifram\test\src\main.rs --crate-name test --crate-type bin -g --out-dir C:\cygwin64\home\Cifram\test\target --dep-info C:\cygwin64\home\Cifram\test\target\.fingerprint\test-51757ad0485ed143\dep-bin-test -L C:\cygwin64\home\Cifram\test\target -L C:\cygwin64\home\Cifram\test\target\deps`
error: linking with `gcc` failed: exit code: 1
note: gcc '-m64' '-L' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib' '-o' 'C:\cygwin64\home\Cifram\test\target\test.exe' 'C:\cygwin64\home\Cifram\test\target\test.o' '-Wl,--whole-archive' '-lmorestack' '-Wl,--no-whole-archive' '-fno-lto' '-fno-use-linker-plugin' '-Wl,--gc-sections' '-static-libgcc' '-Wl,--enable-long-section-names' '-Wl,--nxcompat' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libnative-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libstd-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libsync-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\librustrt-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libcollections-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\liballoc-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libunicode-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\liblibc-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\librand-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libcore-4e7c5e5c.rlib' '-L' 'C:\cygwin64\home\Cifram\test\target' '-L' 'C:\cygwin64\home\Cifram\test\target\deps' '-L' 'C:\cygwin64\home\Cifram\test\.rust' '-L' 'C:\cygwin64\home\Cifram\test' '-Wl,--whole-archive' '-Wl,-Bstatic' '-Wl,--no-whole-archive' '-Wl,-Bdynamic' '-lws2_32' '-lcompiler-rt'
note: C:\cygwin64\home\Cifram\test\target\test.o: file not recognized: File format not recognized
collect2.exe: error: ld returned 1 exit status

error: aborting due to previous error
Could not compile `test`.

Caused by:
  Process didn't exit successfully: `rustc C:\cygwin64\home\Cifram\test\src\main.rs --crate-name test --crate-type bin -g --out-dir C:\cygwin64\home\Cifram\test\target --dep-info C:\cygwin64\home\Cifram\test\target\.fingerprint\test-51757ad0485ed143\dep-bin-test -L C:\cygwin64\home\Cifram\test\target -L C:\cygwin64\home\Cifram\test\target\deps` (status=101)

我不确定为什么 rustc 调用 gcc,因为我知道它是建立在 LLVM 之上的。我确实通过 MinGW 安装了 gcc,所以我的第一个想法是 gcc 安装可能会干扰。

Cifram@Valyria ~
$ gcc -v
Using built-in specs.
COLLECT_GCC=C:\MinGW\bin\gcc.exe
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/4.8.1/lto-wrapper.exe
Target: mingw32
Configured with: ../gcc-4.8.1/configure --prefix=/mingw --host=mingw32 --build=mingw32 --without-pic --enable-shared --enable-static --with-gnu-ld --enable-lto --enable-libssp --disable-multilib --enable-languages=c,c++,fortran,objc,obj-c++,ada --disable-sjlj-exceptions --with-dwarf2 --disable-win32-registry --enable-libstdcxx-debug --enable-version-specific-runtime-libs --with-gmp=/usr/src/pkg/gmp-5.1.2-1-mingw32-src/bld --with-mpc=/usr/src/pkg/mpc-1.0.1-1-mingw32-src/bld --with-mpfr= --with-system-zlib --with-gnu-as --enable-decimal-float=yes --enable-libgomp --enable-threads --with-libiconv-prefix=/mingw32 --with-libintl-prefix=/mingw --disable-bootstrap LDFLAGS=-s CFLAGS=-D_USE_32BIT_TIME_T
Thread model: win32
gcc version 4.8.1 (GCC)

所以它是 gcc 的最新版本。但是,这可能不是 rustc 所期望的。所以我从路径中删除了 C:\MinGW\bin 并再次尝试,得到:

Cifram@Valyria ~/test
$ cargo run --verbose
   Compiling test v0.0.1 (file:///C:/cygwin64/home/Cifram/test)
     Running `rustc C:\cygwin64\home\Cifram\test\src\main.rs --crate-name test --crate-type bin -g --out-dir C:\cygwin64\home\Cifram\test\target --dep-info C:\cygwin64\home\Cifram\test\target\.fingerprint\test-51757ad0485ed143\dep-bin-test -L C:\cygwin64\home\Cifram\test\target -L C:\cygwin64\home\Cifram\test\target\deps`
error: linking with `gcc` failed: exit code: 1
note: gcc '-m64' '-L' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib' '-o' 'C:\cygwin64\home\Cifram\test\target\test.exe' 'C:\cygwin64\home\Cifram\test\target\test.o' '-Wl,--whole-archive' '-lmorestack' '-Wl,--no-whole-archive' '-fno-lto' '-fno-use-linker-plugin' '-Wl,--gc-sections' '-static-libgcc' '-Wl,--enable-long-section-names' '-Wl,--nxcompat' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libnative-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libstd-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\librand-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libsync-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\librustrt-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libcollections-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\liballoc-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\liblibc-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libunicode-4e7c5e5c.rlib' 'C:\Program Files (x86)\Rust\bin\rustlib\x86_64-w64-mingw32\lib\libcore-4e7c5e5c.rlib' '-L' 'C:\cygwin64\home\Cifram\test\target' '-L' 'C:\cygwin64\home\Cifram\test\target\deps' '-L' 'C:\cygwin64\home\Cifram\test\.rust' '-L' 'C:\cygwin64\home\Cifram\test' '-Wl,--whole-archive' '-Wl,-Bstatic' '-Wl,--no-whole-archive' '-Wl,-Bdynamic' '-lws2_32' '-lcompiler-rt'
note: ld: this linker was not configured to use sysroots

error: aborting due to previous error
Could not compile `test`.

Caused by:
  Process didn't exit successfully: `rustc C:\cygwin64\home\Cifram\test\src\main.rs --crate-name test --crate-type bin -g --out-dir C:\cygwin64\home\Cifram\test\target --dep-info C:\cygwin64\home\Cifram\test\target\.fingerprint\test-51757ad0485ed143\dep-bin-test -L C:\cygwin64\home\Cifram\test\target -L C:\cygwin64\home\Cifram\test\target\deps` (status=101)

嗯,这是一个稍微不同的错误,但并没有更好。相同的 gcc 命令失败,但是,在错误之前是:

C:\cygwin64\home\Cifram\test\target\test.o: file not recognized: File format not recognized

现在是:

ld: this linker was not configured to use sysroots

我觉得这些都不是很有意义。我尝试直接运行“rustc main.rs”。得到了同样的错误(除了它是“src\main.o”而不是“target\test.o”)。尝试从本机 Windows 命令行而不是 cygwin 执行所有这些操作。同样的错误。因此,应该归咎于 Cargo 或 cygwin 似乎不是。我还尝试下载 Rust 的最后一个“稳定”版本(0.12.0),但仍然遇到相同的错误。我用谷歌搜索了这些错误,结果一无所获。所以我的想法不多了。

帮助?

【问题讨论】:

根据Rust's wiki,您应该从 PATH 中删除 MinGW 以使用与 Rust 捆绑的 gcc。在 0.12 之前的版本中,需要单独安装 MinGW。我认为您的第一个错误是由于使用了针对 x86-64 的 Rust 编译器和针对 i386 的链接器。至于你的第二个错误,我不知道。 啊,谢谢你的链接!这至少解决了一部分难题。虽然在使用 Rust 时我不能在我的路径中使用 gcc 真的很不方便。它使编译我想在 Rust(例如 SDL2)中链接到的任何 C 库的过程变得非常麻烦。 【参考方案1】:

成功!事实证明,问题在于我在 cygwin 中也安装了 ld。所以据我所知,它使用的是作为 rustc 的一部分提供的 gcc 版本,但 gcc 调用的是 C:\cygwin64\bin\ld.exe,而不是它自己的内部 ld。

我删除 ld 后,一切正常。

请注意,这强化了我在评论中提出的观点:显然我不能同时在同一台机器上进行 Rust 开发和 C/C++ 开发。即使是为了编译我想在 Rust 中访问的 C 库,比如 SDL2 或 GLFW。这非常不方便。如果 rustc 需要特定版本的 gcc 和 ld,并附带正确的版本,它不应该默认调用系统版本。如果需要可以覆盖它的 gcc 或 ld 版本,这应该通过显式命令行选项来完成。

编辑:添加一个不经意间颠倒句子含义的“不”。

【讨论】:

"它应该默认调用系统版本" => 事实是,Windows 上没有 GCC 的“系统版本”之类的东西。有各种竞争版本(MinGW、MinGW-w64、Cygwin)。您当然可以将同一台机器用于 Rust 和 C/C++ 开发,但您可能需要制作一些批处理文件来为每个文件正确设置环境变量(如果您使用命令解释器/shell 来调用编译器)。 对不起,我在那句话中漏掉了一个“不”。固定。【参考方案2】:

作为替代解决方案,我在 cygwin shell 环境中调用 Rust 时操纵了路径变量。我理解的方式是,Rust 会使用系统路径,搜索 gcc,然后尝试使用它。通过操纵路径来删除不需要的 GCC,它将回退,并使用 rust 安装程序附带的那个。

PATH='/c/Program Files/Rust/bin' 货物构建

*使用安装 Rust 的正确 cygwin 路径。在我的系统上,这是 /c/Program...

【讨论】:

不错的主意。在 Rust 中被 gcc 版本奴役是很不幸的,但是每次我想在 Rust 和 C/C++ 开发之间切换时都必须重新调整我的路径。

如何在 Windows 上链接和编译 Raylib?

】如何在Windows上链接和编译Raylib?【英文标题】:HowdoIlinkandcompileRaylibonwindows?【发布时间】:2021-11-0611:40:25【问题描述】:我已经从官方来源安装了raylibmigw。安装目录为C:\\raylib\\raylib。我从网站上编写了示例程序,如下所示。#... 查看详情

C++ Singleton 无法在 Mac OS 上链接

】C++Singleton无法在MacOS上链接【英文标题】:C++SingletonfailtolinkonMacOS【发布时间】:2012-08-2403:11:29【问题描述】:我正在尝试使用Xcode在C++、MacOS上创建一个非常经典的单例我创建类MySingleton如下:classMySingletonprivate:intval;staticMySingl... 查看详情

无法在 Mac OS X 上链接静态库

】无法在MacOSX上链接静态库【英文标题】:Can\'tlinkstaticlibraryonMacOSX【发布时间】:2018-05-0508:48:28【问题描述】:我无法将静态库链接到MacOSX上的可执行文件。我的仓库目录中有lib女巫包含所有库,例如libstdc++.a、libssl.a、libz.a。C... 查看详情

使用 CMake 在 Mac 上链接静态 GLFW 和 OpenGL

...06-0704:22:58【问题描述】:我正在尝试在mac上测试glfw3。我无法构建一个简单的项目,因为我无法链接到OpenGL。目录结构├──CMakeLists.txt├──OpenGL│  ├──Application.cpp│  ├──CMakeList 查看详情

GCC - 在 Ubuntu 上链接 bass.lib

...时间】:2011-09-0210:35:42【问题描述】:我使用CPP和BASS在Windows上编写了一个应用程序,现在我必须让它在Linux(UBUNTU)上运行。Iamusinggccversion4.5.2.我的目录中有bass.lib,我尝试使用以下命令参数编译prog.cpp:gccprog.cpp-L.- 查看详情

在 Sql Server 2008 上链接 MySQL 服务器

...程序中,我必须在部署在Linux机器上的MySqlServer和部署在Windows机器上的SQLServer之间传输数据,这是两种方式。我们计划通过在SQLServer上创建MySql作为链接服务器来实现。我创建了一个指向Linu 查看详情

在 textview 上链接,文本中的域不起作用,链接不可点击

...:2018-10-2420:10:36【问题描述】:当字符串表示域名时,我无法linkfy带有href的字符串。所以字符串。让我告诉你。这是字符串:<stringname="go_to_settings">Pleaseg 查看详情

更改 iOS/ipad 上链接的 URL(应用内)

...:我正在编辑嵌入在ipad应用程序中的web视图。它包含我无法用标签包装的各种多媒体元素。因此,我在页面上有一个元素,并根据用户的操作动态更改href,然后强制点击发生。这实际上很好用,但动态特性却不行。两者都可以... 查看详情

何时在 Xcode 上链接框架/库?

】何时在Xcode上链接框架/库?【英文标题】:Whentolinkframeworks/librariesonXcode?【发布时间】:2019-11-2209:55:25【问题描述】:正如标题所说,我们什么时候需要在Xcode上手动添加框架/库?当我说手动是通过AppTarget->General->LinkedFrame... 查看详情

在某些列表上链接函数调用

】在某些列表上链接函数调用【英文标题】:Chainingfunctionscallsonsomelist【发布时间】:2021-10-2417:23:22【问题描述】:假设我有三个函数,它需要一个接一个地处理一个列表。deff1(lst):lst_processed=do_something_of_type1(lst)returnlst_processeddef... 查看详情

在这种情况下如何在 Eclipse 上链接库?

】在这种情况下如何在Eclipse上链接库?【英文标题】:Howtolinklibrariesoneclipseinthissituation?【发布时间】:2012-10-0512:31:54【问题描述】:我有一个c++项目,可以用cmake很好的编译。但是我去eclipse的时候,出现了一些问题。DescriptionRe... 查看详情

在 Linux 上链接 c++ 库

】在Linux上链接c++库【英文标题】:linkingc++librariesonLinux【发布时间】:2015-01-1013:18:00【问题描述】:我正在运行以下命令:g++-m32testLogin.cpp-L/root/c++/libs-ldvrnetsdk-otestLoginO-lpthread-lasound结果:/root/c++/libs/libdvrnetsdk.so:undefinedreferenceto` 查看详情

在 OSX 上链接 OpenGL 框架

】在OSX上链接OpenGL框架【英文标题】:LinkingOpenGLframeworkonOSX【发布时间】:2015-06-1608:10:54【问题描述】:我有一个运行Yosemite并支持OpenGL4.x的mac,但是每当我使用“-lSDL2-frameworkOpenGL”标志编译c++项目时,它会自动使用安装在/Syste... 查看详情

如何在 macOS 上链接 libc++?

】如何在macOS上链接libc++?【英文标题】:HowcanIlinklibc++onmacOS?【发布时间】:2021-06-1018:45:03【问题描述】:我正在尝试在macOS11.2(x86-64)上学习C++,但在编译和链接我的代码时遇到了问题。下面列出了我的简单程序。#include<algorit... 查看详情

在 Angular 上链接异步任务

】在Angular上链接异步任务【英文标题】:ChainingasynctasksonAngular【发布时间】:2014-08-0610:56:43【问题描述】:目标我正在做的是链接各种异步任务,这些任务依赖于先前任务的响应,以最终获得一个对象数组,这些对象包含要在$s... 查看详情

在 WhatsApp 短信上链接地理位置

】在WhatsApp短信上链接地理位置【英文标题】:LinkinggeolocationonWhatsApptextmessages【发布时间】:2018-12-1821:02:43【问题描述】:我正在寻找一种通过WhatsApp中的消息以超文本或某种方式发送地理位置(纬度和经度)的方法。我尝试过... 查看详情

可以让 Prettier 允许在新行上链接函数吗?

】可以让Prettier允许在新行上链接函数吗?【英文标题】:PossibletomakePrettierallowchainingfunctionsonnewlines?【发布时间】:2019-05-2208:23:09【问题描述】:我正在编写一些Firebase函数。开箱即用,它带有带有eslint-plugin-promise的EsLint(这很... 查看详情

如何在 Matlab 极轴上链接数据图像?

】如何在Matlab极轴上链接数据图像?【英文标题】:HowtolinkdataimagesonMatlabpolaraxes?【发布时间】:2016-10-1723:04:30【问题描述】:我正在尝试在极轴上使用linkdata图像,这在plot/area/...中很好地描述为linkdata文档here中的笛卡尔。第一... 查看详情