user1584421
user1584421

Reputation: 3843

G++. Cannot link library

I am trying to link a library in order to compile some OpenGL code.

I have the source code i am trying to compile mytest1.cpp, and in the same directory, i got a folder called include with the header files and another folder called lib with all the libraries.

This is what is inside the folder called lib: enter image description here

So when i run this command, in order to link everything together:

g++ -I.\include\ mytest1.cpp -L.\lib\ -llibfreeglut -lopengl32 -lglew32

i get this error:

c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: cannot fin
d -llibfreeglut
collect2.exe: error: ld returned 1 exit status

OS: Windows x64

EDIT: I followed the instructions of Mike Kinghan but unfortunately, this is what i get

C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x75): undefined
 reference to `_imp____glewDeleteVertexArrays'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x90): undefined
 reference to `_imp____glewDeleteBuffers'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xc0): undefined
 reference to `_imp____glewBindVertexArray'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xd9): undefined
 reference to `_imp____glewBindBuffer'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xfa): undefined
 reference to `_imp____glewBufferData'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x123): undefine
d reference to `_imp____glewEnableVertexAttribArray'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x136): undefine
d reference to `_imp____glewVertexAttribPointer'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x171): undefine
d reference to `_imp____glewBindBuffer'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x195): undefine
d reference to `_imp____glewBufferData'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x1be): undefine
d reference to `_imp____glewEnableVertexAttribArray'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x1d1): undefine
d reference to `_imp____glewVertexAttribPointer'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x20c): undefine
d reference to `_imp____glewBindBuffer'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x230): undefine
d reference to `_imp____glewBufferData'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x273): undefine
d reference to `_imp____glewBindVertexArray'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x28f): undefine
d reference to `_imp____glewBindVertexArray'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x2db): undefine
d reference to `_imp____glewBindVertexArray'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x4d4): undefine
d reference to `_imp____glewUniformMatrix4fv'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x6e8): undefine
d reference to `_imp____glewUniformMatrix4fv'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0x859): undefine
d reference to `_imp____glewUniformMatrix4fv'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xaf1): undefine
d reference to `_imp____glewGenVertexArrays'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xb0c): undefine
d reference to `_imp____glewGenBuffers'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xbbe): undefine
d reference to `initshaders(unsigned int, char const*)'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xbd7): undefine
d reference to `initshaders(unsigned int, char const*)'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xbf3): undefine
d reference to `initprogram(unsigned int, unsigned int)'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xbfd): undefine
d reference to `_imp____glewGetUniformLocation'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xc1e): undefine
d reference to `_imp____glewGetUniformLocation'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xc3f): undefine
d reference to `_imp____glewUniformMatrix4fv'
C:\Users\User1\AppData\Local\Temp\ccyjpOjl.o:mytest1.cpp:(.text+0xc8e): undefine
d reference to `_imp____glewUniformMatrix4fv'
c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe: C:\Users\U
ser1\AppData\Local\Temp\ccyjpOjl.o: bad reloc address 0xd in section `.text$_ZSt
4sqrtf[__ZSt4sqrtf]'
collect2.exe: error: ld returned 1 exit status

Upvotes: 0

Views: 1310

Answers (1)

Mike Kinghan
Mike Kinghan

Reputation: 61147

Pehaps you've already pulled off a successful linkage featuring:

g++ ... -L.\lib\ ... -lglew32

with .\lib\glew32.lib, and now you wonder why one like:

g++ ... -L.\lib\ ... -llibfreeglut

fails to find .\lib\libfreeglut.a

Here you have one little snags of working with a Windows port of a Unix/Linux toolchain (GCC & GNU binutils).

Classically on *nix systems a file that provides the name library for linkage is is either called libname.a (a static library) or libname.so (a dynamic library a.k.a shared library).

The option -lname instructs the GNU linker to search the specified and default library directories for either of the files libname.a or libname.so and input the first one it finds to the linkage. If it finds both in the same search directory then it chooses libname.so

But this protocol won't do for a Windows port of the toolchain - such as your mingw port - because on Windows the native tradition is to call a static library name.lib and a dynamic library name.dll, and a dynamic library always has the extension .dll

So your mingw GNU linker with obey -lname by searching for any of the files:

libname.a libname.dll name.lib name.dll

(and if it's like mine, it prefers a *.lib over an *.a, and an *.a over a *.dll if more than one candidate is found in the same search directory.)

Accordingly your linkage:

g++ -I.\include\ mytest1.cpp -L.\lib\ -llibfreeglut -lopengl32 -lglew32

would successfuly obey -lglew32 because glew32.lib exists in .\lib. But it will fail on -llibfreeglut because none of:

liblibfreeglut.a liblibfreeglut.dll libfreeglut.lib libfreeglut.dll

exists. Since libfreeglut.a does exist, use:

g++ -I.\include\ mytest1.cpp -L.\lib\ -lfreeglut -lopengl32 -lglew32

to solve this specific linkage failure. You don't show us where you expect the linker to find a file satisfying -lopengl32.

Later... new trouble

Having got your linkage to find the library .\lib\libfreeglut.a you now have undefined reference linkage errors for numerous references matching _imp____glew* from your own code mytest1.cpp. Clearly none of your code's intended references into the glew library are being resolved.

One of the things you need to know when working with Windows .lib and .dll files is that a name.lib file might be a self-contained static library (of the very same archive format as a *nix name.a static library), or it might be specialized archive that actually functions as a DLL import library that stands proxy for a DLL at linktime, the latter being a purely Microsoft idea. A DLL import library name.lib defines symbols of the form _imp_<symbol>1 whose linkage in a program lets the OS loader provide the program with a pointer to the runtime address of the DLL definition of <symbol>, when name.dll is loaded into the process address space.

I am confidently guessing that your glew32.lib is not a actually a static library that you or somebody else built from source with mingw GCC 4.8.1 or an ABI compatible compiler but is a DLL import library from a binary glew package you downloaded that was built with a Microsoft compiler for use with Microsoft compilers.

In general you can't mix object files and/or libraries in the same linkage that were built by different non-ABI compatible compilers, and MS C/C++ is not ABI compatible with GCC C/C++.

A name-mangling protocol is part of the ABI. The name mangling protocols of MS C++ and GCC/Clang C++ are radically different and attempted linkages that mix the two always fail for undefined reference errors. The name mangling protocols of MS C and GCC/Clang C diverge a bit, but they do diverge, and your linkage now falls foul of one of their divergences, attempting to match the C symbols generated by mingw g++ from the C header files <GL/*.h> when it compiled mytest1.cpp with the C symbols generated by MS C when it built your glew32.lib. Your compiler, for example, outputs an undefined reference to

_imp____glewBindVertexArray

which the linkage could only resolve to a symbol defined in glew32.lib, but if you run:

>objdump -t glew32.lib | findstr "glewBindVertexArray"

in your mingw console the closest you will come is:

__imp___glewBindVertexArray

which is missing one _.

You need to build glew - a static library or a DLL, or both - from source with your mingw toolchain, then compile your mytest1.cpp (and any subsequent GLEW program) using the header files of the library you built and link your program against the library you have built.

You'll find plenty of guidance for "Build glew for mingw" on the internet, notably on Stackoverflow in the answers to Building glew on windows with mingw


[1] Where <symbol> might itself have one or more leading _ as a result of C or C++ compiler name-mangling and possibly a source-code naming convention.

Upvotes: 1

Related Questions