Standalone 32bit Windows App using MSVC?


#1

Hi folks,

is there any documentation on how to build a standalone Win32 app through MSVC?

Current issues I have:

  • When I rename the binary it crashes while reading the registry. I’ll try to work out a case to reproduce it but it’s really extremely weird…
  • When I run it on XP it says that this is not a valid XP application. My shallow knowledge is that this can be fixed by passing “some flags” to MSVC
  • When I run it there’s always a console window showing. Needs another flag passed to MSVC
  • When I run it on a box without Visual Studio installed, I used to get an error dialog complaining about some runtime dll missing. (will try to reproduce it, is currently shadowed by missing OpenSSL DLL errors that I’ll try to work on). Is this the missing piece of “Completely remove the dependence on the CRT” on this issue? https://github.com/rust-lang/rfcs/issues/1061
  • What’s the convention to put resource files? It’s not mentioned here http://doc.crates.io/guide.html#project-layout

So… what’s the best way to pass linker ops to MSVC? And what is the best place to document how to build a proper windows app?

Thanks in advance for your insights!

Cheers,
Kosta


[Solved] Build ripgrep for Windows XP with static linking
#2
  • Renaming binaries causing crashes? I’d need a lot more info to know what is going on.
  • Pass /SUBSYSTEM:CONSOLE,5.01 for 32-bit or /SUBSYSTEM:CONSOLE,5.02 for 64-bit as a flag to the linker. This would involve cargo rustc -- -Clink-args="things in here".
  • Pass /SUBSYSTEM:WINDOWS to the linker.
  • Since it relies on the VC++ redistributable, that means you need to have that redistributable installed on any machine you want to run the program on. Removing the dependence on the CRT would be an alternative but would only work for pure Rust software which doesn’t statically link any C/C++ libraries. It may also be possible to have it statically link the CRT but Rust isn’t quite flexible enough to do that yet.
  • Rust/Cargo do not automatically handle resource files. If you want to get resource files linked in you’ll have to use cargo rustc to get them manually passed to the linker.

#3

Thanks @retep998 for you quick reply! (And sorry for my slooow reply - maybe I shouldn’t raise such issues before going on a long weekend…)

  • The “crash on rename” seems just to be a typical case of “undefined behaviour behaving weirdly”. I’ll double-check all unsafe blocks.
  • Passing /SUBSYSTEM:CONSOLE,5.01 seems to work
  • Passgin /SUBSYSTEM:WINDOWS seems to work, if you also pass /ENTRY:mainCRTStartup. Otherwise, the linker complains about not finding _WinMain@16 as it doesn’t consider “main” function as starting point.
  • Relying on the CRT distributable being installed is a no-go for me, as I’m basically writing a “portable” app. It’s one of the hard requirements… But it’s good to know that this doesn’t work yet. I’ll just have to wait for this to work and sue use windows-gcc for now. In my “other” win32 thread, there’s instructions on how to statically link the minimal gcc runtime required.
  • Ok, as I already need custom linker args anyway, it should be fine to just link them the same way when needed…

But one big question is still remaining: What is the best place to document this? I think every windows dev searching the forums is a bit… inefficient. There does not seem to be a rust wiki. If I have the time, I might write this all up with an example project on github to document it. If you can think of a better way, please let me know!

Again, thanks for your very insightful reply!

Cheers,
Kosta


#4

You can actually link the CRT statically if you invoke the linker completely manually. Just don’t pass msvcrt.lib and instead pass libcmt.lib (or libvcruntime.lib and libucrt.lib if you’re using the universal CRT).

If you don’t need to link to any C/C++ code/libraries (aside from system libraries), then you can even use your own custom entry point thereby saving space on the CRT entry point and initialization gunk.