1

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)
Community
  • 1
  • 1
Timothy Truckle
  • 15,071
  • 2
  • 27
  • 51

1 Answers1

1

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

Christos Lytras
  • 36,310
  • 4
  • 80
  • 113
  • still not able to confirm since I now ran into a problem with the 32 bit target. See here: http://stackoverflow.com/questions/40584265/undefined-reference-to-winmain16-after-applying-windes – Timothy Truckle Nov 14 '16 at 08:08
  • Did you try that I told you, to change windres order and the object file it generates? Then add that object file to the g++ linker rigth after the `-o $@` – Christos Lytras Nov 14 '16 at 08:41
  • yes, the new make file now first creates an *.o file on which windres adds the icon. That is what I got from your answer. – Timothy Truckle Nov 14 '16 at 09:07
  • The makefile you got on the other post is wrong and I still see there you got the windres AFTER the g++ linker commented. I'll check on your error later to see what it is about and I'll update. – Christos Lytras Nov 14 '16 at 09:16
  • change to `$(mingwPath)/windres -v -i $(SOURCE_DIR_NAME)/resources/$(APP_NAME).rc -o $(TARGET_BASE_NAME)Res.o --output-format=coff --target=pe-i386` – Timothy Truckle Nov 14 '16 at 09:17
  • `$(mingwPath)/g++ -m32 -c $< -o $@ $(TARGET_BASE_NAME)Res.o -static -l winpthread` – Timothy Truckle Nov 14 '16 at 09:17
  • now I get `target/JavaLauncherRes.o: linker input file unused because linking not done` – Timothy Truckle Nov 14 '16 at 09:18
  • could whe have a short chat please? http://chat.stackoverflow.com/rooms/info/128038/unable-to-add-icon-to-exe-using-windres?tab=general – Timothy Truckle Nov 14 '16 at 09:24