windowsgcciconsmingwwindres

unable to add icon to exe using windres


I'd like to add an Icon to my exe compiled with mingw-gcc.

I followed instructions in this SO post but the Icon does not show up on my exe in windows explorer.

[edit] Meanwhile I found out that windres destroys my executable. Before applying windres the executable runs as expected. After applying windres calling the executable results in a windows error message telling (roughly) that this executable is not compatible with this windows version.

What am I doing wrong?


This is my directory layout:

$ ls -lR launcher/
launcher/:
total 508
drwxr-xr-x 1 me 1049089      0 Aug 20  2015 src/
drwxr-xr-x 1 me 1049089      0 Nov  7 10:56 target/

launcher/src:
total 0
drwxr-xr-x 1 me 1049089 0 Nov  7 10:51 main/

launcher/src/main:
total 4
drwxr-xr-x 1 me 1049089 0 Nov  7 10:52 cpp/
drwxr-xr-x 1 me 1049089 0 Apr 14  2016 resources/
drwxr-xr-x 1 me 1049089 0 Nov  4 15:11 scripts/

launcher/src/main/cpp:
total 8
-rw-r--r-- 1 me 1049089 6793 Nov  7 10:41 JavaLauncher.cpp

launcher/src/main/resources:
total 5
-rw-r--r-- 1 me 1049089   47 Nov  7 10:47 javaLauncher.rc
-rw-r--r-- 1 me 1049089 2238 Apr 14  2016 JavaLauncher.ico

launcher/src/main/scripts:
total 1
-rw-r--r-- 1 me 1049089 389 Nov  7 10:56 makefile

launcher/target:
total 4
-rwxr-xr-x 1 me 1049089 2502 Nov  7 10:56 JavaLauncher.exe*

this is my resource file:

0 ICON "launcher/src/main/resources/JavaLauncher.ico"

this is my makefile:

all: launcher/target/JavaLauncher.exe

launcher/target/JavaLauncher.exe: launcher/src/main/cpp/JavaLauncher.cpp launcher\target
    /Absolute/Path/to/mingw64/bin/g++.exe $< -o $@ -static -l winpthread
    /Absolute/Path/to/mingw64/bin/windres.exe -v -i launcher/src/main/resources/javaLauncher.rc -o $@


launcher\target:
    cmd /c md $@

this is the output of make:

/Project/root>/Absolute/Path/to/mingw64\bin\make.exe -f launcher\src\main\scripts\makefile
cmd /c md launcher\target
/Absolute/Path/to/mingw64/bin/g++.exe launcher/src/main/cpp/JavaLauncher.cpp -o launcher/target/JavaLauncher.exe -static -l winpthread
/Absolute/Path/to/mingw64/bin/windres.exe -v -i launcher/src/main/resources/javaLauncher.rc -o launcher/target/JavaLauncher.exe
Using `/Absolute/Path/to/mingw64/bin/gcc -E -xc -DRC_INVOKED  launcher/src/main/resources/javaLauncher.rc'
Using popen to read preprocessor output

/Project/root>

this is the result in windows explorer: exe without specified image


[edit] The final working solution is this:

mingwPath = $(realpath Path/to/mingw64/bin)
TARGET_DIR=target
TARGET_OBJECT_DIR=$(TARGET_DIR)/objects
TARGET_DIR_NAME=$(subst /,\, $(TARGET_DIR))
TARGET_OBJECT_DIR_NAME=$(subst /,\, $(TARGET_OBJECT_DIR))
SOURCE_DIR_NAME=src/main
APP_NAME=MyApp
TARGET_BASE_NAME=$(TARGET_DIR)/$(APP_NAME)
TARGET_ARCH=-m32

all: $(TARGET_OBJECT_DIR_NAME) $(TARGET_BASE_NAME).exe


$(TARGET_BASE_NAME).exe: $(TARGET_OBJECT_DIR)/$(APP_NAME).o\ 
 $(TARGET_OBJECT_DIR)/$(APP_NAME)Res.o $(TARGET_OBJECT_DIR_NAME)    
    $(mingwPath)/g++  $(TARGET_ARCH) -o $@ -static -l winpthread   $(filter %.o,$^)

$(TARGET_OBJECT_DIR)/$(APP_NAME).o: $(SOURCE_DIR_NAME)/cpp/$(APP_NAME).cpp
    $(mingwPath)/g++ $(TARGET_ARCH) -c $<  -o $@ 

$(TARGET_OBJECT_DIR)/$(APP_NAME)Res.o:  $(SOURCE_DIR_NAME)/resources/$(APP_NAME).rc
    $(mingwPath)/windres -v -i $< -o $@  --output-format=coff --target=pe-i386


$(TARGET_OBJECT_DIR_NAME):$(TARGET_DIR_NAME)
    echo $@
    cmd /c md $@

$(TARGET_DIR_NAME):
    echo $@
    cmd /c md $@

clean: 
    cmd /c del /s /q $(TARGET_DIR_NAME)

Solution

  • I'm not sure if the windres resource compiler can compile and add the resource data directly to the exe file, but that is what you're trying to do here. Maybe it is possible, I searched a little bit but couldn't find regarding information.

    I got this working and having an exe icon. You need to specify the resource object generated by windres to the g++ linker after the program object. Also change the order and have windres run first so to have the resource object file generated before g++ linker links the program and resource objects.

    all: launcher/target/JavaLauncher.exe
    
    launcher/target/JavaLauncher.exe: launcher/src/main/cpp/JavaLauncher.cpp launcher\target
        /Absolute/Path/to/mingw64/bin/windres.exe -v -i launcher/src/main/resources/JavaLauncher.rc -o launcher/src/main/resources/JavaLauncherRes.o
        /Absolute/Path/to/mingw64/bin/g++.exe $< -o $@ launcher/src/main/resources/JavaLauncherRes.o -static
    
    
    launcher\target:
        cmd /c md $@
    

    enter image description here