I'm trying to cross-compile a small test opengl/glew program and I get linker errors from undefined references.
$ /usr/bin/i486-mingw32-g++ -I/usr/i486-mingw32/include -L/usr/i486-mingw32/lib/ -lglfw -lglew32 -lopengl32 main.cc
/tmp/cct8OpVh.o:main.cc:(.text+0x50): undefined reference to `glfwInit'
/tmp/cct8OpVh.o:main.cc:(.text+0xa6): undefined reference to `glfwOpenWindowHint'
...
The same code does work when compiling for linux:
$ g++ -I/usr/include -L/usr/lib/ -lglfw -lGLEW -lGL main.cc
One thing that caught my eye is that every exported symbol from cross-compiled libraries has an extra underscore prefix:
$ nm /usr/lib/libglfw.a | grep glfwInit$
00000000 T glfwInit
$ /usr/i486-mingw32/bin/nm /usr/i486-mingw32/lib/libglfw.a | grep glfwInit$
00000000 T _glfwInit
This seems to be a common thing since even libstdc++.a shares this property, but why is my cross-compiler linker then looking for non-underscore symbols?
Running arch with following packages (local means AUR):
community/mingw32-binutils 2.23.1-3
community/mingw32-gcc 4.7.2-1
local/mingw32-glew 1.9.0-1
local/mingw32-glfw 2.7.7-1
community/mingw32-pthreads 2.9.1-1
community/mingw32-runtime 3.20-4
community/mingw32-w32api 3.17-1
EDIT
After playing out with both pkg-config and watching glfw recompile and test itself, I came up with the following magic that seems to work, at least I'm compiling:
/usr/bin/i486-mingw32-g++ -I/usr/i486-mingw32/include -L/usr/i486-mingw32/lib -mwindows main.cc -lglew32 /usr/i486-mingw32/lib/libglfw.a /usr/i486-mingw32/lib/libopengl32.a -static-libgcc
There are few questions though:
What is the difference between linking with -l and without?
Why do I need to use -l with glew and cannot with glfw
I was able to solve my problem and, in case someone ever runs into similar situation hope this helps you.
There are two versions of glew32 -library in my system, glew32.a and glew32.dll.a.
glew32.a does not allow for using --static, glew32.dll.a does.
The two commands which compile succesfully, only first of which I've run are:
/usr/bin/i486-mingw32-g++ -I/usr/i486-mingw32/include -L/usr/i486-mingw32/lib main.cc -lglew32.dll -lglfw -lopengl32 --static
/usr/bin/i486-mingw32-g++ -I/usr/i486-mingw32/include -L/usr/i486-mingw32/lib main.cc -lglew32 -lglfw -lopengl32
Looking at my old compiling attempts, the problem was wrong order of libraries and that main.cc was after the libraries.
There is a program, called pkg-config that helps you to configure your compiler. See the manual pages for usage information, but, for this case, its output is:
-mwin32 -I/usr/i486-mingw32/include -L/usr/i486-mingw32/lib -lglfw -lglu32 -lopengl32 -lm -s -mwindows -e _mainCRTStartup
Try to compile with this, I guess it will work.
Related
I'm trying to use X86_64-w64-mingw32-g++ (packaged in Archlinux's MingW package) to cross compile some C++ code into an Windows executable, however I'm having trouble getting past some issues.
I'm calling
x86_64-w64-mingw32-g++ -o build_win/asm build_win/asm.o build_win/asm_lib.o build_win/socket_boost.o -I../extra/etc -fopenmp -lrt -std=c++11 -g -lboost_system -lboost_serialization
from a makefile, but I get thrown the errors:
/usr/lib/gcc/x86_64-w64-mingw32/5.1.0/../../../../x86_64-w64-mingw32/bin/ld: cannot find -lrt
/usr/lib/gcc/x86_64-w64-mingw32/5.1.0/../../../../x86_64-w64-mingw32/bin/ld: cannot find -lboost_system
/usr/lib/gcc/x86_64-w64-mingw32/5.1.0/../../../../x86_64-w64-mingw32/bin/ld: cannot find -lboost_serialization
This works fine with native g++, so exactly do I have to change for mingw to compile?
EDIT: I have mingw-w64-boost package installed, which includes boost libraries pre-compiled and ready to be linked. However, it seems the naming convention is a bit different, and -lboost_system for example becomes -llibboost_system-mt (not exactly sure what the -mt suffix entails).
Problem is I can't find the mingw counterpart for -lrt. I've tried with both -lrtm and -lrtutils but in both cases I get:
[...]
undefined reference to `__imp_getsockopt'
Are you sure that -lboost_system and other libraries are present in the same directory as makefile ?
If not then please include -L flag which indicates the location of your library.
For example:
-L /path_openmp -fopenmp -L /path_boost_system/ -lboost_system -L /path_serialization -lboost_serialization
Moreover, you need not include -I and -g flag when creating an executable from .o files. These are needed when you create .o from .cpp files.
There is no rt library on Windows.
You are missing -lws2_32.
$ x86_64-w64-mingw32-nm -A /usr/x86_64-w64-mingw32/lib/*.a 2>/dev/null | grep getsockopt | grep " T "
I am compiling a C++ application using GNU g++. The project takes advantage of OpenSSL libraries.
Background
On my machine (a 64 bit CentOS quad core) I compile and link my files.
g++ -g -c -L/usr/local/lib/ -L/usr/lib64/
-I/usr/local/include/ -I/usr/local/ssl/include/
-lcrypto mysrc1.cpp mysrc2.cpp mysrc3.cpp
g++ -L/usr/local/lib/ -L/usr/lib64/ -lcrypto
*.o -o ./myapp.out
My application uses function MD5 which is contained in libcrypto.so. As you can see I specify to g++ the dirs where to search using the -L, -I options and which libraries to look for with the -l<lib-name> option. There are some trivial paths like /usr/local/lib which can be omitted of course, but I specified them because the makefile is parametric.
The problem
My problem is that I can successfully compile my stuff (first command), but linking fails (second command):
/usr/bin/ld: cannot find -lcrypto
collect2: ld returned 1 exit status
make: * [cppsims_par] Error 1
But I did check folders and everything... libcrypto.so is inside /usr/lib64/. What is going on?
It may help if you try strace to find why it failed the file lookup
strace -f -e trace=file g++ -L/usr/local/lib/ -L/usr/lib64/ -lcrypto
*.o -o ./myapp.out
I did find the problem and it is related to this question: ld cannot find an existing library
Actually I had no symlink libcrypto.so and the compiler was not able to find the library...
I had related issue, and resolved it after inspecting the trace.
I had
-L<my/path/to/lib> -llib_some_library
when it should have been
-L<my/path/to/lib> -lsome_library
I'm trying to link to a static library, libcovis.a. Everything looks fine but I still have
undefined reference to `CoViG_PublicDemo::MoInS::reset()'
I checked that the name exists in the library
$nm libcovis.a | grep reset
...
_ZN16CoViG_PublicDemo5MoInS5resetEv
...
I'm using linking arguments -L/path/to/libcovis.a -lcovis
What am I doing wrong ?
Edit:
The error might be something else, if do
gcc main.cpp -I/usr/include/opencv -I/usr/include/cairo -I../../Source -o slam -rdynamic -lGLU -lGL -lSM -lICE -lX11 -lXext -lglut -lXi -lxml2 -lboost_filesystem-mt -llapack -lblas -lcv -lcxcore -lcvaux -lhighgui -lcairo ../../Source/libcovis.a ../../Source/contrib/gnuplot_i/libcovis_contrib_gnuplot_i.a -lgl2ps
It works !
But when I'm in KDevelop using cmake, I doesn't work anymore. I use
CMAKE_EXE_LINKER_FLAGS:STRING=-rdynamic -lGLU -lGL -lSM -lICE -lX11 -lXext -lglut -lXi -lxml2 -lboost_filesystem-mt -llapack -lblas -lcv -lcxcore -lcvaux -lhighgui -lcairo /usr/local/src/CoViS-0.0.0-1/Source/libcovis.a /usr/local/src/CoViS-0.0.0-1/Source/contrib/gnuplot_i/libcovis_contrib_gnuplot_i.a -lgl2ps
CMAKE_CXX_FLAGS:STRING=-I/usr/local/src/CoViS-0.0.0-1/Source -I/usr/include/opencv -I/usr/include/cairo
The only difference I can see is that the paths are absolute and not relative, but if he couldn't find the libs, he would say it...
There are two different issues there, the first of which is the simplest, you have used the wrong compiler options. The -L option tells the linker to also look in the directory when looking for a library. The -l tells it to link the specific library. To link you would then use:
g++ -o test test.o -L/path/to -lcovis
or
g++ -o test test.o -l/path/to/libcovis.a
To force static linking if the same library is present as a dynamic library in the same directory.
The second potential issue is that the order of static libraries in the linker command line does matter, so that might also be an issue if there is a dependency on different static libs.
g++ -o test tests.o -ldependent -lprovider
The linker will process the libraries in order as they are in the command line, and from each static lib it will only pull those symbols that are required (with as much information as the linker has at that time). In the command line above, the linker will extract from dependent the symbols it needs for test.o, and that might in turn add new undefined symbols to the program (the dependencies of dependent). When it processes provider it will fill in those symbols. If the order was reversed in the command line, the symbols that are required by dependent but not by test.o would not be added to the executable, as the linker does not know that those symbols will be needed when processing provider.
Should the arguments be like -L/path/to/ -lcovis?
Besides, object files should be placed before libs, for example
g++ obj1.o obj2.o -L/path/to/ -lcovis.
If you see the link succeeding in one context but not another, I suspect the problem may be caused by the order in which the link operation is executed as the linker will discard symbols in a library if they're not needed at the point in which the library is referenced.
Here is a link explaining: http://www.network-theory.co.uk/docs/gccintro/gccintro_18.html
I've run into similar situations in the past the linking order was found to be the cause of the problem.
I compiled my normal cpp files to .o, and my cuda .cu files to .co
I want to link these so I can call the cuda stuff from my normal C++ file
Here is my linker command that Make is running:
g++ -I ../readers/ -I../writers -I../common/ -I /home/dcole/software/xerces-c-3.1.1/src -I /home/dcole/NVIDIA_GPU_Computing_SDK/C/common/inc/ -I /usr/local/cuda/include -O3 -fPIC -fopenmp -DFIX_PAULI -DFIX_YAMA -DUSING_CUDA -o YamaguchiGPU YamaguchiMain.o YamaguchiDecomp.o cuYamaguchi.co -L/usr/lib64/ ../../lib/IDT.a ../../lib/Linux/libxerces-c.a ../../lib/Linux/libfftw3f.a -lcurl -lidn -ldl -lssl -lm -lpthread -lcuda -L/usr/local/cuda/lib64/libcudart.so
So I am definitly linking cuda, and cudart, but yet I get this:
cuYamaguchi.co: In function `__sti____cudaRegisterAll_46_tmpxft_00003190_00000000_4_cuYamaguchi_cpp1_ii_init_gpu()':
tmpxft_00003190_00000000-1_cuYamaguchi.cudafe1.cpp:(.text+0x1b4): undefined reference to `__cudaRegisterFatBinary'
tmpxft_00003190_00000000-1_cuYamaguchi.cudafe1.cpp:(.text+0x20f): undefined reference to `__cudaRegisterFunction'
The Cuda file is being linked without problems but it looks like you might have forgotten to define some necessary function (like cudaRegisterFatBinary).
Upgrading to gcc 4.7.0 or higher should fix this horrid linker issue.
I was using an absolute search path in the linker to _libcudart.so_. I changed the -L to point to just the folder, then added -libcudart so it would search the folder for that lib.
I am trying to compile a C++ program which invokes the ARPACK library.
My problem is that when everything is linked, some of the symbols in the ARPACK library do not get resolved. They are
__gfortran_transfer_integer
__gfortran_transfer_character
__gfortran_transfer_complex
__gfortran_compare_string
__gfortran_st_write_done
__gfortran_st_write
__gfortran_transfer_real
__gfortran_transfer_array
I did a brute force search on my lib directory, and found no library which provided all of these symbols. A couple of them are provided by libf77blas, and it looks like g95 has some similar symbols (with gfortran replaced by g95), but I am at a complete loss as to what else I might need to install. I am compiling my code with
g++-mp-4.5 -O3 -Wall -Wl,-search_paths_first -headerpad_max_install_names my.o -o my.out -L/opt/local/lib -larpack -lm -L/opt/local/lib -lgsl -lgslcblas -lm -lf77blas -llapack -larpack -lqblas -lsquack
and /opt/local/lib actually has all the libraries I reference.
Has anyone run into this problem, or can point to the solution?
add to linker -lgfortran .................