gtk-rs / gtk3-rs

Rust bindings for GTK 3
https://gtk-rs.org
MIT License
508 stars 90 forks source link

gtk-rs on Windows with MSVC should be possible with zero attrition #116

Open fungos opened 6 years ago

fungos commented 6 years ago

note: I'm not sure if the best place is here or at sys repository, but as any user looking for gtk-rs on windows will tend to land here, I'm opening this issue here.

This is more of a distribution problem, but may be extremely beneficial for Rust GUI situation.

As it stands, gtk-rs is buildable on Windows using MSVC toolchain, but this does not mean it is usable without additional steps, as an application trying to link with GTK will still need all the GTK libraries previously downloaded (or worse, separately built) and well configured.

The ideal would have to be any application using gtk-rs and being compiled on windows using the MSVC toolchain, to have these libraries (downloaded or compiled) and configuration done by cargo itself (via plugin or build.rs in *-sys crates).

One way to achieve this, would be by abusing or mimicking the "cc" and "cmake" crates. This could be best achieved by using vcpkg-rs. Although vcpkg itself has some issues[1] with GTK port, it builds flawlessly and this can be used as a mean of distribution for dependencies when using MSVC toolchain.

Further improvement can be collaborated with vcpkg-rs

[1] The first issue is that vcpkg GTK port outputs "gtk-3.0.lib" and "gdk-3.0.lib" while gtk-rs expects "gtk-3.lib" and "gtk-3.lib". The second issue is that gtk-rs expects some debug features to be enabled on the libraries, for this I've opened this issue/PR there.

GuillaumeGomez commented 6 years ago

note: I'm not sure if the best place is here or at sys repository, but as any user looking for gtk-rs on windows will tend to land here, I'm opening this issue here.

Here is fine.

...

I agree that windows support isn't great. Any improvement on this side would be very appreciated!

sdroege commented 6 years ago

I wouldn't suggest using the vcpkg packages as they have a custom build system different from upstream and last I checked it compiled but didn't work. Writing a custom CMake build system around these projects is not trivial and requires considerable maintenance effort.

GTK and all (?) its dependencies now have support for meson, which can either build via ninja with the MSVC toolchain or output VS solution files that can be built with msbuild.exe.

As that is supported and maintained by the GTK project, I would suggest going down that road instead.


Also all this should be optional in the -sys crates to allow people using their own binaries as they wish and do now already. E.g. it would be a problem if glib-sys would download a new glib binary when used together with the GStreamer binaries as those already ship a suitable version of glib.


And last, this is not limited to the MSVC toolchain but generally on Windows (and you can use mingw GTK in an MSVC application and the other way around).

fungos commented 6 years ago

I tried it recently and it builds and seems to work up-to where I was able to test (all relm examples except webkit).

I agree with using an alternate build system is not ideal, but meson is far away in the "standard" build system than CMake, and vcpkg is growing in a fast pacing way as the solution to the C dependencies issues on Windows (even more in corporate settings).

Also, requiring a Rust user to install meson as a pre-step is against the concept of zero attrition[2] - CMake is already included in Visual Studio 2017 (as is ninja), and Rust CMake support is very well known and accepted already.

With the objective of achieving friction-less gtk-rs support on Windows, CMake is in a way better spot.


Kind of. The defaults should always be effort less.

It should be a safe automatic fallback when using MSVC toolchain. If someone wants their own specific libs, they presumably knows what and how to configure it, then opting-in is a no brainer.

On a Unix setting this is not an issue, but we all know the sad state of Windows for C development.


No, not limited but this is where the audience is most neglected.

Depending on more stuff (mingw) when developing MSVC is generally not well regarded, so being able to use mingw with MSVC is unrelated to this issue.


The point of the issue here is simply:

Native[1] effort-less[2] support to the MSVC toolchain

[1] native: full msvc toolchain without mingw [2] effort-less: no manual work to acquire (and buid) dependencies and tooling is required other than the default rust setup on Windows with MSVC toolchain.

sdroege commented 6 years ago

Can you confirm that the vcpkg cmake build actually work, or just builds fine? I'm worried about 1) it working suboptimal due to incorrect build, 2) becoming outdated because nobody cares to maintain and keep the build system up to date.

meson is going to become the default and only build system of upstream GTK and is already of quite a few of its dependencies, and it builds things fine on Windows and with MSVC. Apart from ninja and Python 3 it doesn't really need anything (and Python 3 is required for building GTK anyway for various build scripts like glib-mkenums).

It would also make sense on the vcpkg side to not use cmake here but meson to build the ninja.build for gtk and dependencies unless they have too much time and really want to maintain another build system for all these libraries themselves.


I agree that the defaults should be effort-less, but I don't want this to conflict with other software. In the case of GStreamer, people already have GLib, Pango, etc. available via GStreamer and requiring another step from them to opt-out of vcpkg would be a problem. Making things easier for one group of people while making it harder for others is not really a good solution.


I only mentioned mingw here because people using the Rust mingw toolchain probably also want to have gtk easily available, and they could also use MSVC-built binaries. Would be nice to also make their life easier.

ras0219-msft commented 6 years ago

Hi, vcpkg developer here!

@sdroege We definitely recognize how important GTK is as a library and are motivated to keep it maintained and working :). While we do have an alternate buildsystem for now that is more compatible across all platforms with how we build its dependencies, we definitely are interested in improving meson support in the future and would love to converge on the upstream build!

Currently, the main problem is weak pkgconfig support due to its lack of use on Windows, but we'd like to improve that in the future (several users have indicated that it's possible to fix this).

Note that when we support Meson, we'll definitely be doing it in a zero attrition way, the same as we handle other dependencies such as CMake, etc.

nirbheek commented 6 years ago

Hi @ras0219-msft, I'm a Meson developer and we'd be happy to assist you in setting up Meson for vcpkg, and any issues you have with pkg-config support. Could you expand on that?

Like @sdroege said Meson is meant to be easy to use on all platforms: our only dependencies are Python 3.5+ and Ninja and we have extensive CI for Windows.

The installation is: pip3 install meson (you will probably want to start with the 0.47 stable branch which uses setuptools to install an executable wrapper on Windows till 0.48 is released). I know that VS ships with Python 3 and Ninja already so it should not require an onerous amount of work to support Meson.

We've been wanting native support for building of Meson projects in vcpkg and Visual Studio so that developers have the same experience on Windows that they do on Linux and macOS. I even gave a talk about this at the annual GNOME conference this year: https://www.youtube.com/watch?v=mmPSWQ3p-WI

Note that all GNOME libraries are moving to Meson, so it will greatly reduce your workload to build them with Meson.

ras0219-msft commented 6 years ago

@nirbheek Awesome! To avoid gunking up a rust issue tracker with something semi-unrelated, would you mind mailing us at vcpkg@microsoft.com?

We have the beginnings of a standard helper at [1] which is used to build libepoxy, but it needs a lot more love from someone familiar with meson.

[1] https://github.com/Microsoft/vcpkg/blob/master/scripts/cmake/vcpkg_configure_meson.cmake

nirbheek commented 6 years ago

@nirbheek Awesome! To avoid gunking up a rust issue tracker with something semi-unrelated, would you mind mailing us at vcpkg@microsoft.com?

Done! Let's carry it forward on email.

sdroege commented 6 years ago

Considering that it seems like vcpkg would be a good option for Windows if MSVC is available and the libraries are not found via pkg-config directly.

LordZane commented 6 years ago

Somewhat unrelated, but working on a gtk-rs project (on windows) using msys2 works fine when I build the app. Trying to distribute it does not, with libgdk_pixbuff dll causing a crash. Maybe a more isolated from-scratch gtk build could fix this? And what about static linking of gtk libs? Not having to distribute a zip of 1 exe, and like 15 dll's would be nice

fungos commented 5 years ago

https://github.com/Microsoft/vcpkg/issues/4212 is merged, a default vcpkg build should be compatible with gtk-rs now.

kykc commented 5 years ago

For anyone interested, I was able to hack minimal project using gtk-rs/vcpkg which is buildable with *-pc-msvc targets on Windows: repo

It was almost straightforward, but a few hacks was still needed to get it to work, see Makefile.toml and build.rs for details.

EPashkin commented 5 years ago

@fungos, @daxpedda Sorry, but we decide in https://github.com/gtk-rs/sys/pull/126 not add vcpkg support in next release,

AregevDev commented 5 years ago

Any news about MSVC support? You released a new version recently (nice work BTW)

nirbheek commented 5 years ago

I'm working on building gtk+ 3 on Windows with Meson and MSVC.

One part of that is already complete and I'm generating gtk+ and gstreamer using Cerbero, and this tarball was the result of that. This is necessary if someone wants to, f.ex., build an app that uses gstreamer-rs on Windows. It contains gtk+ 3.22, but it should work. You can try that for now.

I'm in the process of updating the build files to gtk+ 3.24 and merging that upstream (it's already upstream for gtk4).

Eventually I want this to all work without requiring something like Cerbero. This is already possible for gstreamer, but not for gtk yet.

sdroege commented 5 years ago

Any news about MSVC support?

What's missing for MSVC btw? It's working fine with gtk-rs as long as you get working GTK binaries from somewhere. That's how @GuillaumeGomez and I did the RustFest workshop in Rome last year, code can be found here. It's using @nirbheek's GTK binaries.

w1th0utnam3 commented 5 years ago

First of all, thanks for your work on this project.

What's missing for MSVC btw?

Some prominent documentation of the required steps would be nice. Just to make it clear for anyone who stumbles on this from Google, the following steps worked for me:

  1. Download @nirbheek binaries (gtk + gstreamer): https://nirbheek.in/files/binaries/gstreamer/1.15.0.1/gtk/windows/gstreamer-1.0-windows-msvc-x86_64-1.15.0.1.tar.bz2
  2. Add the lib directory to the LIB environment variable (otherwise LINK.exe wouldn't find the .lib files)
  3. Add the bin directory to the PATH environment variable.

Any updates on building more recent versions of GTK that are compatible with gtk-rs?

AregevDev commented 5 years ago

Is it possible to use a static version of GTK libraries? I remember using it in Windows and it required a bunch of DLLs for a simple program

ketsuban commented 5 years ago

With all due deference to @nirbheek I'd prefer something a little more official for GTK binaries, so here's the adventure I went on. I'm on Windows 10, I have the Visual Studio 2019 build tools installed, and I have the current stable build of Rust (rustc 1.35.0 (3c235d560 2019-05-20)) installed through rustup.

  1. Install GTK3 using vcpkg following the instructions on the GTK website. I'll refer to its directory as %VCPKGDIR%.
  2. Add %VCPKGDIR%\installed\x64-windows\bin to the PATH environment variable.
  3. Set the GTK_LIB_DIR environment variable to %VCPKGDIR%\installed\x64-windows\lib.
  4. Create some symlinks.
    • %VCPKGDIR%\installed\x64-windows\lib\gtk-3.0.lib points to %VCPKGDIR%\installed\x64-windows\lib\gtk-3.lib.
    • %VCPKGDIR%\installed\x64-windows\lib\gdk-3.0.lib points to %VCPKGDIR%\installed\x64-windows\lib\gdk-3.0.lib.
    • %VCPKGDIR%\installed\x64-windows\bin\gtk-3.0.dll points to %VCPKGDIR%\installed\x64-windows\bin\gtk-3.dll.
    • %VCPKGDIR%\installed\x64-windows\bin\gdk-3.0.dll points to %VCPKGDIR%\installed\x64-windows\bin\gdk-3.dll.
  5. Set up a Rust binary crate using GTK and try to build it.
  6. error LNK2019: unresolved external symbol gtk_font_chooser_level_get_type referenced in function _ZN78_$LT$gtk..auto..flags..FontChooserLevel$u20$as$u20$glib..types..StaticType$GT$11static_type17h551b8861bdc92772E.

As best I can tell the problem here is that the level property of GtkFontChooser has a minimum version of 3.22.30, and the function gtk_font_chooser_level_get_type has a minimum version of 3.24, but vcpkg currently provides 3.22.19.

edit: Probably worth mentioning this isn't specifically a MSVC problem - it happens to -gnu users as well, but it was "resolved" by updating to GTK 3.24. gtk-rs provides version features for multiple iterations of GTK, so I infer that it's supposed to be compatible with them; this is a bug, since it prevents people using gtk-rs with versions of GTK prior to at least 3.22.30.

EPashkin commented 5 years ago

@ketsuban we fixed that in git version https://github.com/gtk-rs/gtk/pull/804, package release still in progress.

ketsuban commented 5 years ago

@EPashkin Ah, okay, thanks. I tried using gtk-rs straight from Git (it required a small change to my call to Application::new) and, um...

error: process didn't exit successfully: target\debug\gtktest.exe (exit code: 0xc0000139, STATUS_ENTRYPOINT_NOT_FOUND)

EPashkin commented 5 years ago

Try cargo clean and rm Cargo.lock If this not help, then http://www.dependencywalker.com/ can help in search for missing entry point.

ketsuban commented 5 years ago

Turned out there was a zlib1.dll earlier on my PATH which was causing the problem - once I fixed that the executable ran without a hitch.

sdroege commented 5 years ago

I saw you pasted these instructions also at https://www.reddit.com/r/rust/comments/bzkhmt/how_to_use_gtkrs_on_windows_using_the_msvc/

Want to send a PR to add this to the website? :)

Personally I'm always using MSVC with gtk-rs on Windows, unless I have to test something with mingw. It's known to work and much better for debugging on this awful development platform.

nyanpasu64 commented 5 years ago

I got 0xc0000139 when running from CLion, and a working window when running from cargo run from CLI, or Windows Explorer.

sdroege commented 5 years ago

I got 0xc0000139 when running from CLion, and a working window when running from cargo run from CLI, or Windows Explorer.

This has nothing to do with this issue. Please create a new one with more details

XVilka commented 4 years ago

Should be MSVC 2019 build then added in the AppVeyor configuration?

sdroege commented 4 years ago

Should be MSVC 2019 build then added in the AppVeyor configuration?

Sounds good, do you want to create a PR for that?

fungos commented 4 years ago

I did a little proof-of-concept on a thing that can help with this issue and I truly believe this is the way forward (at least on Windows), take a look at AutoVcpkg.

I'm still unsure as how to make this go forward within gtk-rs and there are a few things to work on it. But it may be something to use with the core gtk-rs crate in a way that any dependent crate can automatically take advantage, making gtk on windows and osx as easy as on linux.

As a PoC usage, I tried it on relm and from a possible relm user's PoV who just wants give a quick try on a machine without any trace of gtk itself, doing this:

c:\rust\relm> cargo run --example button

Simply works.

No instructions to follow on how to install gtk required.

See here: relm example

There are still some things about missing pixmaps, that will require some work on, but this may be at least something to get the discussion back on what is the best direction forward.

sdroege commented 4 years ago

There are still some things about missing pixmaps, that will require some work on, but this may be at least something to get the discussion back on what is the best direction forward.

Before anybody builds something with GTK from vcpkg, it would be best if some time would be spent on making the GTK vcpkg package actually complete and working. The missing icons and other resources are one long-known problem with the packaging over there.

windelbouwman commented 4 years ago

Is there any news on this topic? I managed to build an application on windows with vcpkg, visual studio and rust for windows. The icons are missing, but apart from that, the application works.

martinlindhe commented 4 years ago

@windelbouwman I think the missing icons issue with vcpkg is tracked here: https://github.com/microsoft/vcpkg/issues/6554

sdroege commented 4 years ago

You might want to check https://www.gtk.org/docs/installations/windows/ . That has all the details for how to get GTK on Windows running.