Code change:
Linking may fail when an incompatible installation of MinGW is on the PATH, because rustc ends up running external linker instead of the bundled one. I keep seeing people running into this problem when using WIndows installer. The solution it to run rustc in a console with stripped-down PATH, but this workaround is very nonobvious. I am afraid this will negatively affect perception of quality of our Windows distribution because many early adopters will have some version of mingw already installed on their machines. I think the earlier decision to make rustc prefer bundled binaries () was the correct one. We should un-revert , and fix cargo build instead.
cc , , rust-lang/cargo
Regarding cargo, I think we can take one of the following approaches: Use the snapshot compiler. Specify linker path explicitly via . Delete/rename directory after installing. Add a new command line flag to rustc for controlling this behavior. Perhaps something like ? cc
Issues like are definitely quite worrying, but I would see this as more than just a problem with Cargo but also extending to any project relying on libs installed on windows by some compiler toolchain. The bundled gcc doesn't know anything about system lookup paths, and I see this as akin to saying we should run gcc on unix with no default lookup paths (which would likely be disastrous). I suspect that there are other projects which rely on libs coming from a MinGW, and this seems similar to relying on randomly installed libraries on unix systems, so I'm not sure if it's necessarily a bad thing. Do we know why the error in is occurring? It looks like there's an incompatibility with the MinGW installation, but do we know precisely what it is? I was under the impression that linkers were intended to interoperate well...
I don't really want gcc to be able to find arbitrary mingw libraries because I don't want Rust users on Windows to depend on mingw (imagine cargo packages that expect mingw libs but only a fraction of windows users actually have it installed). I've misunderstood the implications of this issue before, but my inclination is to do the revert and make the cargo build do the extra work to get at the libs it needs.
Nominating since this issue gets hit pretty often and is the last major usability problem on windows.
Not quite: mingw gcc has a default library search path built-it, and it is expressed relative to the installation point. So the one we bundle is going to look for libraries only under (unless we supply more via , of course). This is mostly about library compatibility, not about linker. GCC may emit references to library symbols, that may not exist/be buggy in older versions of mingw. This particular one probably happened because the developer had installed mingw with sjlj exception handling, which defines UnwindSjLjResume instead of UnwindResume.
Assigning P-high, 1.0.
Not being able to access the full set of mingw libs means that people can't link to random GNU libs (which I'm in favor of). I'm unclear on whether it also prevents people from linking to various windows system libraries (I have this vague idea that mingw includes artifacts that make the linker able to link to e.g. ). Is there any concern there?
gcc needs to recognize system library (), so picks up . We ship , but we don't ship or so , rust-lang/cargo, and occurs. So, what's the role of bundle? I thought bundle is for providing "minimal" linking environment so that beginners can build hello-world without installing mingw-w64. In this scenario, if user want to do more than bundle can provide (e.g. gdi32), user must install mingw-w64. At least, this is current status. Maybe we can bundle ? is 72M.
Preferring bundle means: if user has old mingw, will not use it. This solves lots of of beginners' issues. , if user really wants to use their own linker, user need to do something. This complicates build story. So my suggestion is 1) prefer bundle and 2) add a flag to not use bundle at all (rather than changing preference). Maybe or ?
on the other hand, there are a few libs that need to be matched to the version of gcc that Rust was built with. It's mostly stuff like and ; possibly also ,. So simply deferring to external linker probably isn't a good idea, unless we ensure that our bundled libs are being found first. I kinda like the idea of shipping the minimal set of import libraries that is sufficient for linking Rust's standard library. We could add a few more common ones like , but everything is a bit much, IMHO. For reference, here's the list of import libraries that D ships with: , , , , , ,, ,, , , , , , , , . Btw, mingw can also link to dlls directly, so in many cases adding to the command line is enough.
ld can also link to dlls directly? Is it possible to #link directly in them in source? #[link(path = "%systemroot%system32")] or something like that?
That D ships a set of system import libraries is encouraging. Though if mingw can link to dlls directly it's not clear why this is such a problem - if we were to just have rustc add the system32 path by default would this problem with windows import libraries go away completely?

Related discussion:
text: else: rustc_dlls.append("libgcc_s_seh-1.dll") <del> target_libs = ["crtbegin.o", "crtend.o", "crt2.o", "dllcrt2.o", "libadvapi32.a", "libcrypt32.a", "libgcc.a", "libgcc_eh.a", "libgcc_s.a", "libimagehlp.a", "libiphlpapi.a", "libkernel32.a", "libm.a", "libmingw32.a", "libmingwex.a", "libmsvcrt.a", "libpsapi.a", "libshell32.a", "libstdc++.a", "libuser32.a", "libws2_32.a", "libiconv.a", "libmoldname.a"] </del> <ins> target_libs = [ # MinGW libs "crtbegin.o", "crtend.o", "crt2.o", "dllcrt2.o", "libgcc.a", "libgcc_eh.a", "libgcc_s.a", "libm.a", "libmingw32.a", "libmingwex.a", "libstdc++.a", "libiconv.a", "libmoldname.a", # Windows import libs "libadvapi32.a", "libbcrypt.a", "libcomctl32.a", "libcomdlg32.a", "libcrypt32.a", "libctl3d32.a", "libgdi32.a", "libimagehlp.a", "libiphlpapi.a", "libkernel32.a", "libmsvcrt.a", "libodbc32.a", "libole32.a", "liboleaut32.a", "libopengl32.a", "libpsapi.a", "librpcrt4.a", "libsetupapi.a", "libshell32.a", "libuser32.a", "libuuid.a", "libwinhttp.a", "libwinmm.a", "libwinspool.a", "libws2_32.a", "libwsock32.a", ] </ins> # Find mingw artifacts we want to bundle target_tools = find_files(target_tools, bin_path)