make recipe to link to avoid undefined reference to WinMain#16 - makefile

Thanks for taking my question. I have spent many hours checking posts on this but I still need help. Thanks for being patient with me :)
I have a class of midi functions that calls the Widows multimedia API.
When I compile my class Midf.h by itself at the command line it compiles and works:
g++ -Wall Midf.h Midf.cpp midftest.cpp -lwinmm -o midftest2.exe
I have written a makefile to include these functions in a larger program.
My recipe for building the Midf.o is as follows:
Midf.o: Midf.cpp Midf.h
g++ -Wall Midf.cpp -lwinmm
At this point I get the following error:
g++ -Wall Midf.cpp -lwinmm
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/lib/libmingw32.a(main.o): In function `main':
e:\p\giaw\src\pkg\mingwrt-4.0.3-1-mingw32-src\bld/../mingwrt-4.0.3-1-mingw32-src/src/libcrt/crt/main.c:91: undefined reference to `WinMain#16'
collect2.exe: error: ld returned 1 exit status
Makefile:21: recipe for target 'Midf.o' failed
make: *** [Midf.o] Error 1
I have read that Mingw does not support wmain, but there is a way around that by making sure that main is defined properly outside of a namespace. I am not sure how to do that.
I would be glad to post the entire makefile, my file that contains main(), Midf.h Midf.cpp or any other file in the source code to find the problem.
By the way, this is a console program and I have tried building it with MinGW and with Cygwin.
Thanks again for everyone willing to help!

To turn my comments into an answer:
If you want to perform separate compilation you have to tell gcc not to link your objects by passing the -c flag.
Your second problem was not passing the libraries during linking, passing them during compilation has no effect.

Related

gcc/g++ parameter order

i just compiled chironfs on my new ubuntu 12.10 server and got the following error:
gcc -Wall -W -Wmissing-prototypes -g -O2 -DFUSE_USE_VERSION=25 -D_FILE_OFFSET_BITS=64 -I/usr/local/include -g -O2 -lm -lfuse -o chironfs chironfs.o chiron-conf.o chirondbg.o chironfn.o
chironfs.o: In function `chiron_init':
/root/chironfs-1.1.1/src/chironfs.c:2000: undefined reference to `pthread_create'
chironfs.o: In function `get_rights_by_name':
/root/chironfs-1.1.1/src/chironfs.c:452: undefined reference to `fuse_get_context'
the pthread error tells me that -lpthread is missing, but the fuse error is kinda weird cause -lfuse is being used
i found a solution here which suggests to put libraries after object files
so i removed -lfuse and added -lfuse -lpthread at the very end of the line
now it compiles without an error and it seems that this is the way it should be: library after object files
my question is:
why is the parameter order relevant for gcc/ld? i tought gcc just parses the params like every other application and may forward the necessary params to ld or such
in general: anyone knows facts or tips for gcc parameter ordering and maybe a bit background
information about why it is needed this way?
thanks
The order of objects and libraries is relevant to the linker (called implicitly by the compiler when creating an executable). When the linker, in its left-to-right scan, finds a use of a name it doesn't know about it starts looking for a definition from that point on. If a definition passes by, it doesn't remember it for later use.
GCC itself passes parameters to ld in relatively transparent fashion
Your question really is about how ld linker works. For simplicity and to handle circular references without infinite loops, it passes through the list of libraries only once, resolving references. So if your reference occurs somewhere and it hasn't seen the library that contains it yet then it's just an error.
Also please read this discussion, where this question is discussed in greater details.

undefined reference to `dl_iterate_phdr'

I need an help!! I am trying to build a standalone executable ie without ANY dynamic linking.
I wrote a small test program, generated a relocatable object file for it called test.o. When I try to build the standalone executable using GNU linker I get the below error:
$ld -static -o test test.o /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/libc.a /usr/lib/gcc/i486-linux-gnu/4.4/libgcc.a /usr/lib/gcc/i486-linux-gnu/4.4/libgcc_eh.a
/usr/lib/gcc/i486-linux-gnu/4.4/libgcc_eh.a(unwind-dw2-fde-glibc.o): In function _Unwind_Find_FDE':
(.text+0x190b): undefined reference todl_iterate_phdr'
How to resolve the undefined symbol dl_iterate_phdr. In which archive this symbol is present?
Thanks!!!
EDIT1:
Just in case if I am not very clear, my motive is to generate a standalone executable ie an executable which is completely ready for execution while it gets loaded into memory i.e.) all symbol resolution and relocation is done by program linker itself instead of dynamic linker. Is it possible to generate such an executable?
FINAL UPDATE:
Now I got it to get complied with ld directly using the below command:
$ld -static -o test /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc/i486-linux-gnu/4.4.3/crtbeginT.o /usr/lib/gcc/i486-linux-gnu/4.4.3/crtend.o test.o --start-group /usr/lib/gcc/i486-linux-gnu/4.4.3/libgcc.a /usr/lib/gcc/i486-linux-gnu/4.4.3/libgcc_eh.a /usr/lib/libc.a --end-group
man ld says --start-group archives --endgroup is used to resolve circular references!! Also i find symbol dl_iterate_phdr is defined in libc.a.
Thanks all for your help!!
When I try to build the standalone executable using GNU linker
Don't. Use of ld to link any user-space program is most often a bug. Your link line is certainly incorrect.
Use compiler driver to do the heavy lifting for you. This should work:
gcc -static -o test test.o
I am looking to use ld since I wanted to build a standalone executable
What makes you believe that GCC-built executable is less stand-alone than ld-built one? Whatever it is, you are mistaken: gcc simply invokes ld with correct arguments.
If you're getting this error when targeting android, you need to link against libdl.so (-ldl)
gcc -o main main.c -L . -static-libgcc -Wl,-static -lhello -lc

Building a program (sscep) against OpenSSL: undefined reference to '[...]'

I am trying to build a tool called sscep (http://www.klake.org/~jt/sscep/) for Windows. It does not run natively and I have a "patch" that changes sscep to make it compile on Windows.
After applying the patch, it does compile perfectly but the linker screws. I am using gcc in minGW/msys
The original messsage was that it couldn't find the crypto lib so I added the library with "-L../openssl-mingw/lib" which then didn't create any more errors. I also have the command line switch -lcrypto in my command: gcc -L../openssl-mingw/lib -lcrypto sscep.o init.o net.o sceputils.o pkcs7.o ias.o fileutils.o -o sscep.In this directory is a libcrypto.a. OpenSSL itself was compiled with the exact same compiler just running ./config && make && make test && make install. Also the sources were extracted using the minGW tar and not 7-zip.
After following all documentation this is my (truncated) output:
sscep.o:sscep.c:(.text+0x83): undefined reference to `WSAStartup#8'
sscep.o:sscep.c:(.text+0xa5): undefined reference to `WSACleanup#0'
sscep.o:sscep.c:(.text+0x3d5): undefined reference to `BIO_new_mem_buf'
sscep.o:sscep.c:(.text+0x3e0): undefined reference to `ASN1_INTEGER_new'
sscep.o:sscep.c:(.text+0x414): undefined reference to `a2i_ASN1_INTEGER'
sscep.o:sscep.c:(.text+0x432): undefined reference to `ASN1_INTEGER_to_BN'
sscep.o:sscep.c:(.text+0x448): undefined reference to `BN_bn2dec'
sscep.o:sscep.c:(.text+0xb7e): undefined reference to `EVP_des_cbc'
sscep.o:sscep.c:(.text+0xbaf): undefined reference to `EVP_bf_cbc'
sscep.o:sscep.c:(.text+0xbda): undefined reference to `EVP_des_cbc'
sscep.o:sscep.c:(.text+0xc02): undefined reference to `EVP_des_ede3_cbc'
sscep.o:sscep.c:(.text+0xc48): undefined reference to `EVP_md5'
sscep.o:sscep.c:(.text+0xc79): undefined reference to `EVP_md5'
sscep.o:sscep.c:(.text+0xca1): undefined reference to `EVP_sha1'
This goes on for every file in there and supposedly every function called.
Searching here and google resulted in a missing library but omitting the -L directive from above I get another error about not finding libcrypto. So I assume that the library is actually found but somewhat with wrong addresses or something?
Here my compiler/linker knowledge actually ends.
If it is possible that the patch is responsible for that (which I do not believe since these are all openssl functions and the compiling works) then I can provide you with it.
Edit: Is there any information that I should provide so someone can help me? The version of openssl is 1.0.1 if this makes any difference.
On this topic: If it does make a difference, could this error occur because of a wrong version. As far as I understand linker theory, this error should not originate from a wrong version unless all of the below functions were replaced by differently named ones (but then the compiler would have complained, I guess?).
Another addition: Since I am on a 64 bit Windows 7, I tried to compile it with -m32 flag but that did not help. I assume since mingw is already 32 bit only, I can't even build x64. Another question is whether it is a problem that I am running in a virtualized environment on an AMD Opteron while openssl is built with the command "-march=i486"?
With some help I could finally figure this out! It was a problem of the order AND a problem of missing libraries. The combination killed me.
The libraries had to be -lcrypto -lws2_32 -lgdi32 not just -lcrypto. Furthermore, I had to append the libraries after the object files, so: $(CC) $(CFLAGS) $(OBJS) -lcrypto -lws2_32 -lgdi32 -o $(PROG) was the right make line.
Finally with this, it compiles fine. I didn't even need any architecture flags and such.

Very strange linker behavior

This is strange because I was able to get the error below to go away by removing the reference to libm.
gcc -o example example.o -Wl -L/home/kensey/cdev/lib -L/usr/lib/x86_64-linux-gnu -lmysqlclient -lpthread -lz -L/usr/lib/x86_64-linux-gnu -lm -lrt -ldl -lcdev -L/home/kensey/www.tools/gplot-lib -lgplot -L/home/kensey/www.tools/gd1_3ret -lgd -lxml2 -lcurl
/usr/bin/ld: /home/kensey/www.tools/gplot-lib/libgplot.a(set.o): undefined reference to symbol 'floor##GLIBC_2.2.5'
/usr/bin/ld: note: 'floor##GLIBC_2.2.5' is defined in DSO /usr/lib/x86_64-linux-gnu/libm.so so try adding it to the linker command line
/usr/lib/x86_64-linux-gnu/libm.so: could not read symbols: Invalid operation
collect2: ld returned 1 exit status
So, if I remove the -lm part of the command, I do not get the error. However, I wonder if anyone knows as to why removing a reference to a library that is needed would fix this. How does the linker know which library to look in? Also - is there a way to query a built executable and say 'which library did you resolve the reference to 'floor'? obviously, there is something going on that I don't understand, and that bothers me...
The explanation to what's happening is very simple:
Your libgplot.a depends on libm.so, yet the order of -lm and -lgplot on the link line is wrong.
The order of libraries on the link line does matter. In general, system libraries (-lpthread, -lm, -lrt, -ldl) should follow everything else on the link line.
When you remove -lm from the link line, libm.so.6 is still pulled into the link by some other library that appears later on the link line (libgd, libxml2 or libcurl) because that library depends on libm.so.6. But now libm.so.6 is in correct place on the link line, and so everything works.
if I put -lm at the end of the link command, listing it as the last library, I do not get the error.
That confirms above explanation.
I've solved the same problem with export LDFLAGS="$LDFLAGS -lm"
Perhaps, your library search paths (/usr/local/lib/ or /usr/lib/, ...) do not contain 64bit libm so gcc cannot locate it if you specify with l flag. If you only specify only the directory it looks like it can find the right one. So you can try:
LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu
and use -lm
Hard to tell. Because there are custom library directories in the command line it's conceivable that -lm links an incompatible alternative version. Without -lm the linker could pull in another version of it because it's needed by one of the libraries you link.
To make sure strace both invocations and see where libm.so is coming from in both cases.
BTW, -Wl switch seems to do nothing and -L/usr/lib/x86_64-linux-gnu is mentioned twice.
Just to add to the list of answers, http://fedoraproject.org/wiki/UnderstandingDSOLinkChange It is informative. It isn't relevant to the question asked above, but, the explanation relates to the error message /usr/bin/ld: note: 'some_reference' is defined in DSO some.so so try adding it to the linker command line
One explanation could be:
It's possibly there is a weakly linked function foo defined outside of libm that is replaced by a strongly linked version of foo defined inside libm, and it is this strongly linked version that calls the undefined function.
This would explain how adding a library can cause an undefined function error.
I just ran into a similar problem; I remember that the order of the libraries did not matter (at least not in the cases I worked with) in the past for gcc. In this question here somebody noticed that the behaviour seems to have changed between 4.4 and 4.5 .
In my case, I got rid of the error message by doing the linking at:
g++ -Wl,--copy-dt-needed-entries [options] [libraries] [object files] -o executable-file
I faced the similar issue because I had manually updated the dev toolchain on my centOS machine to solve a VScode Remote dependency and was linking C++ library with c code.
In my case, I solved this by adding in the Makefile:
LDFLAG=-Wl,--copy-dt-needed-entries
I also pointed my gcc to the version I wanted (After updating toolchain, gcc pointed to the toolchain : /opt/rh/devtoolset-2/root/usr/bin/gcc)
CC=\usr\bin\gcc which is (gcc version 4.4.7)
Use this:
administrator#administrator-Veriton-M200-H81:~/ishan$ gcc polyscanline1.cpp -lglut -lGLU -lGL -lm

GCC - Linking is unsuccessful

and sorry for my not really good english. I'll try my best :)
I am trying to compile a addin for my Casio graphic calculator in C. This works without problems when using the official SDK. Because it is only available for Windows, I want to use gcc.
So I got sh-rtems-gcc and it's binutils from macports and tried to compile my program according to this instructions. I copy-pasted the described addin.ld and crt0.s and placed my main.c and libfxsys.a (from the same guys as the instructions mentioned above) in the same directory. The sub-dir include contains fxsys' headers. I verified the presence of all the functions of the library in the .a file with nm.
When using this command for compilation:
sh-rtems-gcc-4.2.3 -m3 -mb -nostdlib -I./include -c crt0.s main.c
Everything works fine. But then im trying to link:
sh-rtems-gcc-4.2.3 -m3 -mb -nostdlib -L. -o myaddin.elf -Taddin.ld crt0.o main.o -lfxsys
and get the following error:
main.o: In function `__main':
main.c:(.text+0x248): undefined reference to `_Bdisp_AllClr_VRAM'
...
... (--- cut 16 other errors in the same format ---)
...
main.c:(.text+0x360): undefined reference to `_Sleep'
./libfxsys.a(locate.o): In function `_locate':
locate.c:(.text+0x28): undefined reference to `_locate_OS'
collect2: ld gab 1 als Ende-Status zurück
All the missing symbols are in the libfxsys.a. I have verified this with nm.
I have already played with the positions of the library in the command, as this is often mentioned as a source of failure in other posts found in google, but without success. I also tried adding and removing the -lgcc option that is used in the above mentioned instructions, without success.
My Host-Machine is a Intel Mac, OS X 10.6
Because I have no idea how to solve this problem, and get to compile my program, I have to ask: What am I doing wrong? How can I compile my program without using the SDK?
Thanks in advance,
xythobuz
Edit:
I have also tried linking with:
sh-rtems-ld -EB -L. -o myaddin.elf -Taddin.ld crt0.o --start-group main.o libfxsys.a --end-group
But it produces the same output as above.
I can't say the exact problem, but would investigate like this:
Find the library that contains the missing symbols. Use nm to see symbol names
Once you know which library contains the symbols make sure you're linking to it, and in the correct order. Try using recursive symbol resolution options -( -) with your linker.

Resources