Desperately need help with mingw64 and gtk-3.0 for cross compilation from Linux (WSL/Ubuntu) to Windows

The following works with WSL (Ubuntu).

Install mxe with gtk3 for Windows, in /mxe.

mxe.bash

#!/bin/bash

sudo apt -y install libssl-dev libtool-bin flex bison \
  gperf intltool p7zip-full python-is-python3
git clone https://github.com/mxe/mxe.git /mxe
git config --global --add safe.directory /mxe
make -C /mxe MXE_TARGETS='x86_64-w64-mingw32.static' cc gtk3

Install gtk3 for Linux.

gtk.bash

#!/bin/bash

deb="deb http://archive.ubuntu.com/ubuntu focal-updates main"
! grep "$deb" /etc/apt/sources.list >/dev/null \
  && echo "$deb" | sudo tee -a /etc/apt/sources.list
sudo apt update
sudo apt -y upgrade
sudo apt -y install libgtk-3-dev
echo $'\n'"pkg-config --modversion gtk+-3.0"
printf '> %s\n' "`pkg-config --modversion gtk+-3.0`"
echo $'\n'"pkg-config --libs --cflags gtk+-3.0"
printf '> %s\n' "`pkg-config --libs --cflags gtk+-3.0`" ""

I’ve also included echo and printf commands here to print the gtk version and libraries.

My Bash script with commands and exports.

gcc.bash

#!/bin/bash

mkdir -p /gcc/
export PATH=/mxe/usr/bin:"$PATH"
export GCC="-I/gcc/ -L/gcc/ -pthread"
export GTK="`pkg-config --cflags --libs gtk+-3.0`"
export GTKWIN="-mwindows `x86_64-w64-mingw32.static-pkg-config --cflags --libs gtk+-3.0`"

gcc-win(){
  x86_64-w64-mingw32.static-gcc "$@"
}

pkg-config-win(){
  x86_64-w64-mingw32.static-pkg-config "$@"
}

gcc-lib(){
  cp "$1".h "$1".c /gcc/
  gcc -c /gcc/"$1".c -o /gcc/"$1".o
  ar rcs /gcc/"lib$1.a" /gcc/"$1".o
  gcc-win -c /gcc/"$1".c -o /gcc/"$1-win".o
  ar rcs /gcc/"lib$1-win.a" /gcc/"$1-win".o
}

gcc-lib can be used to quickly add a single library in /gcc/.
Sourcing this script creates /gcc (if non-existent) and the script’s exports assume that new libraries are placed in /gcc/.

How to use the commands.

You can use the following test .c files:

gtktest.c

#include <gtk/gtk.h>

static void
print_hello (GtkWidget *widget,
             gpointer   data)
{
  g_print ("Hello World\n");
}

static void
activate (GtkApplication *app,
          gpointer        user_data)
{
  GtkWidget *window;
  GtkWidget *button;
  GtkWidget *button_box;

  window = gtk_application_window_new (app);
  gtk_window_set_title (GTK_WINDOW (window), "Window");
  gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);

  button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
  gtk_container_add (GTK_CONTAINER (window), button_box);

  button = gtk_button_new_with_label ("Hello World");
  g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
  g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
  gtk_container_add (GTK_CONTAINER (button_box), button);

  gtk_widget_show_all (window);
}

int
main (int    argc,
      char **argv)
{
  GtkApplication *app;
  int status;

  app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);

  return status;
}

sqltest.c

#include <sqlite3.h>
#include <stdio.h>

int main(void) {
  printf("%s%s\n", "SQLITE3 VERSION: ", sqlite3_libversion());
  return 0;
}

We’ll compile the sqlite amalgamation file and add the library with gcc-lib.

The SQLite Amalgamation

sqlite-amalgamation-3410200.zip
(2.50 MiB) C source code as an amalgamation, version 3.41.2.

Contents of my ~/gtk/:

  • mxe.bash
  • gtk.bash
  • gcc.bash
  • gtktest.c
  • sqltest.c
  • sqlite3.c
  • sqlite3.h

Install everything with the following commands (provided that you’re in ~/gtk/):

(the first command takes quite a while…)

bash mxe.bash
ls /mxe
bash gtk.bash
. gcc.bash
echo $GCC
echo $GTK
echo $GTKWIN
. gcc.bash
gcc-lib sqlite3
ls /gcc

Now you can easily (cross-)compile the .c files.

. gcc.bash
gcc gtktest.c -o gtktest $GCC $GTK
./gtktest

This opens a GTK GUI prompt with a ‘Hello World’ button you can click.

. gcc.bash
gcc-win gtktest.c -o gtktest.exe $GTKWIN
cp *.exe /mnt/c/users/michiel/gtk/

Then in CMD (Windows):

gtk\gtktest.exe

This opens the same GTK GUI prompt in Windows.

. gcc.bash
gcc sqltest.c -o sqltest -lsqlite3 -ldl $GCC
./sqltest

This prints your Sqlite version (using sqlite in ansi C).

. gcc.bash
gcc-win sqltest.c -o sqltest.exe -lsqlite3-win $GCC
cp *.exe /mnt/c/users/michiel/gtk/

Then in CMD (Windows):

gtk\sqltest.exe

Does the same in CMD.

Good luck!

This is as idiotproof as I, the idiot, can make it.
:smiley:

Thanks to @lb90 for the guidance.

2 Likes