Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Choosing which CRT to link to #1684

Closed
wants to merge 4 commits into from
Closed

Conversation

retep998
Copy link
Member

@retep998 retep998 commented Jul 23, 2016

@retep998 retep998 changed the title Initial version of RFC Choosing which CRT to link to Jul 23, 2016
@nagisa
Copy link
Member

nagisa commented Jul 24, 2016

Environment variable sounds like a very hacky solution to a very specific problem. We instead should be solving this problem in general (overriding the libraries which are linked to and the way they’re linked) and less hacky way (line or two in a Cargo.toml or something).

I find --extern cratename=path to be a very good example of something done okay in that direction. I feel like something similar could be done for native libraries too.

(thinking about it, if libc linked to libc_sys, swapping out libc would already be possible through --extern libc_sys=somecrate.rlib, where all somecrate.rlib does is linking to a library, but that feels clunky)

@retep998
Copy link
Member Author

retep998 commented Jul 24, 2016

@nagisa Well...

  1. libc which libstd depends on has a #[link], and because it isn't a normal Cargo dependency there is no way to control it with build scripts or cfgs or otherwise. We could remove that #[link] but something will still need to be responsible for telling the linker which CRT to link to. It has to be something which can do the job even in a non-cargo environment, so it has to be part of rustc somehow.
  2. libc from crates.io which has the same #[link] except now we have backwards compatibility to think about. Since users of new versions of Rust are supposed to be able to use old versions of libc (otherwise we'd be breaking our stability promise), we have to have something be able to override libc's decisions. Only rustc is in a suitable position to do this, since there isn't a build script whose output cargo could post process.
  3. gcc from crates.io and probably cmake too, currently always compile C/C++ code with /MD, meaning a default reference is always inserted to msvcrt.lib, and again Rust has to be backwards compatible with these crates. So something has to insert a /NODEFAULTLIB:msvcrt.lib in order to override that, and while yes the user could technically use cargo rustc -- -Clink-args="/NODEFAULTLIB:msvcrt.lib" doing so is not obvious at all and it is better if rustc/cargo handles this automatically.
  4. I chose an environment variable because in order for build scripts to know how to build C/C++ code, they would need to be told which CRT to compile code for, and currently the way build scripts are told about that is via an environment variable. If we don't use an environment variable, then it will have to be something that cargo can understand so it can pass an environment variable on to build scripts and inform rustc as well.

I don't mind if we use some sort of parameter to cargo somehow instead of an environment variable. I just care that as a result of whatever option it is, build scripts are informed how to build C/C++ code, and rustc will automatically strip out references to the wrong CRT (because we have to for backwards compatibility).

@nagisa
Copy link
Member

nagisa commented Jul 24, 2016

libc which libstd depends on has a #[link], and because it isn't a normal Cargo dependency

Yes, it sounds to me like what we should be investigating is a --extern-like scheme for #[link] attributes.

gcc from crates.io and probably cmake too, currently always compile C/C++ code with /MD, meaning a default reference is always inserted to msvcrt.lib

Same problem exists on linux too. gcc/clang solve this by having a -static flag (which I suppose would have the effect you describe on windows).

libc from crates.io which has the same #[link] except now we have backwards compatibility to think about.

and

rustc will automatically strip out references to the wrong CRT (because we have to for backwards compatibility).

I don’t see how backward compatibility comes into play here. It seems to me that whatever scheme we pick here, we would only ever be forward-incompatible at worst. No rustc/cargo upgrade could break a pinned version of liblibc which does not support linking library statically.

I chose an environment variable because in order for build scripts to know how to build C/C++ code, they would need to be told which CRT to compile code for, and currently the way build scripts are told about that is via an environment variable.

That’s probably the least convincing reason to use environment variables to me. We co-develop cargo along with rustc and libcore/libstd/liblibc and its fully within our power to make cargo support whatever scheme we decide on.

@retep998
Copy link
Member Author

retep998 commented Jul 24, 2016

Same problem exists on linux too. gcc/clang solve this by having a -static flag (which I suppose would have the effect you describe on windows).

Well on Windows you don't have both static and dynamic versions of a library with the same name with the only way to differentiate between them being the -static flag. The only way to switch from dynamic to static is just not linking to the dynamic one and instead linking to the static one, which is a bit difficult when everything is throwing in implicit or explicit dependencies on the dynamic version..

I don’t see how backward compatibility comes into play here. It seems to me that whatever scheme we pick here, we would only ever be forward-incompatible at worst. No rustc/cargo upgrade could break a pinned version of liblibc which does not support linking library statically.

@nagisa If we try to link libcmt.lib when msvcrt.lib is already being passed by liblibc then the linker will complain about duplicate definitions and even if it doesn't, things will fall apart and break due to linking to two different CRTs which is very bad. Future Rust versions will need to be backwards compatible with the current versions of libc and cmake and gcc, so in order to do that Rust will need to override their decisions. Although the compiled C/C++ code won't be optimal (wrong usage of dllimport), it will usually still work. If we don't override their decisions then we'd need every single crate that brings in an implicit or explicit dependency on msvcrt.lib to support alternate CRTs, which means a project wouldn't be able to take advantage of static CRT support until all their relevant dependencies update.

We co-develop cargo along with rustc and libcore/libstd/liblibc and its fully within our power to make cargo support whatever scheme we decide on.

Then please pick a scheme which supports the following and I'll gladly support it:

  1. Stripping out any dependency to the wrong CRT, including when done via #[link].
  2. Telling the linker to ignore implicit dependencies to the wrong CRT.
  3. Adding a dependency to the right CRT.
  4. Telling a build script which CRT it needs to compile C/C++ for.
  5. Doing all this without requiring new versions of any crates.io crate that links to the CRT or compiles C/C++ code (aside from obscure exceptions).

@ahicks92
Copy link

My two cents, for what it's worth:

I am a Windows developer. I do not know how to distribute the CRT without first looking up the procedure because /MT is way more convenient. Unlike Linux, I can't assume that my end user has it, would be willing to install it, or would even know how to install it if they wanted to. Unless the app has an installer, you have to distribute the DLL alongside it anyway, ruining any real benefit in dynamically linking it. I had assumed Rust would be smart enough to know how to do this and I could just Google it. At the moment my Rust work can be done on MinGW, but I expect this to change.

I'm not saying that this is beautiful. In fact I think it's quite ugly. But it makes it possible. With it, I can give exes out to fellow devs without having to play the "Are you missing the runtime?" game. With this, I can build portable apps and conveniently link my large MSVC-only audio library into them. I have a large C++ package with Python bindings, and the static runtime is how I have wheels that just work; put another way, this is part of the "using Rust from other languages" story in my book. If this can be hacked around, I'd love to know how. If it can't, I think that this RFC should be pushed through as quickly as possible, then followed up with one that makes it pretty and possibly more general. The only change I would propose is possibly making the setting a command line argument to rustc, but I'm sure there's a good reason for choosing the environment variable.

Under the right circumstances, I would go to Nightly to get this feature.

@retep998
Copy link
Member Author

retep998 commented Jul 24, 2016

Anyway, right now there's two ways of configuring this that I see which satisfy my requirements stated in my previous message.

  1. User sets an environment variable which both rustc and build scripts obey. If Add a way for build scripts to be re-run if specific environment variables change cargo#2776 ever gets fixed, then this could enable minimal rebuilds when switching CRT as well.
  2. User sets some sort of flag or configuration for cargo which sets an environment variable for build scripts and passes some sort of flag to rustc.

If anyone can think of a better way, please say so. If you think one of these options is better, please say so.

@retep998 retep998 mentioned this pull request Jul 24, 2016
47 tasks
@codyps
Copy link

codyps commented Jul 24, 2016

Regarding the specific variable to use, it probably makes sense to use the same resolution methodology in place in gcc-rs for CFLAGS, CC, etc. Copied from it's docs:

Each of these variables can also be supplied with certain prefixes and suffixes,
in the following prioritized order:

  1. <var>_<target> - for example, CC_x86_64-unknown-linux-gnu
  2. <var>_<target_with_underscores> - for example, CC_x86_64_unknown_linux_gnu
  3. <build-kind>_<var> - for example, HOST_CC or TARGET_CFLAGS
  4. <var> - a plain CC, AR as above.

So, just do the above for <var> == CRT_KIND (or whatever).

@Diggsey
Copy link
Contributor

Diggsey commented Jul 24, 2016

I would much prefer option 2. I strongly dislike "persistent" environment variables and think they are a terrible way to configure a program: the communication between cargo and a build script is one of the few acceptable uses of environment variables in my mind:

  1. The set of environment variables in use is well defined and documented.
  2. The configuration never changes for the duration of the program from which those environment variables are inherited.
  3. It is a program rather than a person which is configuring the environment.

Any time one of those is violated it causes endless problems.

Option 2 falls foul only of 1) and to solve that, I don't see why we need dynamically named environment variables if it's only used for communication between cargo and the build script - can't we just have a single CRT_KIND environment variable in that case?

@retep998
Copy link
Member Author

retep998 commented Jul 24, 2016

@Diggsey If we did go with option 2, then cargo would only need to pass a simple short CRT_KIND to build scripts. It is only in option 1 where it would need qualification like in @jmesmon 's comment.

Option 2 falls foul only of 1)

I'm not sure what you mean by this.

@ahicks92
Copy link

Perhaps a runtime_link option in Cargo for all targets with possible values static/dynamic, coupled with the environment variables? It seems like other platforms also have this. For those which only have one value or the other, we can error if the user tries to set it.

As someone who uses CMake, I can confirm that the default behavior is /MD and/or /MDD depending on build type. You can offer a CMake option to switch it on a per-project basis, or just make users find/replace the CMakeCache.txt.

On a reread, my previous comment comes across as heavy-handed and possibly a bit hostile. I apologize for that.

@nrc nrc added the T-dev-tools Relevant to the development tools team, which will review and decide on the RFC. label Jul 25, 2016
@alexcrichton
Copy link
Member

The fact that our MSVC target dynamically links the CRT is basically just a historical accident at this point, and I do personally wish that we linked statically by default specifically in the case of MSVC. This question has also come up before for other targets as well. For example the x86_64-unknown-linux-musl target is statically linked to musl right now, but Alpine dynamically links by default and it'd be better to have that behavior there as well.

This also plays into the question of intrusive target configuration in Cargo for the standard library as well for various other codegen options, etc. The compiler and/or Cargo will also need the ability to inform gcc-rs and relevant crates about these options chosen so it can take advantage of it as well, so it's likely that a solution to that problem can be piggy-backed to a solution to this problem.

I'm personally pretty wary of codegen options getting selected by environment variables, and I'm also pretty wary of the static/dynamic split on MSVC. If code compiled for a static msvcrt can't be linked against code compiled for a dynamic msvcrt, then how can we compile what we're shipping as part of the x86_64-pc-windows-msvc target? Right now we may get away with it because we don't ship any C code, but this may be subject to change over time. Am I correct in interpreting that if we used "hot swapping" of any form for a feature like this, we could never add C code to the MSVC target we ship? I believe all other platforms are ok with this because dynamic/static doesn't affect codegen all that much as well, right?

If this is the case then I think we'll really need what amounts to an entirely new target and set of artifacts for this. I'd prefer to avoid actually adding a new target, but the question about other forms of codegen configuration may also play into this as well.

@retep998
Copy link
Member Author

retep998 commented Jul 25, 2016

@alexcrichton The choice between /MD and /MT for the most part just affects how dllimport is applied. Rust already is incapable of figuring out how to apply dllimport and very frequently gets it wrong, so it seems kinda surprising that you suddenly care about whether C can get it right. Rust using stuff from the CRT and getting dllimport wrong is equally as bad as C code using stuff from the CRT and getting dllimport wrong, so adding C code to the MSVC target is equally as bad as adding Rust code to the MSVC target. Adding new targets and new artifacts for linking to the static CRT instead of the dynamic CRT won't really help when Rust doesn't understand dllimport to begin with. But if you wanna push for getting Rust to actually understand dllimport finally, then sure we can have a set of artifacts properly compiled for a given CRT version, but until then it just seems wasteful and useless.

If we really want to get technical about it, every single version of the CRT technically is ABI incompatible, because each version is allowed to add remove and change functionality between versions. Just look at printf which was a function you could link to in older CRT versions and in newer versions was replaced with inline definitions in the headers that reference entirely different symbols. Code compiled against one version of the CRT, whether it is a different version number or static vs dynamic or even debug vs release, can very easily fail to link against a different version (or even worse, successfully link and then result in bugs and crashes at runtime). The reason we don't currently care about which version number the user uses is because we limit ourselves to a subset of functionality which hasn't changed across those versions. As long as you limit your Rust or C code to functionality which remains ABI compatible across all versions of the CRT you care about, then everything is fine, aside from dllimport for dynamic vs static. If you don't depend on any symbols from the CRT, then suddenly you don't even have to care about whether to apply dllimport to CRT symbols because you have none to care about.

Also, if you do want to have separate targets for dynamic vs static CRT, what about debug vs release CRT? Surely someone out there will have a reason for using the debug CRT, so should we add targets for that as well? Does Rust feel like maintaining 8 msvc targets, testing them on buildbot, and distributing artifacts for all of them?

@nagisa
Copy link
Member

nagisa commented Jul 25, 2016

Oh, something I mentioned on IRC, but ended up not mentioning here (also something borderline unrelated to RFC).

Our dependencies on native libraries are very deep in the dependency chain. Executables depend on libstd, libstd depends on liblibc which, in turn, depends on some sort of native C library. This is complete reversal of how linking model works elsewhere, where all the dependent libraries are usually supplied during the link of the final executable.

I feel like that is a big mistake we’re making which also makes solving a bunch of problems hard (swapping out crt, swapping out an allocator, swapping out a panic runtime, etc). We (me and the RFC author) figured out, though, that doing anything about the described issue wouldn’t exactly help much in solving problems described by this RFC¹, but maybe somebody will have any ideas.

¹: Giving build.rs scripts knowledge about CRT being linked to is still hard.

@ahicks92
Copy link

Could this be handled with a special link attribute to specify linking to the CRT for your current platform? This can then be put in a crate, probably libc. As people upgrade it, they're moving off the old behavior. My thought is that dead code elimination will kill the unneeded parts of the CRT, in the case of static linking.

Is the /nodefaultlib guaranteed not to break anything? It seems to me that this would require the symbols to always be the same in all four versions. Does Microsoft make this guarantee? I would think not, as there are some macros that would let C/C++ code tell.

@retep998
Copy link
Member Author

@camlorn /NODEFAULTLIB cannot solve every case, so yes there would be cases where things don't work. Ideally the user would have updated versions of crates that compile C/C++ code to ensure the code is built the correct way. In the static vs dynamic case most of the time it is usually just a matter of whether dllimport is applied, so /NODEFAULTLIB would more likely than not make things work. The debug vs release CRT case is an entirely different story though.

@retep998
Copy link
Member Author

@camlorn Although if we really wanted to be safe, we'd have to ensure that you're not allowed to link in C/C++ code compiled for the wrong CRT version. The only way to check this however is via the LINK4098 warning. We could set /WX if we wanted to make sure this situation is forbidden, however we would also be turning a lot of other linker warnings into errors, like the fact that Rust still doesn't know how to emit dllimport causing linker warnings every time you reference a static across an object boundary. Alternatively we could scan the output of the linker for this specific warning and then print a loud scary error message. We can't make this just a warning, because in order to detect it we can't pass /nodefaultlib, which would result in a dangerous situation where multiple CRTs are linked in.

LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library
LINK : error LNK1218: warning treated as error; no output file generated

@ahicks92
Copy link

@retep998
I don't like it unless you can convince me that /nodefaultlib isn't going to lead to dangerous situations along the same lines as linking multiple CRTs. I would prefer a noisy, this-didn't-compile failure over a silent, this-is-crashing failure. If we can be 100% certain that it's not going to introduce such issues now or in future, I'm for it. Otherwise, I'm not.

Currently, my vote is for scanning the linker output and leaving /nodefaultlib alone. We can investigate an option to allow packages to pass linker options for specific targets in future, assuming that doesn't exist already. That has the added benefit of being more general, i.e. /LTCG (though I suppose Rust needs to write extra stuff for that) or anything else that your linker supports that Rust doesn't know about yet. C++ devs on Windows should be be used to matching CRTs, I'd think. Though I guess VS hides it.

I wish Microsoft had been smarter about this. Too late now, though.

@vadimcn
Copy link
Contributor

vadimcn commented Jul 26, 2016

Given the difficulties with making the flavor of MSVC CRT configurable (and ugliness of using environment variables to control it), I would propose the following:

  • For MSVC >=2015, keep linking dynamically to the "universal" portion of the CRT (ucrtbase.dll), since it is now distributed with Windows (all supported versions anyways).
    Link statically to the compiler-dependent portion of the CRT for the few symbols we need from there (I believe currently those are: __CxxFrameHandler3, memcpy, memmove and memcmp).
  • Don't change anything for MSVC versions <2015. They are being phased out.
    (we could try using mingw's import library to link to UCRT on these versions too, but I am not sure this is worth the trouble).

I think this will address ~99% of motivation of this RFC. The one case this doesn't solve is Windows XP, so devs who need to target it will have to tweak --link-args manually.

@retep998
Copy link
Member Author

@vadimcn I'm not sure how well supported it is to dynamically link the UCRT while statically linking the VC runtime. If we link msvcrt.lib we get both of them dynamically, and if we link libcmt.lib we get both of them statically. We'd have to end up using /NODEFAULTLIB:vcruntime.lib to ensure that vcruntime.lib isn't linked in and hope that there are no ABI differences between it and libvcruntime.lib.

@vadimcn
Copy link
Contributor

vadimcn commented Jul 27, 2016

@retep998: Based on what I know, I see no reason why dynamic UCRT + static vcruntime shouldn't work. But I've been wrong before :), so this needs to be tried out.

@retep998
Copy link
Member Author

@vadimcn This is what happens.

error: linking with `link.exe` failed: exit code: 1120
note: "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\amd64\\link.exe" "libvcruntime.lib" "/NODEFAULTLIB:vcruntime.lib" "/NOLOGO" "/NXCOMPAT" "/LIBPATH:C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\stage1\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\stage1-rustc\\x86_64-pc-windows-msvc\\release\\deps\\rustc_llvm-ed2ca56657e2cbf6.0.o" "/OUT:C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\stage1-rustc\\x86_64-pc-windows-msvc\\release\\deps\\rustc_llvm-ed2ca56657e2cbf6.dll" "/DEF:C:\\Users\\Peter\\AppData\\Local\\Temp\\rustc.lfvDXrxNxERZ\\lib.def" "C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\stage1-rustc\\x86_64-pc-windows-msvc\\release\\deps\\rustc_llvm-ed2ca56657e2cbf6.metadata.o" "/OPT:REF,ICF" "/DEBUG" "/LIBPATH:C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\stage1-rustc\\x86_64-pc-windows-msvc\\release\\deps" "/LIBPATH:C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\stage1-rustc\\x86_64-pc-windows-msvc\\release\\deps" "/LIBPATH:C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\stage1-rustc\\x86_64-pc-windows-msvc\\release\\build\\rustc_llvm-dfaa780e6392fb2a\\out" "/LIBPATH:C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\llvm/lib" "/LIBPATH:C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\stage1\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "rustllvm.lib" "LLVMX86Disassembler.lib" "LLVMX86AsmParser.lib" "LLVMX86CodeGen.lib" "LLVMX86Desc.lib" "LLVMX86Info.lib" "LLVMX86AsmPrinter.lib" "LLVMX86Utils.lib" "LLVMPowerPCDisassembler.lib" "LLVMPowerPCCodeGen.lib" "LLVMPowerPCAsmParser.lib" "LLVMPowerPCDesc.lib" "LLVMPowerPCInfo.lib" "LLVMPowerPCAsmPrinter.lib" "LLVMMipsDisassembler.lib" "LLVMMipsCodeGen.lib" "LLVMMipsAsmParser.lib" "LLVMMipsDesc.lib" "LLVMMipsInfo.lib" "LLVMMipsAsmPrinter.lib" "LLVMMCJIT.lib" "LLVMipo.lib" "LLVMVectorize.lib" "LLVMLinker.lib" "LLVMIRReader.lib" "LLVMInterpreter.lib" "LLVMExecutionEngine.lib" "LLVMRuntimeDyld.lib" "LLVMAsmParser.lib" "LLVMARMDisassembler.lib" "LLVMARMCodeGen.lib" "LLVMARMAsmParser.lib" "LLVMARMDesc.lib" "LLVMARMInfo.lib" "LLVMARMAsmPrinter.lib" "LLVMAArch64Disassembler.lib" "LLVMMCDisassembler.lib" "LLVMAArch64CodeGen.lib" "LLVMSelectionDAG.lib" "LLVMAsmPrinter.lib" "LLVMCodeGen.lib" "LLVMTarget.lib" "LLVMScalarOpts.lib" "LLVMInstCombine.lib" "LLVMInstrumentation.lib" "LLVMProfileData.lib" "LLVMObject.lib" "LLVMTransformUtils.lib" "LLVMBitWriter.lib" "LLVMBitReader.lib" "LLVMAnalysis.lib" "LLVMCore.lib" "LLVMAArch64AsmParser.lib" "LLVMMCParser.lib" "LLVMAArch64Desc.lib" "LLVMAArch64Info.lib" "LLVMAArch64AsmPrinter.lib" "LLVMMC.lib" "LLVMAArch64Utils.lib" "LLVMSupport.lib" "ole32.lib" "/LIBPATH:C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\stage1\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "std-65a5672b61967d12.dll.lib" "advapi32.lib" "ws2_32.lib" "userenv.lib" "shell32.lib" "msvcrt.lib" "/DLL" "/IMPLIB:C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\stage1-rustc\\x86_64-pc-windows-msvc\\release\\deps\\rustc_llvm-ed2ca56657e2cbf6.dll.lib" "compiler-rt.lib"
note:    Creating library C:\msys64\home\Peter\rust\build\x86_64-pc-windows-msvc\stage1-rustc\x86_64-pc-windows-msvc\release\deps\rustc_llvm-ed2ca56657e2cbf6.dll.lib and object C:\msys64\home\Peter\rust\build\x86_64-pc-windows-msvc\stage1-rustc\x86_64-pc-windows-msvc\release\deps\rustc_llvm-ed2ca56657e2cbf6.dll.exp
LLVMAnalysis.lib(IntervalPartition.obj) : warning LNK4217: locally defined symbol memmove imported in function "protected: class std::_Tree_iterator<class std::_Tree_val<struct std::_Tree_simple_types<struct std::pair<class llvm::BasicBlock * const,class llvm::Interval *> > > > __cdecl std::_Tree<class std::_Tmap_traits<class llvm::BasicBlock *,class llvm::Interval *,struct std::less<class llvm::BasicBlock *>,class std::allocator<struct std::pair<class llvm::BasicBlock * const,class llvm::Interval *> >,0> >::_Insert_at<struct std::pair<class llvm::BasicBlock * const,class llvm::Interval *> &,struct std::_Tree_node<struct std::pair<class llvm::BasicBlock * const,class llvm::Interval *>,void *> *>(bool,struct std::_Tree_node<struct std::pair<class llvm::BasicBlock * const,class llvm::Interval *>,void *> *,struct std::pair<class llvm::BasicBlock * const,class llvm::Interval *> &,struct std::_Tree_node<struct std::pair<class llvm::BasicBlock * const,class llvm::Interval *>,void *> *)" (??$_Insert_at@AEAU?$pair@QEAVBasicBlock@llvm@@PEAVInterval@2@@std@@PEAU?$_Tree_node@U?$pair@QEAVBasicBlock@llvm@@PEAVInterval@2@@std@@PEAX@2@@?$_Tree@V?$_Tmap_traits@PEAVBasicBlock@llvm@@PEAVInterval@2@U?$less@PEAVBasicBlock@llvm@@@std@@V?$allocator@U?$pair@QEAVBasicBlock@llvm@@PEAVInterval@2@@std@@@5@$0A@@std@@@std@@IEAA?AV?$_Tree_iterator@V?$_Tree_val@U?$_Tree_simple_types@U?$pair@QEAVBasicBlock@llvm@@PEAVInterval@2@@std@@@std@@@std@@@1@_NPEAU?$_Tree_node@U?$pair@QEAVBasicBlock@llvm@@PEAVInterval@2@@std@@PEAX@1@AEAU?$pair@QEAVBasicBlock@llvm@@PEAVInterval@2@@1@1@Z)
LLVMAnalysis.lib(PostDominators.obj) : warning LNK4217: locally defined symbol memmove imported in function "protected: void __cdecl std::vector<class llvm::BasicBlock *,class std::allocator<class llvm::BasicBlock *> >::_Reserve(unsigned __int64)" (?_Reserve@?$vector@PEAVBasicBlock@llvm@@V?$allocator@PEAVBasicBlock@llvm@@@std@@@std@@IEAAX_K@Z)
LLVMAnalysis.lib(RegionPrinter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(SpecialCaseList.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: char * __cdecl std::allocator<char>::allocate(unsigned __int64)" (?allocate@?$allocator@D@std@@QEAAPEAD_K@Z)
LLVMAnalysis.lib(CFGPrinter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(CostModel.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(DivergenceAnalysis.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(DomPrinter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(RegionInfo.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(RegionPass.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(AliasAnalysisEvaluator.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(CallPrinter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMBitWriter.lib(ValueEnumerator.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(CallGraphSCCPass.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(BlockFrequencyInfo.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(LoopAccessAnalysis.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMTransformUtils.lib(UnifyFunctionExitNodes.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMTransformUtils.lib(LoopUnrollRuntime.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMBitWriter.lib(BitWriter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMBitWriter.lib(BitcodeWriter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMTransformUtils.lib(PromoteMemoryToRegister.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMTransformUtils.lib(LoopUnroll.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMTransformUtils.lib(LoopVersioning.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMTransformUtils.lib(ASanStackFrameLayout.obj) : warning LNK4217: locally defined symbol memmove imported in function "void __cdecl llvm::ComputeASanStackFrameLayout(class llvm::SmallVectorImpl<struct llvm::ASanStackVariableDescription> &,unsigned __int64,unsigned __int64,struct llvm::ASanStackFrameLayout *)" (?ComputeASanStackFrameLayout@llvm@@YAXAEAV?$SmallVectorImpl@UASanStackVariableDescription@llvm@@@1@_K1PEAUASanStackFrameLayout@1@@Z)
LLVMTransformUtils.lib(CodeExtractor.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMTransformUtils.lib(CtorUtils.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMTransformUtils.lib(LoopUtils.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMTransformUtils.lib(LowerSwitch.obj) : warning LNK4217: locally defined symbol memmove imported in function "private: class llvm::BasicBlock * __cdecl `anonymous namespace'::LowerSwitch::switchConvert(class std::_Vector_iterator<class std::_Vector_val<struct std::_Simple_types<struct `anonymous namespace'::LowerSwitch::CaseRange> > >,class std::_Vector_iterator<class std::_Vector_val<struct std::_Simple_types<struct `anonymous namespace'::LowerSwitch::CaseRange> > >,class llvm::ConstantInt *,class llvm::ConstantInt *,class llvm::Value *,class llvm::BasicBlock *,class llvm::BasicBlock *,class llvm::BasicBlock *,class std::vector<struct `anonymous namespace'::IntRange,class std::allocator<struct `anonymous namespace'::IntRange> > const &)" (?switchConvert@LowerSwitch@?A0x8cdc5a1f@@AEAAPEAVBasicBlock@llvm@@V?$_Vector_iterator@V?$_Vector_val@U?$_Simple_types@UCaseRange@LowerSwitch@?A0x8cdc5a1f@@@std@@@std@@@std@@0PEAVConstantInt@4@1PEAVValue@4@PEAV34@33AEBV?$vector@UIntRange@?A0x8cdc5a1f@@V?$allocator@UIntRange@?A0x8cdc5a1f@@@std@@@6@@Z)
LLVMObject.lib(FunctionIndexObjectFile.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: void __cdecl std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::shrink_to_fit(void)" (?shrink_to_fit@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAXXZ)
LLVMTransformUtils.lib(CloneModule.obj) : warning LNK4217: locally defined symbol memmove imported in function "class std::unique_ptr<class llvm::Module,struct std::default_delete<class llvm::Module> > __cdecl llvm::CloneModule(class llvm::Module const *,class llvm::ValueMap<class llvm::Value const *,class llvm::WeakVH,struct llvm::ValueMapConfig<class llvm::Value const *,class llvm::sys::SmartMutex<0> > > &,class std::function<bool __cdecl(class llvm::GlobalValue const *)>)" (?CloneModule@llvm@@YA?AV?$unique_ptr@VModule@llvm@@U?$default_delete@VModule@llvm@@@std@@@std@@PEBVModule@1@AEAV?$ValueMap@PEBVValue@llvm@@VWeakVH@2@U?$ValueMapConfig@PEBVValue@llvm@@V?$SmartMutex@$0A@@sys@2@@2@@1@V?$function@$$A6A_NPEBVGlobalValue@llvm@@@Z@3@@Z)
LLVMTransformUtils.lib(Mem2Reg.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMTransformUtils.lib(InlineFunction.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMProfileData.lib(SampleProf.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMProfileData.lib(SampleProfReader.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMProfileData.lib(InstrProf.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMProfileData.lib(InstrProfReader.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMInstrumentation.lib(AddressSanitizer.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMInstrumentation.lib(MemorySanitizer.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMInstrumentation.lib(ThreadSanitizer.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMInstrumentation.lib(DataFlowSanitizer.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMInstrumentation.lib(BoundsChecking.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMInstrumentation.lib(GCOVProfiling.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMInstrumentation.lib(PGOInstrumentation.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMInstrumentation.lib(InstrProfiling.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(PlaceSafepoints.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMInstCombine.lib(InstructionCombining.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMInstCombine.lib(InstCombineCalls.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMInstCombine.lib(InstCombineVectorOps.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: class llvm::Instruction * __cdecl llvm::InstCombiner::visitExtractElementInst(class llvm::ExtractElementInst &)" (?visitExtractElementInst@InstCombiner@llvm@@QEAAPEAVInstruction@2@AEAVExtractElementInst@2@@Z)
LLVMScalarOpts.lib(StructurizeCFG.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(InductiveRangeCheckElimination.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(RewriteStatepointsForGC.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(StraightLineStrengthReduce.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(Float2Int.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(LoopDistribute.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(LoopLoadElimination.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(Scalarizer.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(GVN.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(MemCpyOptimizer.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(LoopDeletion.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: virtual bool __cdecl `anonymous namespace'::LoopDeletion::runOnLoop(class llvm::Loop *,class llvm::LPPassManager &)" (?runOnLoop@LoopDeletion@?A0xe74e05ca@@UEAA_NPEAVLoop@llvm@@AEAVLPPassManager@4@@Z)
LLVMScalarOpts.lib(LoadCombine.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(LoopRerollPass.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(LoopRotation.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(Reassociate.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(JumpThreading.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(SROA.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(ScalarReplAggregates.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(LoopInterchange.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(LoopUnswitch.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAsmParser.lib(Parser.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAsmParser.lib(LLLexer.obj) : warning LNK4217: locally defined symbol memmove imported in function "void __cdecl UnEscapeLexed(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?UnEscapeLexed@@YAXAEAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
LLVMAsmParser.lib(LLParser.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(DeadStoreElimination.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMVectorize.lib(SLPVectorizer.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMIRReader.lib(IRReader.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: __cdecl llvm::SMDiagnostic::~SMDiagnostic(void)" (??1SMDiagnostic@llvm@@QEAA@XZ)
LLVMExecutionEngine.lib(ExecutionEngineBindings.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMExecutionEngine.lib(TargetSelect.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMipo.lib(FunctionImport.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMipo.lib(Inliner.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMVectorize.lib(BBVectorize.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMVectorize.lib(LoopVectorize.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMipo.lib(MergeFunctions.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMipo.lib(PartialInlining.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMipo.lib(FunctionAttrs.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMipo.lib(StripSymbols.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMipo.lib(ForceFunctionAttrs.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMipo.lib(GlobalDCE.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: virtual bool __cdecl `anonymous namespace'::GlobalDCE::runOnModule(class llvm::Module &)" (?runOnModule@GlobalDCE@?A0x3e5cfd56@@UEAA_NAEAVModule@llvm@@@Z)
LLVMipo.lib(GlobalOpt.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMipo.lib(LowerBitSets.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMipo.lib(ArgumentPromotion.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMipo.lib(SampleProfile.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMipo.lib(LoopExtractor.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMipo.lib(DeadArgumentElimination.obj) : warning LNK4049: locally defined symbol memmove imported
rustllvm.lib(ExecutionEngineWrapper.o) : warning LNK4049: locally defined symbol memmove imported
rustllvm.lib(PassWrapper.o) : warning LNK4049: locally defined symbol memmove imported
LLVMipo.lib(IPO.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMipo.lib(Internalize.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(Program.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(ConvertUTFWrapper.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(regcomp.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(regexec.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(YAMLParser.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(StreamingMemoryObject.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(RandomNumberGenerator.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(Signals.obj) : warning LNK4217: locally defined symbol memmove imported in function "void __cdecl std::_Destroy_range<struct std::_Wrap_alloc<class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > >(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *,struct std::_Wrap_alloc<class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > &)" (??$_Destroy_range@U?$_Wrap_alloc@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@std@@@std@@@std@@YAXPEAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@0AEAU?$_Wrap_alloc@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@std@@@0@@Z)
LLVMSupport.lib(YAMLTraits.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(TimeValue.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(ToolOutputFile.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(Host.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(TargetParser.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(GraphWriter.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: char * __cdecl std::allocator<char>::allocate(unsigned __int64)" (?allocate@?$allocator@D@std@@QEAAPEAD_K@Z)
LLVMSupport.lib(ScaledNumber.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(Regex.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(Memory.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(Process.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(Path.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(FoldingSet.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(Debug.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(SmallPtrSet.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(TargetRegistry.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(DynamicLibrary.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: static class llvm::sys::DynamicLibrary __cdecl llvm::sys::DynamicLibrary::getPermanentLibrary(char const *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *)" (?getPermanentLibrary@DynamicLibrary@sys@llvm@@SA?AV123@PEBDPEAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
LLVMSupport.lib(StringRef.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(APInt.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(CommandLine.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(APFloat.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(Triple.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(raw_ostream.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(Timer.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(SourceMgr.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAArch64Utils.lib(AArch64BaseInfo.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSupport.lib(MemoryBuffer.obj) : warning LNK4217: locally defined symbol memmove imported in function "class std::_Generic_error_category & __cdecl std::_Immortalize<class std::_Generic_error_category>(void)" (??$_Immortalize@V_Generic_error_category@std@@@std@@YAAEAV_Generic_error_category@0@XZ)
LLVMSupport.lib(ErrorHandling.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: void __cdecl std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::shrink_to_fit(void)" (?shrink_to_fit@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAXXZ)
LLVMSupport.lib(Twine.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMC.lib(MCObjectFileInfo.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMC.lib(MCSectionMachO.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMC.lib(SubtargetFeature.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMC.lib(StringTableBuilder.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMC.lib(MCInstrDesc.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMC.lib(MCELFStreamer.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMC.lib(MCMachOStreamer.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMC.lib(MCDwarf.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMC.lib(MachObjectWriter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMC.lib(MCAssembler.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMC.lib(ELFObjectWriter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMC.lib(WinCOFFObjectWriter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMC.lib(MCContext.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMC.lib(MCStreamer.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMC.lib(MCObjectStreamer.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMC.lib(WinCOFFStreamer.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMCParser.lib(ELFAsmParser.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAArch64Desc.lib(AArch64MCTargetDesc.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAArch64AsmPrinter.lib(AArch64InstPrinter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMC.lib(MCSubtargetInfo.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMCParser.lib(MCTargetAsmParser.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMCParser.lib(AsmParser.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMCParser.lib(AsmLexer.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMCParser.lib(DarwinAsmParser.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(DiagnosticInfo.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(AutoUpgrade.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(ValueSymbolTable.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAArch64AsmParser.lib(AArch64AsmParser.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(DebugInfoMetadata.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(IRPrintingPasses.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: virtual void * __cdecl llvm::BasicBlockPass::`scalar deleting destructor'(unsigned int)" (??_GBasicBlockPass@llvm@@UEAAPEAXI@Z)
LLVMCore.lib(Verifier.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(IRBuilder.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(ValueTypes.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(Globals.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > & __cdecl std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::assign(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,unsigned __int64,unsigned __int64)" (?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@AEBV12@_K1@Z)
LLVMCore.lib(Dominators.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(TypeFinder.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(DIBuilder.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(LegacyPassManager.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(PassRegistry.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: static class llvm::PassRegistry * __cdecl llvm::PassRegistry::getPassRegistry(void)" (?getPassRegistry@PassRegistry@llvm@@SAPEAV12@XZ)
LLVMCore.lib(DataLayout.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(Instructions.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(Function.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(InlineAsm.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(Module.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(Constants.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(LLVMContext.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(Type.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(Attributes.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(PHITransAddr.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(Core.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(AsmWriter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCore.lib(User.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(LoopPass.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(LazyValueInfo.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(DemandedBits.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(CallGraph.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(DominanceFrontier.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(GlobalsModRef.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(MemoryDependenceAnalysis.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(BlockFrequencyInfoImpl.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(TargetLibraryInfo.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(ScalarEvolutionExpander.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(CodeMetrics.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(CFLAliasAnalysis.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMBitReader.lib(BitstreamReader.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: void __cdecl llvm::BitstreamCursor::ReadAbbrevRecord(void)" (?ReadAbbrevRecord@BitstreamCursor@llvm@@QEAAXXZ)
LLVMAnalysis.lib(VectorUtils.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(LoopInfo.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAnalysis.lib(ScalarEvolution.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMTransformUtils.lib(SSAUpdater.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMTransformUtils.lib(SimplifyLibCalls.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMTransformUtils.lib(SimplifyCFG.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMBitReader.lib(BitcodeReader.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMTransformUtils.lib(LCSSA.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: void * __cdecl llvm::BumpPtrAllocatorImpl<class llvm::MallocAllocator,4096,4096>::Allocate(unsigned __int64,unsigned __int64)" (?Allocate@?$BumpPtrAllocatorImpl@VMallocAllocator@llvm@@$0BAAA@$0BAAA@@llvm@@QEAAPEAX_K0@Z)
LLVMTransformUtils.lib(BreakCriticalEdges.obj) : warning LNK4217: locally defined symbol memmove imported in function "void __cdecl createPHIsForSplitLoopExit(class llvm::ArrayRef<class llvm::BasicBlock *>,class llvm::BasicBlock *,class llvm::BasicBlock *)" (?createPHIsForSplitLoopExit@@YAXV?$ArrayRef@PEAVBasicBlock@llvm@@@llvm@@PEAVBasicBlock@2@1@Z)
LLVMTransformUtils.lib(SymbolRewriter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMTransformUtils.lib(CloneFunction.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMObject.lib(IRObjectFile.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMTransformUtils.lib(BasicBlockUtils.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMTransformUtils.lib(Local.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMTransformUtils.lib(LoopSimplify.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMObject.lib(Error.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMObject.lib(SymbolicFile.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMObject.lib(ELFObjectFile.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMObject.lib(MachOUniversal.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: virtual void * __cdecl llvm::object::MachOUniversalBinary::`scalar deleting destructor'(unsigned int)" (??_GMachOUniversalBinary@object@llvm@@UEAAPEAXI@Z)
LLVMObject.lib(ObjectFile.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMObject.lib(MachOObjectFile.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMObject.lib(Binary.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMObject.lib(COFFObjectFile.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(LoopStrengthReduce.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMObject.lib(Object.obj) : warning LNK4217: locally defined symbol memmove imported in function "class std::_Generic_error_category & __cdecl std::_Immortalize<class std::_Generic_error_category>(void)" (??$_Immortalize@V_Generic_error_category@std@@@std@@YAAEAV_Generic_error_category@0@XZ)
LLVMObject.lib(Archive.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMObject.lib(ArchiveWriter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMTarget.lib(TargetMachine.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: class std::_Tree_iterator<class std::_Tree_val<struct std::_Tree_simple_types<struct std::pair<class llvm::StringRef const ,struct llvm::TargetRecip::RecipParams> > > > __cdecl std::_Tree<class std::_Tmap_traits<class llvm::StringRef,struct llvm::TargetRecip::RecipParams,struct std::less<class llvm::StringRef>,class std::allocator<struct std::pair<class llvm::StringRef const ,struct llvm::TargetRecip::RecipParams> >,0> >::erase(class std::_Tree_const_iterator<class std::_Tree_val<struct std::_Tree_simple_types<struct std::pair<class llvm::StringRef const ,struct llvm::TargetRecip::RecipParams> > > >)" (?erase@?$_Tree@V?$_Tmap_traits@VStringRef@llvm@@URecipParams@TargetRecip@2@U?$less@VStringRef@llvm@@@std@@V?$allocator@U?$pair@$$CBVStringRef@llvm@@URecipParams@TargetRecip@2@@std@@@6@$0A@@std@@@std@@QEAA?AV?$_Tree_iterator@V?$_Tree_val@U?$_Tree_simple_types@U?$pair@$$CBVStringRef@llvm@@URecipParams@TargetRecip@2@@std@@@std@@@std@@@2@V?$_Tree_const_iterator@V?$_Tree_val@U?$_Tree_simple_types@U?$pair@$$CBVStringRef@llvm@@URecipParams@TargetRecip@2@@std@@@std@@@std@@@2@@Z)
LLVMScalarOpts.lib(LICM.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(EarlyCSE.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMScalarOpts.lib(SeparateConstOffsetFromGEP.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(MachinePostDominators.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(SplitKit.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMTarget.lib(Target.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: void __cdecl std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::_Copy(unsigned __int64,unsigned __int64)" (?_Copy@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAX_K0@Z)
LLVMTarget.lib(TargetRecip.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(LatencyPriorityQueue.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(InlineSpiller.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(MIRPrinter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(LiveDebugVariables.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(ScheduleDAGInstrs.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(MachineBlockFrequencyInfo.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(LiveStackAnalysis.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(AggressiveAntiDepBreaker.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(StackSlotColoring.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(LiveDebugValues.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(LiveRangeEdit.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: void * __cdecl llvm::BumpPtrAllocatorImpl<class llvm::MallocAllocator,4096,4096>::Allocate(unsigned __int64,unsigned __int64)" (?Allocate@?$BumpPtrAllocatorImpl@VMallocAllocator@llvm@@$0BAAA@$0BAAA@@llvm@@QEAAPEAX_K0@Z)
LLVMCodeGen.lib(RegisterPressure.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(MachineBlockPlacement.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(MachineLICM.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(MachineSink.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(MachineCopyPropagation.obj) : warning LNK4217: locally defined symbol memmove imported in function "void __cdecl llvm::initializeMachineCopyPropagationPass(class llvm::PassRegistry &)" (?initializeMachineCopyPropagationPass@llvm@@YAXAEAVPassRegistry@1@@Z)
LLVMCodeGen.lib(PrologEpilogInserter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(BranchFolding.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(TailDuplication.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(StackColoring.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(StackProtector.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(PHIElimination.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(TwoAddressInstructionPass.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(ShrinkWrap.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(RegAllocFast.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(RegAllocGreedy.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(GCRootLowering.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(ShadowStackGCLowering.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(LexicalScopes.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: void __cdecl llvm::LexicalScopes::initialize(class llvm::MachineFunction const &)" (?initialize@LexicalScopes@llvm@@QEAAXAEBVMachineFunction@2@@Z)
LLVMCodeGen.lib(UnreachableBlockElim.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(MachineFunctionPrinterPass.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(CodeGenPrepare.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(Analysis.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > & __cdecl std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::erase(unsigned __int64,unsigned __int64)" (?erase@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@_K0@Z)
LLVMCodeGen.lib(GCMetadata.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(ScheduleDAGPrinter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(DFAPacketizer.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(PostRASchedulerList.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(PeepholeOptimizer.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(MachineTraceMetrics.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(RegAllocPBQP.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(MachineInstrBundle.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(InterleavedAccessPass.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(GlobalMerge.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(MachineVerifier.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(LiveIntervalAnalysis.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(SlotIndexes.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: class llvm::SlotIndex __cdecl llvm::SlotIndexes::insertMachineInstrInMaps(class llvm::MachineInstr *,bool)" (?insertMachineInstrInMaps@SlotIndexes@llvm@@QEAA?AVSlotIndex@2@PEAVMachineInstr@2@_N@Z)
LLVMCodeGen.lib(LiveInterval.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(ScheduleDAG.obj) : warning LNK4217: locally defined symbol memmove imported in function "private: void __cdecl llvm::ScheduleDAGTopologicalSort::DFS(class llvm::SUnit const *,int,bool &)" (?DFS@ScheduleDAGTopologicalSort@llvm@@AEAAXPEBVSUnit@2@HAEA_N@Z)
LLVMCodeGen.lib(IntrinsicLowering.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(RegisterCoalescer.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(MachineScheduler.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(IfConversion.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(MachineDominators.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(EdgeBundles.obj) : warning LNK4217: locally defined symbol memmove imported in function "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl llvm::WriteGraph<class llvm::EdgeBundles>(class llvm::EdgeBundles const &,class llvm::Twine const &,bool,class llvm::Twine const &)" (??$WriteGraph@VEdgeBundles@llvm@@@llvm@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBVEdgeBundles@0@AEBVTwine@0@_N1@Z)
LLVMCodeGen.lib(MachineLoopInfo.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(WinEHPrepare.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(StackMaps.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(MachineModuleInfo.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(MachineBasicBlock.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(LiveVariables.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(ExecutionDepsFix.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(TargetLoweringObjectFileImpl.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(EarlyIfConversion.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(MachineFunction.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAsmPrinter.lib(DwarfCompileUnit.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAsmPrinter.lib(EHStreamer.obj) : warning LNK4217: locally defined symbol memmove imported in function "protected: void __cdecl llvm::EHStreamer::computeCallSiteTable(class llvm::SmallVectorImpl<struct llvm::EHStreamer::CallSiteEntry> &,class llvm::SmallVectorImpl<struct llvm::LandingPadInfo const *> const &,class llvm::SmallVectorImpl<unsigned int> const &)" (?computeCallSiteTable@EHStreamer@llvm@@IEAAXAEAV?$SmallVectorImpl@UCallSiteEntry@EHStreamer@llvm@@@2@AEBV?$SmallVectorImpl@PEBULandingPadInfo@llvm@@@2@AEBV?$SmallVectorImpl@I@2@@Z)
LLVMCodeGen.lib(MachineInstr.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMCodeGen.lib(Passes.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAsmPrinter.lib(DebugLocStream.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAsmPrinter.lib(DwarfAccelTable.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAsmPrinter.lib(DwarfFile.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAsmPrinter.lib(DwarfUnit.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAsmPrinter.lib(AsmPrinter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAsmPrinter.lib(AsmPrinterInlineAsm.obj) : warning LNK4217: locally defined symbol memmove imported in function "private: void __cdecl llvm::AsmPrinter::EmitInlineAsm(class llvm::MachineInstr const *)const " (?EmitInlineAsm@AsmPrinter@llvm@@AEBAXPEBVMachineInstr@2@@Z)
LLVMAsmPrinter.lib(DwarfDebug.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAsmPrinter.lib(WinCodeViewLineTables.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSelectionDAG.lib(ScheduleDAGRRList.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSelectionDAG.lib(ScheduleDAGVLIW.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSelectionDAG.lib(SelectionDAGPrinter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSelectionDAG.lib(ResourcePriorityQueue.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSelectionDAG.lib(SelectionDAGDumper.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSelectionDAG.lib(ScheduleDAGSDNodes.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSelectionDAG.lib(LegalizeTypes.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSelectionDAG.lib(LegalizeDAG.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSelectionDAG.lib(SelectionDAGISel.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSelectionDAG.lib(TargetLowering.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSelectionDAG.lib(DAGCombiner.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSelectionDAG.lib(StatepointLowering.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAArch64CodeGen.lib(AArch64FrameLowering.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAArch64CodeGen.lib(AArch64ISelLowering.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSelectionDAG.lib(SelectionDAG.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMSelectionDAG.lib(SelectionDAGBuilder.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAArch64CodeGen.lib(AArch64A53Fix835769.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAArch64CodeGen.lib(AArch64CollectLOH.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAArch64CodeGen.lib(AArch64Subtarget.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAArch64CodeGen.lib(AArch64PBQPRegAlloc.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAArch64CodeGen.lib(AArch64ConditionalCompares.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAArch64CodeGen.lib(AArch64PromoteConstant.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAArch64CodeGen.lib(AArch64AddressTypePromotion.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAArch64CodeGen.lib(AArch64A57FPLoadBalancing.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMARMDesc.lib(ARMELFStreamer.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMARMDesc.lib(ARMAsmBackend.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: __cdecl `anonymous namespace'::ARMAsmBackend::ARMAsmBackend(class llvm::Target const &,class llvm::Triple const &,bool)" (??0ARMAsmBackend@?A0x2fee3ca7@@QEAA@AEBVTarget@llvm@@AEBVTriple@3@_N@Z)
LLVMARMDesc.lib(ARMUnwindOpAsm.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMAArch64CodeGen.lib(AArch64TargetMachine.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMARMCodeGen.lib(ARMFrameLowering.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMARMCodeGen.lib(Thumb1FrameLowering.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: void __cdecl std::vector<char,class std::allocator<char> >::_Construct<char const *>(char const *,char const *,struct std::forward_iterator_tag)" (??$_Construct@PEBD@?$vector@DV?$allocator@D@std@@@std@@QEAAXPEBD0Uforward_iterator_tag@1@@Z)
LLVMARMAsmParser.lib(ARMAsmParser.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMARMDesc.lib(ARMMCTargetDesc.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMARMCodeGen.lib(ARMSubtarget.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMARMCodeGen.lib(ARMConstantPoolValue.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMARMCodeGen.lib(ARMISelLowering.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMARMCodeGen.lib(ARMBaseInstrInfo.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMARMCodeGen.lib(ARMLoadStoreOptimizer.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMARMCodeGen.lib(ARMConstantIslandPass.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMARMCodeGen.lib(ARMOptimizeBarriersPass.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMARMCodeGen.lib(Thumb2SizeReduction.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMARMCodeGen.lib(ARMTargetMachine.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMARMCodeGen.lib(ARMAsmPrinter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMARMCodeGen.lib(ARMISelDAGToDAG.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMARMCodeGen.lib(A15SDOptimizer.obj) : warning LNK4217: locally defined symbol memmove imported in function "private: class llvm::SmallVector<unsigned int,8> __cdecl `anonymous namespace'::A15SDOptimizer::getReadDPRs(class llvm::MachineInstr *)" (?getReadDPRs@A15SDOptimizer@?A0xdb2e0bcd@@AEAA?AV?$SmallVector@I$07@llvm@@PEAVMachineInstr@4@@Z)
LLVMRuntimeDyld.lib(RuntimeDyldChecker.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMRuntimeDyld.lib(RuntimeDyldCOFF.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMRuntimeDyld.lib(RuntimeDyldELF.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMRuntimeDyld.lib(RuntimeDyldMachO.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMExecutionEngine.lib(ExecutionEngine.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMExecutionEngine.lib(SectionMemoryManager.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > & __cdecl std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::append(unsigned __int64,char)" (?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@_KD@Z)
LLVMRuntimeDyld.lib(RuntimeDyld.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMRuntimeDyld.lib(RTDyldMemoryManager.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMLinker.lib(IRMover.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMInterpreter.lib(Interpreter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMInterpreter.lib(Execution.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMInterpreter.lib(ExternalFunctions.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMipsDesc.lib(MipsMCTargetDesc.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMipsDesc.lib(MipsMCCodeEmitter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMCJIT.lib(MCJIT.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMLinker.lib(LinkModules.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMipsCodeGen.lib(MipsSEFrameLowering.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMipsCodeGen.lib(Mips16ISelLowering.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMipsCodeGen.lib(MipsSEISelLowering.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMipsAsmParser.lib(MipsAsmParser.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMipsCodeGen.lib(MipsSubtarget.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMipsCodeGen.lib(MipsInstrInfo.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMipsCodeGen.lib(MipsISelLowering.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMipsCodeGen.lib(Mips16FrameLowering.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: virtual unsigned int __cdecl llvm::TargetFrameLowering::getWinEHParentFrameOffset(class llvm::MachineFunction const &)const " (?getWinEHParentFrameOffset@TargetFrameLowering@llvm@@UEBAIAEBVMachineFunction@2@@Z)
LLVMMipsCodeGen.lib(MipsAsmPrinter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMipsCodeGen.lib(MipsOs16.obj) : warning LNK4217: locally defined symbol memmove imported in function "void __cdecl `dynamic initializer for 'Mips32FunctionMask''(void)" (??__EMips32FunctionMask@@YAXXZ)
LLVMMipsCodeGen.lib(Mips16HardFloat.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMipsCodeGen.lib(MipsConstantIslandPass.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMPowerPCAsmParser.lib(PPCAsmParser.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMPowerPCDesc.lib(PPCMCTargetDesc.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMPowerPCAsmPrinter.lib(PPCInstPrinter.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMMipsCodeGen.lib(MipsTargetMachine.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMPowerPCCodeGen.lib(PPCISelDAGToDAG.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMPowerPCCodeGen.lib(PPCSubtarget.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMPowerPCCodeGen.lib(PPCISelLowering.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMPowerPCCodeGen.lib(PPCFrameLowering.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMX86Desc.lib(X86ELFRelocationInfo.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMPowerPCCodeGen.lib(PPCTargetMachine.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMPowerPCCodeGen.lib(PPCVSXSwapRemoval.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMPowerPCCodeGen.lib(PPCBranchSelector.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMX86CodeGen.lib(X86ISelLowering.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMX86Desc.lib(X86MCTargetDesc.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMX86Desc.lib(X86AsmBackend.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMX86Desc.lib(X86MachORelocationInfo.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: virtual class llvm::MCExpr const * __cdecl `anonymous namespace'::X86_64MachORelocationInfo::createExprForRelocation(class llvm::object::RelocationRef)" (?createExprForRelocation@X86_64MachORelocationInfo@?A0x1c875f9c@@UEAAPEBVMCExpr@llvm@@VRelocationRef@object@4@@Z)
LLVMX86CodeGen.lib(X86CallFrameOptimization.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMX86CodeGen.lib(X86TargetObjectFile.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMX86CodeGen.lib(X86MCInstLower.obj) : warning LNK4217: locally defined symbol memmove imported in function "public: virtual void __cdecl llvm::X86AsmPrinter::EmitInstruction(class llvm::MachineInstr const *)" (?EmitInstruction@X86AsmPrinter@llvm@@UEAAXPEBVMachineInstr@2@@Z)
LLVMX86CodeGen.lib(X86FrameLowering.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMX86CodeGen.lib(X86TargetMachine.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMX86CodeGen.lib(X86Subtarget.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMX86CodeGen.lib(X86InstrInfo.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMX86CodeGen.lib(X86OptimizeLEAs.obj) : warning LNK4049: locally defined symbol memmove imported
rustllvm.lib(ArchiveWrapper.o) : warning LNK4217: locally defined symbol memmove imported in function "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > & __cdecl std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::erase(unsigned __int64,unsigned __int64)" (?erase@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QEAAAEAV12@_K0@Z)
rustllvm.lib(RustWrapper.o) : warning LNK4049: locally defined symbol memmove imported
LLVMX86AsmParser.lib(X86AsmParser.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMX86AsmParser.lib(X86AsmInstrumentation.obj) : warning LNK4049: locally defined symbol memmove imported
LLVMExecutionEngine.lib(ExecutionEngine.obj) : warning LNK4217: locally defined symbol __std_type_info_compare imported in function "public: virtual void * __cdecl std::_Ref_count_del<class llvm::MCJITMemoryManager,struct std::default_delete<class llvm::MCJITMemoryManager> >::_Get_deleter(class type_info const &)const " (?_Get_deleter@?$_Ref_count_del@VMCJITMemoryManager@llvm@@U?$default_delete@VMCJITMemoryManager@llvm@@@std@@@std@@UEBAPEAXAEBVtype_info@@@Z)
LLVMAnalysis.lib(RegionPrinter.obj) : error LNK2019: unresolved external symbol __imp_memchr referenced in function "public: virtual class std::error_condition __cdecl std::_System_error_category::default_error_condition(int)const " (?default_error_condition@_System_error_category@std@@UEBA?AVerror_condition@2@H@Z)
LLVMSupport.lib(SpecialCaseList.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMProfileData.lib(InstrProf.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMProfileData.lib(InstrProfReader.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMAnalysis.lib(CFGPrinter.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMAnalysis.lib(DomPrinter.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMipo.lib(ForceFunctionAttrs.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMAsmParser.lib(LLLexer.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMInstrumentation.lib(DataFlowSanitizer.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMProfileData.lib(SampleProfReader.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMSupport.lib(Regex.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMSupport.lib(DataExtractor.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMSupport.lib(YAMLParser.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMSupport.lib(Signals.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMSupport.lib(SourceMgr.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMSupport.lib(StringRef.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMSupport.lib(CommandLine.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMSupport.lib(ScaledNumber.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMAArch64AsmPrinter.lib(AArch64InstPrinter.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMMC.lib(ELFObjectWriter.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMMC.lib(MCAsmStreamer.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMSupport.lib(Triple.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMAArch64AsmParser.lib(AArch64AsmParser.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMMCParser.lib(AsmParser.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMMCParser.lib(DarwinAsmParser.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMMCParser.lib(ELFAsmParser.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMCore.lib(Constants.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMCore.lib(InlineAsm.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMCore.lib(DataLayout.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMCore.lib(AutoUpgrade.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMAnalysis.lib(ScalarEvolution.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMAnalysis.lib(TargetLibraryInfo.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMAnalysis.lib(ValueTracking.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMCore.lib(AsmWriter.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMObject.lib(Archive.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMObject.lib(MachOObjectFile.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMTransformUtils.lib(SimplifyLibCalls.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMBitReader.lib(BitcodeReader.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMARMAsmParser.lib(ARMAsmParser.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMAsmPrinter.lib(DwarfDebug.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMAsmPrinter.lib(WinCodeViewLineTables.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMTarget.lib(TargetRecip.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMX86AsmParser.lib(X86AsmParser.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMPowerPCAsmParser.lib(PPCAsmParser.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMRuntimeDyld.lib(RuntimeDyldChecker.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMARMCodeGen.lib(ARMAsmPrinter.obj) : error LNK2001: unresolved external symbol __imp_memchr
LLVMAsmPrinter.lib(AsmPrinterInlineAsm.obj) : error LNK2019: unresolved external symbol __imp_strchr referenced in function "void __cdecl EmitGCCInlineAsmStr(char const *,class llvm::MachineInstr const *,class llvm::MachineModuleInfo *,int,int,class llvm::AsmPrinter *,unsigned int,class llvm::raw_ostream &)" (?EmitGCCInlineAsmStr@@YAXPEBDPEBVMachineInstr@llvm@@PEAVMachineModuleInfo@2@HHPEAVAsmPrinter@2@IAEAVraw_ostream@2@@Z)
LLVMSupport.lib(CommandLine.obj) : error LNK2001: unresolved external symbol __imp_strchr
LLVMSupport.lib(Regex.obj) : error LNK2001: unresolved external symbol __imp_strchr
C:\msys64\home\Peter\rust\build\x86_64-pc-windows-msvc\stage1-rustc\x86_64-pc-windows-msvc\release\deps\rustc_llvm-ed2ca56657e2cbf6.dll : fatal error LNK1120: 2 unresolved externals

So your idea is kinda broken.

@retep998
Copy link
Member Author

If I go from the other route and do what I suggested and pass libcmt.lib and /nodefaultlib:msvcrt.lib then I end up with these errors.

error: linking with `link.exe` failed: exit code: 1120
note: "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\amd64\\link.exe" "libcmt.lib" "/NODEFAULTLIB:msvcrt.lib" "/NOLOGO" "/NXCOMPAT" "/LIBPATH:C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\stage1\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\stage1-rustc\\x86_64-pc-windows-msvc\\release\\deps\\flate-564ae00030fab161.0.o" "/OUT:C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\stage1-rustc\\x86_64-pc-windows-msvc\\release\\deps\\flate-564ae00030fab161.dll" "/DEF:C:\\Users\\Peter\\AppData\\Local\\Temp\\rustc.fD2PbDq1pEJb\\lib.def" "C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\stage1-rustc\\x86_64-pc-windows-msvc\\release\\deps\\flate-564ae00030fab161.metadata.o" "/OPT:REF,ICF" "/DEBUG" "/LIBPATH:C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\stage1-rustc\\x86_64-pc-windows-msvc\\release\\deps" "/LIBPATH:C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\stage1-rustc\\x86_64-pc-windows-msvc\\release\\deps" "/LIBPATH:C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\stage1-rustc\\x86_64-pc-windows-msvc\\release\\build\\flate-0738c2cedb0ab516\\out" "/LIBPATH:C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\stage1\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "miniz.lib" "/LIBPATH:C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\stage1\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "std-65a5672b61967d12.dll.lib" "advapi32.lib" "ws2_32.lib" "userenv.lib" "shell32.lib" "msvcrt.lib" "/DLL" "/IMPLIB:C:\\msys64\\home\\Peter\\rust\\build\\x86_64-pc-windows-msvc\\stage1-rustc\\x86_64-pc-windows-msvc\\release\\deps\\flate-564ae00030fab161.dll.lib" "compiler-rt.lib"
note:    Creating library C:\msys64\home\Peter\rust\build\x86_64-pc-windows-msvc\stage1-rustc\x86_64-pc-windows-msvc\release\deps\flate-564ae00030fab161.dll.lib and object C:\msys64\home\Peter\rust\build\x86_64-pc-windows-msvc\stage1-rustc\x86_64-pc-windows-msvc\release\deps\flate-564ae00030fab161.dll.exp
miniz.lib(miniz.o) : warning LNK4217: locally defined symbol free imported in function mz_free
miniz.lib(miniz.o) : error LNK2019: unresolved external symbol __imp_malloc referenced in function tdefl_compress_mem_to_heap
miniz.lib(miniz.o) : error LNK2019: unresolved external symbol __imp_realloc referenced in function tdefl_output_buffer_putter
miniz.lib(miniz.o) : error LNK2019: unresolved external symbol __imp__wassert referenced in function tdefl_compress_buffer
C:\msys64\home\Peter\rust\build\x86_64-pc-windows-msvc\stage1-rustc\x86_64-pc-windows-msvc\release\deps\flate-564ae00030fab161.dll : fatal error LNK1120: 3 unresolved externals

I think it should be fairly obvious by now that getting dllimport right is really important. I am feeling more sympathetic to the multiple target solution because that way we can ensure all the code in the standard library, both Rust and C, was compiled with the correct mode so it uses dllimport correctly. Unfortunately getting Rust to use dllimport correctly is blocked by rust-lang/rust#27438 so until that is fixed adding more targets won't actually solve anything.

@retep998
Copy link
Member Author

Oh, and on a somewhat related note, statically linking the CRT is at odds with Rust dylibs.

When statically linking the CRT, each binary (.dll or .exe) has its own copy of the CRT, with its own state. This means that if you call any CRT function that relies on CRT state you need to make sure you call that function in the correct binary, otherwise you'll be working with the wrong state which is incredibly bad. The problem here is that functions defined in a Rust dylib might not actually run inside that dylib, but rather in another binary, due to inlining and monomorphization. Because which binary a function runs in is indeterminate, it cannot call any CRT function that relies on CRT state, otherwise bad things will occur.

@jan-hudec
Copy link

jan-hudec commented Jul 27, 2016

In MSC++, code compiled with /MT is basically incompatible with code compiled with /MD.
@retep998, adding a target indeed does look like the only workable approach.

Also, the static target probably shouldn't support dynamic libraries at all, because on Windows, linking DLLs against static runtime is fraught with peril. The problem is that Windows can't merge symbols during dynamic linking (ELF-based systems can and do), so each DLL linked with use it's own copy of libc, including its own copy of memory allocator. That can be lived with if it is ensured that any resources are always released from the same library they were acquired, but I am not sure if Rust can ensure it will always be the case. Prohibiting dynamic linking in that target is easier and the static mode does not have that much benefit when other .dlls have to be provided anyway.

This makes the static target for Windows rather similar to the -musl target for Linux.

It also means that adding the target is not blocked by rust-lang/rust#27438 because that target simply never needs to emit dllimport for anything, ever, so the code emitting it can simply be disabled in that target and does not have to be fixed.

The gcc crate will have to be taught to compile all C/C++ dependencies appropriately, but it would have to anyway and the target at least makes it obvious something new is going on.

@retep998
Copy link
Member Author

because that target simply never needs to emit dllimport for anything, ever

No, even when linking to the static CRT you still have to deal with other dependencies that can be dynamically linked (such as all the system libraries, kernel32 user32 advapi32 and so on), and so you still need to be able to apply dllimport correctly. Statically linking the CRT just means you have to make sure you don't emit dllimport for things from the CRT.

The only legitimate use I see for dylib at the moment is for compiler plugins anyway, all other uses are handled by cdylib, so if we make the static CRT target an std only target then we can disable dylib completely without consequence (but leave cdylib because it is still useful).

@Diggsey
Copy link
Contributor

Diggsey commented Jul 27, 2016

@retep998 Are you still compiling with /MD in that first example? As long as no data symbols are imported from the UCRT, it should be possible to compile everything as though it were /MT, but replace libucrt.lib with the ucrt.lib import library by using /NODEFAULTLIB:libucrt.lib.

What you're doing is the reverse (compile as /MD but replace vcruntime.lib with libvcruntime.lib, which won't work because the program itself will expect to dllimport the methods from vcruntime, hence the linker errors for __imp_ symbols, there being no import table in libvcruntime.lib.

@retep998
Copy link
Member Author

@Diggsey I didn't change how any of the code was being compiled, I just passed those linker flags. Right now the entire ecosystem builds code using /MD so I just wanted to see how things would work if we did try to switch to link code using the static CRT without changing how code is compiled otherwise.

@jan-hudec
Copy link

@retep998,

No, even when linking to the static CRT you still have to deal with other dependencies that can be dynamically linked (such as all the system libraries, kernel32 user32 advapi32 and so on)

Ok, it will be slightly more complicated than never generating it, but still simpler than full fix of that bug, because the kernel32.dll, user32.dll & co. are a special cases and are always DLLs, so the symbols from them can be handled by explicit annotation. When they are accessed directly and not through the libc, in which case that takes care of it.

The only legitimate use I see for dylib at the moment is for compiler plugins anyway

There are legitimate uses for other kinds of plugins. But the argument is that when you have dylibs, you don't have a single self-contained binary any more anyway, so the main advantage of the static target is gone.

but leave cdylib because it is still useful

I think initially even those could be disabled. Most DLL plugins need to be compiled against dynamic runtime of the same version as the application that loads them anyway. The main exception that comes to mind is COM modules where the interface does ensure resources are local to each component, but I don't think that can be distributed without installer, so the benefit is not so big there either.

@retep998
Copy link
Member Author

retep998 commented Jul 27, 2016

@jan-hudec It is perfectly acceptable for a DLL to use the static CRT as long as it doesn't share any CRT objects across the DLL boundary. So a cdylib is perfectly capable of encapsulating any usage of the CRT and thus being entirely safe.

There are legitimate uses for other kinds of plugins.

But dylib should not be used for other kinds of plugins. Whenever you want to create a DLL to be dynamically loaded by some application, you almost always want cdylib.

Ok, it will be slightly more complicated than never generating it, but still simpler than full fix of that bug, because the kernel32.dll, user32.dll & co. are a special cases and are always DLLs, so the symbols from them can be handled by explicit annotation.

We don't have any sort of annotation to say whether to apply dllimport at the moment, which is basically the issue. Also don't forget about linking third party C libraries, especially when the user has to provide them so they could be either static or dynamic and Rust has no idea which it is unless the user tells Rust somehow.

When they are accessed directly and not through the libc, in which case that takes care of it.

We don't access any system stuff through libc anyway, we only rely on the CRT for math functions and a few memory functions like memcpy.

The main exception that comes to mind is COM modules where the interface does ensure resources are local to each component, but I don't think that can be distributed without installer, so the benefit is not so big there either.

I have absolutely no idea what you mean by this. I fail to see how COM is relevant to using the CRT, nor how installers are required for COM.

@Diggsey
Copy link
Contributor

Diggsey commented Jul 27, 2016

There are legitimate uses for dylib, but most of them are impractical until rust gets at least a partially stable ABI, so I'd also be happy just to disable it for now. cdylib on the other hand is a must have!

@ahicks92
Copy link

I think this is starting to highlight a deficiency in Cargo: there is no convenient way to arrange for the distribution of all needed dlls. I can't put them anywhere special, build.rs can't tell Cargo about them, etc. It's possible I'm missing something, admittedly. That said, I think a similar problem applies to data for games and the like. The solution is therefore probably more general.

@jan-hudec
Any plugin interface which requires passing CRT objects across the DLL boundary is, in my opinion, a bad plugin interface. You don't have enough control on Windows to know what runtimes the DLLs will expect, so the only practical way to do it is to mandate that plugin devs write their plugins with a specific runtime and tool. This eliminates all sorts of niche languages, not to mention simpler stuff like developing a plugin in MinGW for an app that used MSVC.

Basically, the problem is that such a design mandates using MSVC because you need the runtime to manipulate things the app sends you, so forget anything that doesn't use it.

I also use static linking of the runtime into DLLs and careful interface design to let my VC++2015 project be safely called by ctypes from Python 2.7 without requiring users to install additional runtimes. In that case, being static or not actually doesn't matter because there's still a version mismatch, so you have to apply the same considerations anyway. My plan was to apply the same approach to my first Rust project.

Disabling cdylib would make me very sad, while also locking my current Rust project to MinGW.

@vadimcn
Copy link
Contributor

vadimcn commented Jul 28, 2016

@retep998: FWIW, here's a change to link vcruntime statically. Don't know if this is the most elegant way, but at least stuff works.

@retep998
Copy link
Member Author

retep998 commented Jul 28, 2016

@vadimcn That basically breaks support for older versions of MSVC before the transition to ucrt and vcruntime. You'd need to do it based on the version of MSVC. Also that doesn't fix anything for other compiled C/C++ stuff, only how stuff inside Rust is built with cmake, and even then only when using the old configure system.

@vadimcn
Copy link
Contributor

vadimcn commented Jul 28, 2016

You'd need to do it based on the version of MSVC.

Yep, that's the deal.

Also that doesn't fix anything for other compiled C/C++ stuff,

gcc crate could to the same.

and even then only when using the old configure system.

What's preventing us from porting this to rustbuild?


But I agree, this is a pretty fragile approach for not that much benefit over just compiling everything for static linkage and letting the linker fix things up.

@alexcrichton
Copy link
Member

@brson and I have opened an alternative RFC to this which emphasizes environment variables less and focuses on cross-platform support to handle musl as well.

@alexcrichton
Copy link
Member

@rfcbot fcp close

I've proposed moving #1721 into FCP for merging, and as a result I think this RFC is also ready for closing (as #1721 subsumes it)

@rfcbot
Copy link
Collaborator

rfcbot commented Oct 5, 2016

Team member alexcrichton has proposed to close this. The next step is review by the rest of the tagged teams:

No concerns currently listed.
Once these reviewers reach consensus, this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@vadimcn
Copy link
Contributor

vadimcn commented Oct 11, 2016

@rfcbot reviewed

1 similar comment
@michaelwoerister
Copy link
Member

@rfcbot reviewed

@rfcbot
Copy link
Collaborator

rfcbot commented Oct 17, 2016

All relevant subteam members have reviewed. No concerns remain.

@alexcrichton
Copy link
Member

🔔 This RFC is now entering its week-long final comment period for closing 🔔

@alexcrichton alexcrichton added the final-comment-period Will be merged/postponed/closed in ~10 calendar days unless new substational objections are raised. label Oct 18, 2016
@rfcbot
Copy link
Collaborator

rfcbot commented Oct 24, 2016

It has been one week since all blocks to the FCP were resolved.

@alexcrichton
Copy link
Member

Ok! Looks like no new information was brought up, so I'm going to close this in favor of #1721 which is also in FCP. Thanks again for the RFC @retep998!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
final-comment-period Will be merged/postponed/closed in ~10 calendar days unless new substational objections are raised. T-dev-tools Relevant to the development tools team, which will review and decide on the RFC.
Projects
None yet
Development

Successfully merging this pull request may close these issues.