OpenSSL linking undefined reference to `EVP_MD_CTX_new' and others - gcc

I am compiling some codes based on OpenSSL. The compiler, parameters and error are shown in the following.
$ gcc -I/home/share/pkp/include -L/home/share/pkp/lib -lssl -lcrypto -Wall -O3 -Wpedantic -Wno-unused-result -Wno-pointer-sign ot.c -o ot
/tmp/cck3sgve.o: In function `main':
ot.c:(.text.startup+0x20): undefined reference to `EVP_get_digestbyname'
ot.c:(.text.startup+0x31): undefined reference to `EVP_MD_CTX_new'
ot.c:(.text.startup+0x41): undefined reference to `EVP_DigestInit_ex'
ot.c:(.text.startup+0x53): undefined reference to `EVP_DigestFinal_ex'
ot.c:(.text.startup+0x5b): undefined reference to `EVP_MD_CTX_free'
collect2: error: ld returned 1 exit status
Here are versions of components in the compile environments.
$ uname -a
Linux yzx-lab3 4.4.0-17763-Microsoft #379-Microsoft Wed Mar 06 19:16:00 PST 2019 x86_64 x86_64 x86_64 GNU/Linux
$ /home/share/pkp/bin/openssl version
./bin/openssl: relocation error: ./bin/openssl: symbol EVP_mdc2 version OPENSSL_1_1_0 not defined in file libcrypto.so.1.1 with link time reference
$ grep "OPENSSL_VERSION" /home/share/pkp/openssl-1.1.1a/include/openssl/opensslv.h
# define OPENSSL_VERSION_NUMBER 0x1010101fL
# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1a 20 Nov 2018"
$ gcc --version
gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
I know there already many question about the similar error and have tried many solutions. But they do not work.
1) Fist I obtain the source code and unzip all the fils to "/home/share/pkp".
wget https://www.openssl.org/source/old/1.1.1/openssl-1.1.1a.tar.gz
Then compile and install openssl library.
./config --prefix=/home/share/pkp --openssldir=/home/share/pkp/openssl
make && make test && make install
There is no error message during the installation.
2) To asure that openssl is compiled and installed correctly, I do some verifications.
$ ls /home/share/pkp/lib/ -l
total 14912
drwxrwxrwx 1 share share 4096 Jun 18 12:30 engines-1.1
-rw-r--r-- 1 share share 5700252 Jun 18 12:30 libcrypto.a
lrwxrwxrwx 1 share share 16 Jun 18 12:30 libcrypto.so -> libcrypto.so.1.1
-rwxr-xr-x 1 share share 3414744 Jun 18 12:30 libcrypto.so.1.1
-rw-r--r-- 1 share share 1043216 Jun 18 12:30 libssl.a
lrwxrwxrwx 1 share share 13 Jun 18 12:30 libssl.so -> libssl.so.1.1
-rwxr-xr-x 1 share share 692696 Jun 18 12:30 libssl.so.1.1
$ nm /home/share/pkp/lib/libcrypto.a | grep "EVP_get_digestbyname" | wc -l
24
$ du /home/share/pkp/include/openssl -ah
4.0K /home/share/pkp/include/openssl/aes.h
36K /home/share/pkp/include/openssl/asn1.h
0 /home/share/pkp/include/openssl/asn1_mac.h
16K /home/share/pkp/include/openssl/asn1err.h
36K /home/share/pkp/include/openssl/asn1t.h
4.0K /home/share/pkp/include/openssl/async.h
4.0K /home/share/pkp/include/openssl/asyncerr.h
36K /home/share/pkp/include/openssl/bio.h
8.0K /home/share/pkp/include/openssl/bioerr.h
4.0K /home/share/pkp/include/openssl/blowfish.h
24K /home/share/pkp/include/openssl/bn.h
8.0K /home/share/pkp/include/openssl/bnerr.h
4.0K /home/share/pkp/include/openssl/buffer.h
4.0K /home/share/pkp/include/openssl/buffererr.h
4.0K /home/share/pkp/include/openssl/camellia.h
4.0K /home/share/pkp/include/openssl/cast.h
4.0K /home/share/pkp/include/openssl/cmac.h
20K /home/share/pkp/include/openssl/cms.h
12K /home/share/pkp/include/openssl/cmserr.h
4.0K /home/share/pkp/include/openssl/comp.h
4.0K /home/share/pkp/include/openssl/comperr.h
8.0K /home/share/pkp/include/openssl/conf.h
4.0K /home/share/pkp/include/openssl/conf_api.h
4.0K /home/share/pkp/include/openssl/conferr.h
20K /home/share/pkp/include/openssl/crypto.h
4.0K /home/share/pkp/include/openssl/cryptoerr.h
16K /home/share/pkp/include/openssl/ct.h
4.0K /home/share/pkp/include/openssl/cterr.h
8.0K /home/share/pkp/include/openssl/des.h
16K /home/share/pkp/include/openssl/dh.h
4.0K /home/share/pkp/include/openssl/dherr.h
12K /home/share/pkp/include/openssl/dsa.h
4.0K /home/share/pkp/include/openssl/dsaerr.h
4.0K /home/share/pkp/include/openssl/dtls1.h
12K /home/share/pkp/include/openssl/e_os2.h
4.0K /home/share/pkp/include/openssl/ebcdic.h
64K /home/share/pkp/include/openssl/ec.h
0 /home/share/pkp/include/openssl/ecdh.h
0 /home/share/pkp/include/openssl/ecdsa.h
16K /home/share/pkp/include/openssl/ecerr.h
36K /home/share/pkp/include/openssl/engine.h
8.0K /home/share/pkp/include/openssl/engineerr.h
12K /home/share/pkp/include/openssl/err.h
76K /home/share/pkp/include/openssl/evp.h
12K /home/share/pkp/include/openssl/evperr.h
4.0K /home/share/pkp/include/openssl/hmac.h
4.0K /home/share/pkp/include/openssl/idea.h
8.0K /home/share/pkp/include/openssl/kdf.h
4.0K /home/share/pkp/include/openssl/kdferr.h
8.0K /home/share/pkp/include/openssl/lhash.h
4.0K /home/share/pkp/include/openssl/md2.h
4.0K /home/share/pkp/include/openssl/md4.h
4.0K /home/share/pkp/include/openssl/md5.h
4.0K /home/share/pkp/include/openssl/mdc2.h
12K /home/share/pkp/include/openssl/modes.h
216K /home/share/pkp/include/openssl/obj_mac.h
8.0K /home/share/pkp/include/openssl/objects.h
4.0K /home/share/pkp/include/openssl/objectserr.h
16K /home/share/pkp/include/openssl/ocsp.h
4.0K /home/share/pkp/include/openssl/ocsperr.h
8.0K /home/share/pkp/include/openssl/opensslconf.h
8.0K /home/share/pkp/include/openssl/opensslv.h
8.0K /home/share/pkp/include/openssl/ossl_typ.h
16K /home/share/pkp/include/openssl/pem.h
0 /home/share/pkp/include/openssl/pem2.h
8.0K /home/share/pkp/include/openssl/pemerr.h
12K /home/share/pkp/include/openssl/pkcs12.h
4.0K /home/share/pkp/include/openssl/pkcs12err.h
12K /home/share/pkp/include/openssl/pkcs7.h
8.0K /home/share/pkp/include/openssl/pkcs7err.h
4.0K /home/share/pkp/include/openssl/rand.h
8.0K /home/share/pkp/include/openssl/rand_drbg.h
8.0K /home/share/pkp/include/openssl/randerr.h
4.0K /home/share/pkp/include/openssl/rc2.h
4.0K /home/share/pkp/include/openssl/rc4.h
4.0K /home/share/pkp/include/openssl/rc5.h
4.0K /home/share/pkp/include/openssl/ripemd.h
24K /home/share/pkp/include/openssl/rsa.h
12K /home/share/pkp/include/openssl/rsaerr.h
8.0K /home/share/pkp/include/openssl/safestack.h
4.0K /home/share/pkp/include/openssl/seed.h
4.0K /home/share/pkp/include/openssl/sha.h
4.0K /home/share/pkp/include/openssl/srp.h
4.0K /home/share/pkp/include/openssl/srtp.h
112K /home/share/pkp/include/openssl/ssl.h
0 /home/share/pkp/include/openssl/ssl2.h
16K /home/share/pkp/include/openssl/ssl3.h
48K /home/share/pkp/include/openssl/sslerr.h
4.0K /home/share/pkp/include/openssl/stack.h
12K /home/share/pkp/include/openssl/store.h
8.0K /home/share/pkp/include/openssl/storeerr.h
4.0K /home/share/pkp/include/openssl/symhacks.h
72K /home/share/pkp/include/openssl/tls1.h
24K /home/share/pkp/include/openssl/ts.h
8.0K /home/share/pkp/include/openssl/tserr.h
4.0K /home/share/pkp/include/openssl/txt_db.h
16K /home/share/pkp/include/openssl/ui.h
4.0K /home/share/pkp/include/openssl/uierr.h
4.0K /home/share/pkp/include/openssl/whrlpool.h
44K /home/share/pkp/include/openssl/x509.h
32K /home/share/pkp/include/openssl/x509_vfy.h
8.0K /home/share/pkp/include/openssl/x509err.h
36K /home/share/pkp/include/openssl/x509v3.h
12K /home/share/pkp/include/openssl/x509v3err.h
1.6M /home/share/pkp/include/openssl
3)Finally, I tried other compile commands, but then still do not work.
$ gcc -I/home/share/pkp/include -L/home/share/pkp/lib -lcrypto -lssl -Wall -O3 -Wpedantic -Wno-unuse
d-result -Wno-pointer-sign ot.c -o ot
$ gcc -I/home/share/pkp/include -L/home/share/pkp/lib -lssl -lcrypto -Wall -O3 -Wpedantic -Wno-unuse
d-result -Wno-pointer-sign ot.c -o ot
$ gcc -I/home/share/pkp/include -L/home/share/pkp/lib -lcrypto -lssl -Wall -Wpedantic -Wno-unuse
d-result -Wno-pointer-sign ot.c -o ot
$ gcc -I/home/share/pkp/include -L/home/share/pkp/lib -lcrypto -O3 -Wall -Wpedantic -Wno-unuse
d-result -Wno-pointer-sign ot.c -o ot
4) It seems that the openssl from downloaded source code is conflict with the openssl installed by "apt-get". So I try another method.
./config && make && make test && make install
It will install openssl into the system directory. Then I run
$ gcc -lssl -lcrypto ot.c -o ot
/tmp/ccrFwoa7.o: In function `main':
ot.c:(.text+0x2d): undefined reference to `EVP_get_digestbyname'
ot.c:(.text+0x66): undefined reference to `EVP_MD_CTX_new'
ot.c:(.text+0x82): undefined reference to `EVP_DigestInit_ex'
ot.c:(.text+0x99): undefined reference to `EVP_DigestFinal_ex'
ot.c:(.text+0xa5): undefined reference to `EVP_MD_CTX_free'
collect2: error: ld returned 1 exit status
It still failed. Envn I follow the solution in here trying to statically link libcrypto and libssl. It failed again.
$ gcc -lssl -lcrypto -ldl -lz -static -static-libgcc ot.c -o ot
/tmp/cc39C5Gq.o: In function `main':
ot.c:(.text+0x2d): undefined reference to `EVP_get_digestbyname'
ot.c:(.text+0x66): undefined reference to `EVP_MD_CTX_new'
ot.c:(.text+0x82): undefined reference to `EVP_DigestInit_ex'
ot.c:(.text+0x99): undefined reference to `EVP_DigestFinal_ex'
ot.c:(.text+0xa5): undefined reference to `EVP_MD_CTX_free'
collect2: error: ld returned 1 exit status
I am sure all the static libraries are in the correct location.
$ whereis lib{ssl,crypto,z,dl}.a
libssl: /usr/lib/x86_64-linux-gnu/libssl.a /usr/lib/x86_64-linux-gnu/libssl.so /usr/local/lib/libssl.a /usr/local/lib/libssl.so
libcrypto: /usr/lib/x86_64-linux-gnu/libcrypto.a /usr/lib/x86_64-linux-gnu/libcrypto.so /usr/local/lib/libcrypto.a /usr/local/lib/libcrypto.so /mnt/c/Windows/System32/libcrypto.dll
libz: /usr/lib/x86_64-linux-gnu/libz.a /usr/lib/x86_64-linux-gnu/libz.so
libdl: /usr/lib/x86_64-linux-gnu/libdl.a /usr/lib/x86_64-linux-gnu/libdl.so
5) Come here to post this question.
#include <stdio.h>
#include <openssl/evp.h>
int main(int argc, char *argv[]){
EVP_MD_CTX *mdctx;
const EVP_MD *md;
unsigned char md_value[EVP_MAX_MD_SIZE];
int md_len, i;
md = EVP_get_digestbyname(argv[1]);
if(!md) {
printf("Unknown message digest %s\n", argv[1]);
exit(1);
}
mdctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(mdctx, md, NULL);
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
EVP_MD_CTX_free(mdctx);
printf("Digest is: ");
for (i = 0; i < md_len; i++)
printf("%02x", md_value[i]);
printf("\n");
exit(0);
}
The code should be compiled with no error. But now it shows "undefined reference to `EVP_get_digestbyname'".

You have to put the libraries in the end of the compiling command, like this:
gcc -I/home/share/pkp/include -L/home/share/pkp/lib -Wall -O3 -Wpedantic -Wno-unused-result -Wno-pointer-sign ot.c -o ot -lcrypto -lssl
You can know why here: Why does the library linker flag sometimes have to go at the end using GCC?
I reproduced the error in my machine and this change solved it.

Related

gnu ld: symbol remains undefined, even when it is defined

Trying to link a program which (for unknown reasons) generates a reference to "xmemdup".
I found the source code for xmemdup.c, and compiled it, and included the .o file in the link, but ld still claims it is undefined.
$ gcc -Wall -g -O2 -pipe -DBINDIR=\"/usr/bin\" -c -o rsh.o rsh.c
This worked, generating rsh.o
$ ll rsh.o ../publib-0.40/alloc/xmemdup.o
-rw-r--r-- 1 perryh perryh 2344 Dec 29 22:25 ../publib-0.40/alloc/xmemdup.o
-rw-r--r-- 1 perryh perryh 68656 Dec 30 00:47 rsh.o
Proves that the .o files I am about to pass to the linker do exist. BTW xmemdup.o is an object file, not a library, so it should get included unconditionally even if it were not needed to resolve a reference.
$ gcc -Wall -g -O2 -pipe -DBINDIR=\"/usr/bin\" -o rsh rsh.o ../publib-0.40/alloc/xmemdup.o
/usr/bin/ld: symbol lookup error: /usr/bin/ld: undefined symbol: xmemdup
collect2: error: ld returned 127 exit status
and yet the linker can't see the definition of xmemdup in xmemdup.o

Size of the file produced by linker is too large

I have those three files that don't have many bytes.
.rw-r--r-- 936 28 Jan 00:53 kernel.o
.rw-r--r-- 512 28 Jan 00:53 kernel_entry.o
.rw-r--r-- 872 28 Jan 00:53 screen.o
I assembled kernel_entry.o using NASM 2.15.05:
nasm src/kernel_entry.asm -f elf32 -o ../build/obj/kernel_entry.o
And i compiled kernel.o and screen.o using gcc 11.1.0:
gcc -ffreestanding -m32 -fno-pie -c -Iinclude -MMD -o ../build/obj/kernel.o src/kernel.c
gcc -ffreestanding -m32 -fno-pie -c -Iinclude -MMD -o ../build/obj/driver/screen.o src/driver/screen.c
My goal is to produce 32 bit executable code.
Then i link those 3 files together using ld 2.36.31:
ld -m elf_i386 -Ttext 0x1000 --oformat binary ../build/obj/kernel_entry.o ../build/obj/kernel.o ../build/obj/driver/screen.o -o ../build/kernel.bin
However, I expected the output file to be the size of the three .o files but it is 135M which is way too much:
.rwxr-xr-x 135M 28 Jan 01:16 build/kernel.bin
Looking at the hexadecimal representation of the file, I see a little room for my instructions and the rest is just zeros.
Do you have any idea what's wrong? By removing the oformat parameter I get a decent size but the code does not execute as expected
Thank you.

Error cross-compiling binutils-gdb for windows

I cloned binutils-gdb repository from here (master branch) on a linux machine (Ubuntu) and I want to compile it for Windows (using x86_64_w64_mingw32 toolchain).
First, I ran ./configure with the following options to specify the cross-compile toolchain.
./configure --prefix=/usr/x86_64-w64-mingw32 --target=arm-none-eabi --host=x86_64-w64-mingw32
Then I ran make and get the following error (I omitted most of the output because it is pretty large):
[...]
x86_64-w64-mingw32-gcc -DHAVE_CONFIG_H -DWITH_DEFAULT_ALIGNMENT=STRICT_ALIGNMENT -DDEFAULT_INLINE=0 -Wall -Wdeclaration-after-statement -Wpointer-arith -Wpointer-sign -Wno-unused -Wunused-value -Wunused-function -Wno-switch -Wno-char-subscripts -Wmissing-prototypes -Wdeclaration-after-statement -Wempty-body -Wmissing-parameter-type -Wold-style-declaration -Wold-style-definition -Wno-format -Werror -DMODET -I. -I. -I../common -I./../common -I../../include -I./../../include -I../../bfd -I./../../bfd -I../../opcodes -I./../../opcodes -I../../intl -g -O2 -c -o callback.o -MT callback.o -MMD -MP -MF .deps/callback.Tpo ./../common/callback.c
./../common/callback.c: In function ‘os_time’:
./../common/callback.c:417:25: error: passing argument 1 of ‘time’ from incompatible pointer type [-Werror=incompatible-pointer-types]
417 | return wrap (p, time (t));
| ^
| |
| long int *
In file included from ./../common/callback.c:35:
/usr/share/mingw-w64/include/time.h:230:47: note: expected ‘time_t *’ {aka ‘long long int *’} but argument is of type ‘long int *’
230 | static __inline time_t __CRTDECL time(time_t *_Time) { return _time64(_Time); }
| ~~~~~~~~^~~~~
cc1: all warnings being treated as errors
make[3]: *** [Makefile:513: callback.o] Error 1
make[3]: Leaving directory '/media/D/Work/FC/binutils-gdb/sim/arm'
make[2]: *** [Makefile:928: all-recursive] Error 1
make[2]: Leaving directory '/media/D/Work/FC/binutils-gdb/sim'
make[1]: *** [Makefile:8376: all-sim] Error 2
make[1]: Leaving directory '/media/D/Work/FC/binutils-gdb'
make: *** [Makefile:915: all] Error 2
I think it has something to do with time_t being typedef'd as a long long int (64 bit integer) in the host platform (Windows), however, the function os_time from the file sim/common/callback.c:414 (path relative to project root), takes a long (32 bit integer) as a parameter:
static long
os_time (host_callback *p, long *t)
{
return wrap (p, time (t));
}
How can I fix this error? Or are there any issue trackers for binutils-gdb?
This is because you are building the current, non-release,development version - I got the exact same error while building from the latest git revision at the time I cloned the repository, 0a703a4cedffa6f3824e87f115e8d392e32de191.
If you really want to build from the development tree, you will have to wait for the issue to be fixed, or to fix it by yourself - this is not being addressed in this answer.
But if building the latest released version, 2.36.1, is sufficient, the procedure hereafter will work (tested on Ubuntu 20.04 TLS):
wget https://ftp.gnu.org/gnu/binutils/binutils-2.36.1.tar.gz
tar zxf binutils-2.36.1.tar.gz
mkdir binutils
cd binutils
../binutils-2.36.1/configure --prefix=$(pwd)/binutils-2.36.1-x86_64-w64-mingw32 --target=arm-none-eabi --program-prefix=arm-none-eabi- --host=x86_64-w64-mingw32
make
make install
ll -gG binutils-2.36.1-x86_64-w64-mingw32/bin/
total 159144
drwxrwxr-x 2 4096 Apr 7 14:41 ./
drwxrwxr-x 6 4096 Apr 7 14:41 ../
-rwxr-xr-x 1 9212998 Apr 7 14:41 arm-none-eabi-addr2line.exe*
-rwxr-xr-x 2 9748961 Apr 7 14:41 arm-none-eabi-ar.exe*
-rwxr-xr-x 2 14457348 Apr 7 14:41 arm-none-eabi-as.exe*
-rwxr-xr-x 1 9077841 Apr 7 14:41 arm-none-eabi-c++filt.exe*
-rwxr-xr-x 1 816086 Apr 7 14:41 arm-none-eabi-elfedit.exe*
-rwxr-xr-x 1 10783524 Apr 7 14:41 arm-none-eabi-gprof.exe*
-rwxr-xr-x 4 14526998 Apr 7 14:41 arm-none-eabi-ld.bfd.exe*
-rwxr-xr-x 4 14526998 Apr 7 14:41 arm-none-eabi-ld.exe*
-rwxr-xr-x 2 9259673 Apr 7 14:41 arm-none-eabi-nm.exe*
-rwxr-xr-x 2 10655762 Apr 7 14:41 arm-none-eabi-objcopy.exe*
-rwxr-xr-x 2 14908446 Apr 7 14:41 arm-none-eabi-objdump.exe*
-rwxr-xr-x 2 9748961 Apr 7 14:41 arm-none-eabi-ranlib.exe*
-rwxr-xr-x 2 6156460 Apr 7 14:41 arm-none-eabi-readelf.exe*
-rwxr-xr-x 1 9193640 Apr 7 14:41 arm-none-eabi-size.exe*
-rwxr-xr-x 1 9190290 Apr 7 14:41 arm-none-eabi-strings.exe*
-rwxr-xr-x 2 10655762 Apr 7 14:41 arm-none-eabi-strip.exe*
I did not test building from the git repository after having checked-out the binutils-2_36_1 tag:
git -C binutils-gdb checkout binutils-2_36_1
But it should work, if what was tagged is what was packaged in the archive file, which should be the case.

Yocto project cannot find asm/errno.h

I'm trying to compile a program that requires asm/errno.h header.
Building C object CMakeFiles/modem.dir/src/client.c.o
| /home/kristupas/yocto/oe-core/build/tmp-glibc/sysroots/x86_64-linux/usr/bin/arm-oe-linux-gnueabi/arm-oe-linux-gnueabi-gcc -Dmodem_EXPORTS -std=gnu99 -march=armv7-a -mfloat-abi=softfp -mfpu=neon --sysroot=/home/kristupas/yocto/oe-core/build/tmp-glibc/sysroots/mdm9607 -O2 -fexpensive-optimizations -frename-registers -fomit-frame-pointer -fPIC -I/home/kristupas/yocto/oe-core/build/tmp-glibc/work/armv7a-vfp-neon-oe-linux-gnueabi/libmodem/1.0-r0/libmodem/src -I/home/kristupas/yocto/oe-core/build/tmp-glibc/work/armv7a-vfp-neon-oe-linux-gnueabi/libmodem/1.0-r0/libmodem/include -o CMakeFiles/modem.dir/src/client.c.o -c /home/kristupas/yocto/oe-core/build/tmp-glibc/work/armv7a-vfp-neon-oe-linux-gnueabi/libmodem/1.0-r0/libmodem/src/client.c
| [ 83%] /home/kristupas/yocto/oe-core/build/tmp-glibc/work/armv7a-vfp-neon-oe-linux-gnueabi/libmodem/1.0-r0/libmodem/src/client.c:14:25: fatal error: asm/ernno.h: No such file or directory
| #include <asm/ernno.h>
^
The --sysroot argument is set correctly to my targets sysroot, but gcc still can't find the header, even though it's clearly there:
ls -la /home/kristupas/yocto/oe-core/tmp-glibc/sysroots/mdm9607/usr/include/asm/ | grep "errno\.h"
-rw-r--r-- 3 kristupas kristupas 31 Kov 9 16:06 errno.h
Doing
echo | /home/kristupas/yocto/oe-core/build/tmp-glibc/sysroots/x86_64-linux/usr/bin/arm-oe-linux-gnueabi/arm-oe-linux-gnueabi-gcc -R -Wp. -v -
returns this:
--includedir=/home/kristupas/yocto/oe-core/build/tmp-glibc/sysroots/x86_64-linux/usr/include
This is the include directory for the host, which does not contain asm/errno.h. Shouldn't it point to targets sysroot instead?
Turns out I misspelled errno and failed to notice it for hours!

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:
[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)
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 $#

Resources