How to compile C GTK3+ program in Ubuntu for windows?

I attempted to follow this tutorial 5 or maybe more times and I found what was wrong. I was extracting commands from the wrong directories and downloading the wrong version of GTK+ 3 Windows binaries.

My version of mingw is mingw64 thus I needed to download win64 version.

and I was executing command export PKG_CONFIG_PATH=/opt/gtk3-win64/lib/pkgconfig from /opt/gtk3-win64,but I needed to execute this command from the directory in which my test.c file was located.

I'll make this tutorial easy for future readers.

  1. Install mingw cross-compiler by the command:

    sudo apt-get install mingw-w64
    
  2. Download GTK+ 3 Windows binaries from here (the link in this tutorial is old, here is latest link: http://win32builder.gnome.org/). Download the appropriate version as I was downloading the wrong version. Don't make the same mistake as I did.

  3. Extract the zip file in /opt/gtkwin (recommended) by command

    sudo mkdir /opt/gtkwin && sudo unzip <name of the zip file> -d /opt/gtkwin
    
  4. Use the directory in which you have extracted the zip file. In this case I have extracted in /opt/gtkwin/ and executed the following command:

    find /opt/gtkwin -name '*.pc' -exec sudo sed -e 's@^prefix=.*@prefix=/opt/gtkwin@' -i
    
  5. Go to the directory in which you have the .c file which you which to compile and execute this command:

    export PKG_CONFIG_PATH=/opt/gtkwin/lib/pkgconfig
    
  6. Compile the program by:

    • for 64-bit:

      x86_64-w64-mingw32-gcc test.c $(pkg-config --cflags gtk+-3.0 --libs)
      
    • for 32-bit:

      i586-mingw32msvc-gcc test.c $(pkg-config --cflags --libs gtk+-3.0)
      

Also you should visit this tutorial as I had learn this from there.

This will create an .exe file which can't run in UNIX as it is targeted to run on DOS.


MXE gives ok results. The compiled executable takes a while to load up, and also brings up an empty command prompt. However, this is the only thing I tried that remotely worked.

Summary:

  • Install MXE per the official tutorial
  • x86_64-w64-mingw32.static-gcc -o OUTFILE.exe INFILE.c `x86_64-w64-mingw32.static-pkg-config --cflags --libs gtk+-3.0`
    
  • OUTFILE.exe should now be ready to run on a computer with Windows. Copy it over and double click it, or launch it from the command prompt.

Details

(Mostly summarized from their tutorial)
apt-get install autoconf automake autopoint bash bison bzip2 flex g++ g++-multilib gettext git gperf intltool libc6-dev-i386 libgdk-pixbuf2.0-dev libltdl-dev libssl-dev libtool-bin libxml-parser-perl lzip make openssl p7zip-full patch perl python ruby sed unzip wget xz-utils

git clone https://github.com/mxe/mxe.git
sudo mv mxe /opt/mxe
cd /opt/mxe
make MXE_TARGETS='x86_64-w64-mingw32.static' cc gtk3

That should create the cross compiler, linker, and appropriate libraries in /opt/mxe/usr/bin. They'll all be named something crazy like x86_64-w64-mingw32.static-pkg-config. That's a lot to type! Use makefiles or something so you don't have to type it all out every time.

Add the following line to ~/.bashrc (or whatever script your shell runs automatically):

export PATH=/opt/mxe/usr/bin:${PATH}

Close and reopen your terminal. echo $PATH should include /opt/mxe/usr/bin. You can now compile things with the command x86_64-w64-mingw32.static-gcc (used just like normal gcc). Make sure to use x86_64-w64-mingw32.static-pkg-config in place of regular pkg-config.

Notes:

Maybe MXE-compiled executeables are slow for me it is secretly embedding debug stuff. Maybe mingw can take flags exclude that? Maybe also there are flags to not open the blank command prompt?

Some of the apt-get package installs may be unnecessary, idk.

You should do make MXE_TARGETS='x86_64-w64-mingw32.static' cc gtk3 instead of just make because make generates every single package. That takes very long and will fail on random packages. Some of them can be excluded with the -o flag; for example, make -o cloog -o gdal -o graphicsmagick will exclude the cloog, gdal, and graphicsmagick packages, but that doesn't work on some packages. You should only make the specific packages you need.

MXE_TARGETS='x86_64-w64-mingw32.static' makes the 64 bit version (32 bit is default). Besides the gtk package, we need cc for gcc and pkg-config. Also note that it is gtk3, instead of just gtk like it says in their documentation.

Short guide to pkg-config for complete n00bs: To use #includes in libraries besides the C standard library and your own work, you need pkg-config to tell the C compiler where they are. Basically, the command pkg-config --cflags --libs LIBRARY_NAME, will look through a set of default directories for LIBRARY_NAME.pc files, which contain instructions to make the flags, which can then be passed as arguments to gcc.

The LIBRARY_NAME for gtk3 is gtk+-3.0, for some reason. If you can't figure out what the LIBRARY_NAME for a lib is, you can usually use the find command with a wildcard. For example, find /opt/mxe/usr -Iname gtk*.pc. The I in -Iname means case insensitive.