Reputation: 3843
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
:
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
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
<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