Cross Compiling Windows Applications

Cross Compiling Windows Applications

Saturday, Apr 15, 2023 by Leon

A recent job I landed through UpWork gave me the chance to set up a new application development workflow that I’ve been wanting to nail down which allows me to do all the development and testing of the windows applications on my Linux workstation.

Up till now I’ve been doing Windows development in a Windows10 VM utilizing Cygwin and wxWidgets. While very doable, I’m just not as efficient working in Windows. This comes from the majority of my last 20 years spent on Linux server and workstations.

So now I just have to:

  • set up the Makefile to call the cygwin toolchain executables for g++, gcc, ld, and windres
  • create a resource file for windres to set the APPINFO resources in the executable
  • use Wine to do inital debugging and testing
  • set up a shared folder with VMware to easily move executables and data to my WIN10 environment for further testing

Since this was a console application, one of the most tedious parts was to find just the right compile/link options to prevent Windows from opening a separate output window for the messages send to STDOUT.

For this particular project I also had to download and compile the Exiv2 Library and the Mini YAML parser for the config file.

In a nutshell the client had a large library of JPG photos dating back many years but were meticulously orgainized in a detailed folder structure. The goal of the application would be recursively descend a given directory structure, find all the JPG files, and add the TAGS to them based on parsing of the full directory path, including splitting tags where CamelCase, spaces, and numbers where found. All of the photos would then be loaded into Piwigo, which would use the embedded EXIF information to add the tags to the system when the files were imported.

Here is the Makefile I wound up using:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#
# Makefile for compiling windows console application
# on a Linux host
#
OBJS = exifupdate.o Yaml.o

# note - the ws2_32 and psapi libraries were needed
#        to be linked into the final application
#        by the Exiv2 library
LIBS = -lstdc++  -lpthread -lws2_32 -lpsapi

COPTS = -D__USE_MINGW_ANSI_STDIO -std=c++20 \
        -I exiv2/include/ -I exiv2/build

LDOPTS = -static -mconsole 
LD = i686-w64-mingw32-ld
CC = i686-w64-mingw32-gcc
CPP = i686-w64-mingw32-g++
WINDRES = i686-w64-mingw32-windres

manifest.o: manifest.rc
	$(WINDRES) $< -o $@

.cpp.o :
	$(CPP) $(COPTS) -c $< 

.c.o :
	$(CC) $(COPTS) -c $< 

exifupdate:	$(OBJS)
	$(CPP) $(OBJS) -o $@ exiv2/build/lib/libexiv2.a \
	$(LIBS) $(LDOPTS) manifest.o

clean:
	rm *.o
	rm *.exe

Let me know if you have any questions about how I set this up.


photo by Alex Andres from Pexels