We're hiring!
*

Build and run GTK 4 applications with Visual Studio

Xavier Claessens avatar

Xavier Claessens
March 18, 2021

Share this post:

Over the past few months, I've been working on a side project to improve Meson sub-project support. The best stress test is to build projects on Windows, without msys2, because it has no dependencies or tools installed (e.g. pkg-config). Meson has to build everything itself from scratch.

Here are step-by-step instructions, starting from a fresh Windows 10 installation, on how to run a gtk4-demo application.

Install Visual Studio

Download from https://visualstudio.microsoft.com/vs/community. Make sure to check the box "Desktop development with C++".

Collabora - Installing Visual Studio

Install Python >= 3.6

Download from https://www.python.org/downloads. Make sure to check the box "Add python to PATH".

Collabora - Installing Python

Install Git for Windows

Download from https://gitforwindows.org. It asks many questions, however the default is always good enough, so next, next, next...

Collabora - Installing Git for Windows

Open developer terminal

From the Windows start menu, search for x64 Native Tools Command Prompt for VS 2019. That will open a terminal configured to use MSVC x64 tools.

Collabora - Visual Studio Developer Command Prompt

First let's create a directory where we'll fetch the source code:

mkdir C:\src
cd C:\src

Let's also configure git:

git config --global user.email "xavier.claessens@collabora.com"
git config --global user.name "Xavier Claessens"

Install Meson

Installing the latest release of Meson (requires >=0.57.0) can be done with a simple command:

C:\src>pip install meson

Fetch GTK4 source

Fetch gtk from git:

C:\src>git clone https://gitlab.gnome.org/GNOME/gtk.git
C:\src>cd gtk

At the time of writing !3135 is not yet merged, so we need to use my branch:

(Update March 22: This has now been merged so my branch is no longer needed.)

C:\src\gtk>git fetch https://gitlab.gnome.org/xclaesse/gtk.git meson-install-script
C:\src\gtk>git checkout -b meson-install-script FETCH_HEAD

Build GTK4 with all its dependencies

During the GTK4 configuration, Meson will download and configure all dependencies. Great efforts have been made across all dependencies to make them work out of the box on Windows.

C:\src\gtk>meson setup build --prefix C:/gnome
C:\src\gtk>meson compile -C build
C:\src\gtk>meson install -C build

Collabora - GTK4 configuration

Run gtk4-demo

That's all, you can now run demo applications!

C:\src\gtk>C:\gnome\bin\gtk4-demo.exe

Collabora - Running gtk4-demo.exe

It works out of the box on my VirtualBox machine, however on my physical PC with an intel GPU, I get a crash at startup:

Unhandled exception at 0x5211345E (ig4icd32.dll) in gtk4-demo.exe: 0xC0000005: Access violation reading location 0x00000050

This can be worked around by using cairo rendering:

C:\src\gtk>set GSK_RENDERER=cairo
C:\src\gtk>C:\gnome\bin\gtk4-demo.exe

Debug in Visual Studio

Since this is a complete build using MSVC, it is also fully debuggable.

  • Open Visual Studio
  • Click "Open a project or solution"
  • Browse to C:\gnome\bin\gtk4-demo.exe
  • Click "Start" button

If you break execution, or hit a crash, it will open the source code and you can debug step by step, see the value of any variable, whether it is in gtk or in any of its dependencies.

Debugging in Visual Studio.

What's next?

Here's a list of some of the items I would like to eventually look into:

  • See if we can use GTK4 as sub-project of a real application. Which applications do we have that are ported to GTK4 already and runs on Windows? Gedit?
  • Add GStreamer gst-build as a sub-project of GTK4 to build the media player? This would probably lead to a world record of number of Meson subprojects built at once.
  • Add Windows CI to GTK4?

As usual, if you have any questions about GTK4 or GStreamer on Windows, or any other platform, please contact us!

Comments (9)

  1. Lindomar:
    Mar 19, 2021 at 07:23 PM

    Is it possible to use GTK4 in Python 3.9 on Windows?

    Reply to this comment

    Reply to this comment

    1. Xavier Claessens:
      Mar 22, 2021 at 12:38 PM

      With this tutorial it is not building gobject-introspection bindings. It should be possible to add g-i as a subproject and set GI_TYPELIB_PATH but I haven't tried it yet.

      Reply to this comment

      Reply to this comment

  2. Christian Ohrfandl:
    Mar 20, 2021 at 12:12 AM

    Hi,

    thank you for the tutorial!

    However, I face the following issues when running the command "meson compile -C build" (multiple times):

    FAILED: subprojects/freetype2/freetype-6.dll.p/src_gzip_ftgzip.c.obj
    "cl" "-Isubprojects\freetype2\freetype-6.dll.p" "-Isubprojects\freetype2" "-I..\subprojects\freetype2" "-I..\subprojects\freetype2\include" "-IC:/dev/StrawberryPerl/c/lib/pkgconfig/../../include/libpng16" "/MD" "/nologo" "/showIncludes" "/W2" "/O2" "/Zi" "-DFT2_BUILD_LIBRARY" "-DFT_CONFIG_CONFIG_H=" "-DFT_CONFIG_OPTIONS_H=" "-DDLL_EXPORT" "-D_CRT_SECURE_NO_WARNINGS" "-D_CRT_NONSTDC_NO_WARNINGS" "/Fdsubprojects\freetype2\freetype-6.dll.p\src_gzip_ftgzip.c.pdb" /Fosubprojects/freetype2/freetype-6.dll.p/src_gzip_ftgzip.c.obj "/c" ../subprojects/freetype2/src/gzip/ftgzip.c
    ../subprojects/freetype2/src/gzip/ftgzip.c(46): fatal error C1083: Datei (Include) kann nicht geöffnet werden: "zlib.h": No such file or directory
    [93/3580] Compiling C object subprojects/freetype2/freetype-6.dll.p/src_psaux_psaux.c.obj
    ninja: build stopped: subcommand failed.

    FAILED: subprojects/freetype2/freetype-6.dll.p/src_gzip_ftgzip.c.obj
    "cl" "-Isubprojects\freetype2\freetype-6.dll.p" "-Isubprojects\freetype2" "-I..\subprojects\freetype2" "-I..\subprojects\freetype2\include" "-IC:/dev/StrawberryPerl/c/lib/pkgconfig/../../include/libpng16" "/MD" "/nologo" "/showIncludes" "/W2" "/O2" "/Zi" "-DFT2_BUILD_LIBRARY" "-DFT_CONFIG_CONFIG_H=" "-DFT_CONFIG_OPTIONS_H=" "-DDLL_EXPORT" "-D_CRT_SECURE_NO_WARNINGS" "-D_CRT_NONSTDC_NO_WARNINGS" "/Fdsubprojects\freetype2\freetype-6.dll.p\src_gzip_ftgzip.c.pdb" /Fosubprojects/freetype2/freetype-6.dll.p/src_gzip_ftgzip.c.obj "/c" ../subprojects/freetype2/src/gzip/ftgzip.c
    ../subprojects/freetype2/src/gzip/ftgzip.c(46): fatal error C1083: Datei (Include) kann nicht geöffnet werden: "zlib.h": No such file or directory

    FAILED: subprojects/glib/gobject/gobject-2.0-0.dll.p/gclosure.c.obj
    "cl" "-Isubprojects\glib\gobject\gobject-2.0-0.dll.p" "-Isubprojects\glib\gobject" "-I..\subprojects\glib\gobject" "-Isubprojects\glib" "-I..\subprojects\glib" "-Isubprojects\glib\glib" "-I..\subprojects\glib\glib" "-Isubprojects\proxy-libintl" "-I..\subprojects\proxy-libintl" "/MD" "/nologo" "/showIncludes" "/W2" "/O2" "/Zi" "/wd4035" "/wd4715" "/wd4116" "/wd4046" "/wd4068" "/wo4090" "/FImsvc_recommended_pragmas.h" "/utf-8" "-D_GNU_SOURCE" "-DG_ENABLE_DEBUG" "-DG_LOG_DOMAIN=\"GLib-GObject\"" "-DGOBJECT_COMPILATION" "/Fdsubprojects\glib\gobject\gobject-2.0-0.dll.p\gclosure.c.pdb" /Fosubprojects/glib/gobject/gobject-2.0-0.dll.p/gclosure.c.obj "/c" ../subprojects/glib/gobject/gclosure.c
    ../subprojects/glib/gobject/gclosure.c(28): fatal error C1083: Datei (Include) kann nicht geöffnet werden: "ffi.h": No such file or directory

    It is interesting though, e.g. zlib.h is located in the place where it should reside. However, ffi.h is not there...

    Anyway, here you can find the whole log from compilation: https://pastebin.com/T0QRUZya

    Do you have any suggestions?

    Cheers,
    Christian

    Reply to this comment

    Reply to this comment

    1. LINDOMAR BEGA:
      Mar 20, 2021 at 01:00 AM

      The tutorial works perfectly, but no commands can be left. I had a problem compiling twice and since I was not an expert I remade everything.

      Reply to this comment

      Reply to this comment

    2. Xavier Claessens:
      Mar 22, 2021 at 12:43 PM

      Check your logs to see if it has setup zlib subproject, or if it found it on your system somewhere. Could you attach your /meson-logs/meson-logs.txt for more info, please?

      Reply to this comment

      Reply to this comment

      1. Frank:
        Jun 23, 2021 at 10:29 AM

        Hello and thanks for your very helpfull tutorial!

        I've got an equal issue with subprojects/glib/gobject/gobject-2.0-0.dll.p:
        ../subprojects/glib/gobject/gclosure.c(28): fatal error C1083: Datei (Include) kann nicht geöffnet werden: "ffi.h"

        Maybe its a conflict with pkg-config:

        Run-time dependency libffi found: YES 3.3-rc0
        Pkg-config binary for MachineChoice.HOST is cached.
        Determining dependency 'zlib' with pkg-config executable 'N:\\prog\\Perl64\\perl\\bin\\pkg-config.BAT'
        env[PKG_CONFIG_PATH]:
        Called `N:\prog\Perl64\perl\bin\pkg-config.BAT --modversion zlib` -> 0
        1.2.11
        env[PKG_CONFIG_PATH]:
        Called `N:\prog\Perl64\perl\bin\pkg-config.BAT --cflags zlib` -> 0

        env[PKG_CONFIG_ALLOW_SYSTEM_LIBS]: 1
        env[PKG_CONFIG_PATH]:
        Called `N:\prog\Perl64\perl\bin\pkg-config.BAT --libs zlib` -> 0
        -LN:/prog/Perl64/c/lib/pkgconfig/../../lib -lz
        env[PKG_CONFIG_PATH]:
        Called `N:\prog\Perl64\perl\bin\pkg-config.BAT --libs zlib` -> 0
        -lz
        Run-time dependency zlib found: YES 1.2.11
        Running compile:
        Working directory: N:\data\src\build\meson-private\tmpgj8j6uyd
        Command line: cl N:\data\src\build\meson-private\tmpgj8j6uyd\testfile.c /FeF:\Daten\gtk4\src\gtk\build\meson-private\tmpgj8j6uyd\output.exe /nologo /showIncludes /MD /nologo /showIncludes /Od kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib

        Reply to this comment

        Reply to this comment

  3. Giulio:
    Jun 28, 2021 at 09:43 AM

    Below you find the procedure to install GTK4 on Windows via MSYS2 without building it from source.

    https://stackoverflow.com/a/68150140/11323942

    Reply to this comment

    Reply to this comment

  4. Valaist:
    Jul 19, 2021 at 04:04 PM

    Thanks for the tutorial. It seems there is an issue with the created "gspawn-win64-helper(-console).exe" which is used by the Vala compiler and possibly other mechanisms.

    On my machine, it always errors with

    GLib:ERROR:C:\vcpkg\buildtrees\glib\src\2.52.3-9cb1890713.clean\glib\gspawn-win32.c:378:set_child_error: code should not be reached

    Do you have an idea why?

    Reply to this comment

    Reply to this comment

  5. Carlo:
    Jul 19, 2021 at 07:40 PM

    Hello,

    Thanks for the tutorial! I had one issue with the C:\TDM-GCC-32, some library was missing. I ended up downloading it and included some more stuff. Then this ended up working but now I have the following issue:

    Compiler stderr:
    C:\src\gtk\build\meson-private\tmp9nbyjbky\testfile.c: In function 'main':
    C:\src\gtk\build\meson-private\tmp9nbyjbky\testfile.c:12:14: error: #error "No definition for __builtin__aligned_malloc found in the prefix"
    #error "No definition for __builtin__aligned_malloc found in the prefix"
    ^
    C:\src\gtk\build\meson-private\tmp9nbyjbky\testfile.c:20:13: error: '__builtin__aligned_malloc' undeclared (first use in this function)
    __builtin__aligned_malloc;
    ^
    C:\src\gtk\build\meson-private\tmp9nbyjbky\testfile.c:20:13: note: each undeclared identifier is reported only once for each function it appears in

    Checking for function "_aligned_malloc" : NO
    Running compile:
    Working directory: C:\src\gtk\build\meson-private\tmpdup4zcdd
    Command line: gcc C:\src\gtk\build\meson-private\tmpdup4zcdd\testfile.c -o C:\src\gtk\build\meson-private\tmpdup4zcdd\output.exe -D_FILE_OFFSET_BITS=64 -O0 -std=gnu99 -Wl,--start-group -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -Wl,--end-group

    Code:
    #include
    #include

    #if defined __stub_aligned_alloc || defined __stub___aligned_alloc
    fail fail fail this function is not going to work
    #endif

    int main(void) {
    void *a = (void*) &aligned_alloc;
    long long b = (long long) a;
    return (int) b;
    }
    Compiler stdout:

    Compiler stderr:
    C:\src\gtk\build\meson-private\tmpdup4zcdd\testfile.c: In function 'main':
    C:\src\gtk\build\meson-private\tmpdup4zcdd\testfile.c:9:32: error: 'aligned_alloc' undeclared (first use in this function)
    void *a = (void*) &aligned_alloc;
    ^
    C:\src\gtk\build\meson-private\tmpdup4zcdd\testfile.c:9:32: note: each undeclared identifier is reported only once for each function it appears in
    C:\src\gtk\build\meson-private\tmpdup4zcdd\testfile.c:10:27: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
    long long b = (long long) a;
    ^

    Running compile:
    Working directory: C:\src\gtk\build\meson-private\tmp0splwspb
    Command line: gcc C:\src\gtk\build\meson-private\tmp0splwspb\testfile.c -o C:\src\gtk\build\meson-private\tmp0splwspb\output.exe -D_FILE_OFFSET_BITS=64 -O0 -std=gnu99 -Wl,--start-group -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -Wl,--end-group

    Code:
    #include
    int main(void) {

    /* With some toolchains (MSYS2/mingw for example) the compiler
    * provides various builtins which are not really implemented and
    * fall back to the stdlib where they aren't provided and fail at
    * build/link time. In case the user provides a header, including
    * the header didn't lead to the function being defined, and the
    * function we are checking isn't a builtin itself we assume the
    * builtin is not functional and we just error out. */
    #if !0 && !defined(aligned_alloc) && !0
    #error "No definition for __builtin_aligned_alloc found in the prefix"
    #endif

    #ifdef __has_builtin
    #if !__has_builtin(__builtin_aligned_alloc)
    #error "__builtin_aligned_alloc not found"
    #endif
    #elif ! defined(aligned_alloc)
    __builtin_aligned_alloc;
    #endif
    return 0;
    }
    Compiler stdout:

    Compiler stderr:
    C:\src\gtk\build\meson-private\tmp0splwspb\testfile.c: In function 'main':
    C:\src\gtk\build\meson-private\tmp0splwspb\testfile.c:12:14: error: #error "No definition for __builtin_aligned_alloc found in the prefix"
    #error "No definition for __builtin_aligned_alloc found in the prefix"
    ^
    C:\src\gtk\build\meson-private\tmp0splwspb\testfile.c:20:13: error: '__builtin_aligned_alloc' undeclared (first use in this function)
    __builtin_aligned_alloc;
    ^
    C:\src\gtk\build\meson-private\tmp0splwspb\testfile.c:20:13: note: each undeclared identifier is reported only once for each function it appears in

    Checking for function "aligned_alloc" : NO
    Running compile:
    Working directory: C:\src\gtk\build\meson-private\tmpsp3qak8_
    Command line: gcc C:\src\gtk\build\meson-private\tmpsp3qak8_\testfile.c -o C:\src\gtk\build\meson-private\tmpsp3qak8_\output.exe -D_FILE_OFFSET_BITS=64 -O0 -std=gnu99 -Wl,--start-group -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -Wl,--end-group

    Code:
    #include
    #include

    #if defined __stub_posix_memalign || defined __stub___posix_memalign
    fail fail fail this function is not going to work
    #endif

    int main(void) {
    void *a = (void*) &posix_memalign;
    long long b = (long long) a;
    return (int) b;
    }
    Compiler stdout:

    Compiler stderr:
    C:\src\gtk\build\meson-private\tmpsp3qak8_\testfile.c: In function 'main':
    C:\src\gtk\build\meson-private\tmpsp3qak8_\testfile.c:10:27: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
    long long b = (long long) a;
    ^
    c:/tdm-gcc-32/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: C:\Users\xxxxxxx\AppData\Local\Temp\ccQb62Xy.o:testfile.c:(.text+0x12): undefined reference to `posix_memalign'
    collect2.exe: error: ld returned 1 exit status

    Running compile:
    Working directory: C:\src\gtk\build\meson-private\tmpkv0f0h9x
    Command line: gcc C:\src\gtk\build\meson-private\tmpkv0f0h9x\testfile.c -o C:\src\gtk\build\meson-private\tmpkv0f0h9x\output.exe -D_FILE_OFFSET_BITS=64 -O0 -std=gnu99 -Wl,--start-group -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -Wl,--end-group

    Code:
    #include
    int main(void) {

    /* With some toolchains (MSYS2/mingw for example) the compiler
    * provides various builtins which are not really implemented and
    * fall back to the stdlib where they aren't provided and fail at
    * build/link time. In case the user provides a header, including
    * the header didn't lead to the function being defined, and the
    * function we are checking isn't a builtin itself we assume the
    * builtin is not functional and we just error out. */
    #if !0 && !defined(posix_memalign) && !0
    #error "No definition for __builtin_posix_memalign found in the prefix"
    #endif

    #ifdef __has_builtin
    #if !__has_builtin(__builtin_posix_memalign)
    #error "__builtin_posix_memalign not found"
    #endif
    #elif ! defined(posix_memalign)
    __builtin_posix_memalign;
    #endif
    return 0;
    }
    Compiler stdout:

    Compiler stderr:
    C:\src\gtk\build\meson-private\tmpkv0f0h9x\testfile.c: In function 'main':
    C:\src\gtk\build\meson-private\tmpkv0f0h9x\testfile.c:12:14: error: #error "No definition for __builtin_posix_memalign found in the prefix"
    #error "No definition for __builtin_posix_memalign found in the prefix"
    ^
    C:\src\gtk\build\meson-private\tmpkv0f0h9x\testfile.c:20:13: error: '__builtin_posix_memalign' undeclared (first use in this function)
    __builtin_posix_memalign;
    ^
    C:\src\gtk\build\meson-private\tmpkv0f0h9x\testfile.c:20:13: note: each undeclared identifier is reported only once for each function it appears in

    Checking for function "posix_memalign" : NO

    subprojects\graphene\meson.build:170:2: ERROR: Problem encountered: No aligned malloc function could be found.


    Any idea on this one?


    Also, now that the commits have been merged. Do I still need this below?

    git config --global user.email "xavier.claessens@collabora.com"
    git config --global user.name "Xavier Claessens"

    Thank you for the help!

    Reply to this comment

    Reply to this comment


Add a Comment






Allowed tags: <b><i><br>Add a new comment:


Search the newsroom

Latest Blog Posts

Adding VP9 and MPEG2 stateless support in v4l2codecs for GStreamer

23/06/2021

Earlier this year, from January to April 2021, I worked on adding support for stateless decoders for GStreamer as part of a multimedia internship…

Bag of Freebies for XR Hand Tracking: Machine Learning & OpenXR

17/06/2021

In our previous post, we presented a project backed by INVEST-AI which introduces a multi-stage neural network-based solution. Now let's…

Testing cameras with lc-compliance on KernelCI

15/06/2021

Initiated as a joint effort by the Google Chrome OS team and Collabora, the recent KernelCI hackfest brought the addition of new tests including…

Zink: Summer 2021 update

14/06/2021

There's a lot that has happened in the world of Zink since my last update, so let's see if I can bring you up to date on the most important…

Open Source OpenGL ES 3.1 on Mali GPUs with Panfrost

11/06/2021

Panfrost, the open source driver for Arm Mali, now supports OpenGL ES 3.1 on both Midgard (Mali T760 and newer) and Bifrost (Mali G31, G52,…

Optimizing 3D performance with virglrenderer

17/05/2021

Collabora has been investing into Perfetto to enable driver authors & users to get deep insights into driver internals and GPU performance.…

Open Since 2005 logo

We use cookies on this website to ensure that you get the best experience. By continuing to use this website you are consenting to the use of these cookies. To find out more please follow this link.

Collabora Ltd © 2005-2021. All rights reserved. Privacy Notice. Sitemap.

Collabora Limited is registered in England and Wales. Company Registration number: 5513718. Registered office: The Platinum Building, St John's Innovation Park, Cambridge, CB4 0DS, United Kingdom. VAT number: 874 1630 19.