g++ fails to link libraries while creating a shared object - c++

I am trying to create a static library for my engine.
The command (in a makefile) is:
g++ -c -fPIC window.cc -lGL -lGLEW -lSDL2 -std=c++14 -I../include/ && g++ -static window.o -lSDL2 -lGL -lGLEW -o ../distribute/so/window.so
So, the first command compiles successful, but the other one outputs this:
/usr/bin/ld: cannot find -lGL
/usr/bin/ld: cannot find -lGLEW
collect2: error: ld returned 1 exit status
But I definitely need those arguments. Can we fix it?

You need to know the exact paths of the library files to be linked with.
The directories that contain them should be added to your link line with -L.

Related

How to embed glut library into c++ project?

I have a c++ project but when distribute this, need install libglut.so.3.:
./bin: error while loading shared libraries: libglut.so.3: cannot open shared object file: No such file or directory
I want the user not to have to install this dependency. How to embed the library into project?
I try compile as static library in c++ project using g++. My make file contains:
#g++ \
-o bin \
-std=c++11 \
main.cpp \
-lm -lGL -lGLU -lglut \
;
I try define glut as static library:
-lm -lGL -lGLU -Wl,-Bstatic -lglut -Wl,-Bdynamic
But the compiler says:
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libglut.a(libglut_la-freeglut_state.o): undefined reference to symbol 'XGetWindowAttributes'
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libX11.so: error adding symbols: DSO missing from command line
I try download freeglut-3.0.0 and compile as static library:
Change CMakeLists.txt file for static compile:
OPTION(FREEGLUT_BUILD_SHARED_LIBS "Build FreeGLUT shared library." OFF)
OPTION(FREEGLUT_BUILD_STATIC_LIBS "Build FreeGLUT static library." ON)
And in the CMakeCache.txt:
//Build FreeGLUT shared library.
FREEGLUT_BUILD_SHARED_LIBS:BOOL=OFF
//Build FreeGLUT static library.
FREEGLUT_BUILD_STATIC_LIBS:BOOL=ON
And compile it:
$ cmake .
$ make
[ 62%] Built target freeglut_static
...
[100%] Built target shapes_static
And verify:
$ ll lib/libglut.a
-rw-r--r-- 1 me me 690860 nov 17 19:11 lib/libglut.a
$ file lib/libglut.a
lib/libglut.a: current ar archive
Now, change the makefile:
-lm -lGL -lGLU freeglut-3.0.0/lib/libglut.a
And compile:
$ make
usr/bin/ld: freeglut-3.0.0/lib/libglut.a(fg_state_x11.c.o): undefined reference to symbol 'XGetWindowAttributes'
//usr/lib/x86_64-linux-gnu/libX11.so.6: error adding symbols: DSO missing from command line
But, same error message.
In similar problem: fglut/libfglut.a(freeglut_state.o): undefined reference to symbol 'XGetWindowAttributes' , i try add x11 libraries into project:
-lm -lGL -lGLU -lX11 freeglut-3.0.0/lib/libglut.a
Or:
-lm -lGL -lGLU -lX11 -Wl,-Bstatic -lglut -Wl,-Bdynamic
But have a same error message. What happened?
I have successfully linked my a GLUT program using this command
g++ -o ogl-test main.cpp freeglut-3.0.0/lib/libglut.a -lGL -lGLU -lX11 -lXxf86vm -lXext -lXrandr -lXt -lXi
Hopefully this will also work for you. Make sure you change the path to glut library.

How do I change the order in automake's CXXLINK?

I am trying to compile a simple C++ program with the automake tools. By itself, automake creates in its Makefile the line: CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $#
This way, however, i get some linker errors, which can be resolved by simply putting the -o example example.cpp part in the beginning of the g++ command instead of the end.
How can I instruct automake to put the -o example example.cpp in front of the linker commands?
Here is the Makefile.am
bin_PROGRAMS = GLTest
GLTest_SOURCES = main.cpp
AM_CXXFLAGS=#gllibs_CFLAGS# -std=c++11 -pthread
AM_LDFLAGS=#gllibs_LIBS# -lGL -lGLEW -lglfw -lX11 -lXi -lXrandr
Here are the linker errors:
g++ -I/usr/include/libdrm -std=c++11 -pthread -g -O2 -lGLEW -lGLU -lGL -lglfw -lGL -lGLEW -lglfw -lX11 -lXi -lXrandr -o GLTest main.o
main.o: In function `main':
main.cpp:8: undefined reference to `glfwInit'
main.cpp:9: undefined reference to `glfwWindowHint'
main.cpp:10: undefined reference to `glfwWindowHint'
main.cpp:11: undefined reference to `glfwWindowHint'
main.cpp:12: undefined reference to `glfwWindowHint'
main.cpp:14: undefined reference to `glfwCreateWindow'
collect2: error: ld returned 1 exit status
These are resolved when I compile it manually like this:
g++ -o GLTest main.cpp -I/usr/include/libdrm -std=c++11 -pthread -g -O2 -lGLEW -lGLU -lGL -lglfw -lGL -lGLEW -lglfw -lX11 -lXi -lXrandr
You're doing it wrong. The problem is you're passing libraries as LDFLAGS, and that is incorrect.
You should have
GLTest_LDADD = $(gllibs_LIBS)
so that you're telling automake correctly that those are libraries.
Using libtool may work, depending on the libtool version used, since it can sort the command line, but it's still the wrong thing to do and fails in other situations.
From the linker command in the output it looks like you are not using libtool.
Try adding AM_PROG_LIBTOOL to the configure.ac.

Mixing static and dynamic libraries in fedora

There are already some answers how to mix dynamic and static linking of binaries.
Like in the anwers I read so far I compile like this:
gcc main.cpp -static-libstdc++ -static-libgcc -Wl,-Bstatic -lm -lstdc++ -lpthread -lrt -lc -Wl,-Bdynamic -lmyshared_lib -L. libx.a liby.a
But then I get an error:
/usr/lib/gcc/i686-redhat-linux/4.7.2/../../../libpthread.a(libpthread.o): In function `sem_open':
(.text+0x6407): warning: the use of `mktemp' is dangerous, better use `mkstemp'
/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib/gcc/i686-redhat-linux/4.7.2/../../../libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie
collect2: error: ld returned 1 exit status
The third-party lib is itself dependend on libc.so.6, so I guess this is now in conflict with my static linked libc.
If I compile with the -fPIE and -pie parameters like below - the application segfaults immediately:
gcc main.cpp -fPIE -static-libstdc++ -static-libgcc -Wl,-Bstatic -lm -lstdc++ -lpthread -lrt -lc -Wl,-Bdynamic -lmyshared_lib -L. libx.a liby.a -Wl,-pie
Does it even work to compile nearly completely static and just link one shared object additionally?
I try to do this because I want to get one specific 32bit binary to run on a x64 system using a 32bit third party shared object...

Undefined reference to symbol, even though the library is linked

When linking a project I am working on, the linker gives the following errors:
/usr/bin/ld: ../Includes and Libs/lib/libsfml21rca.a(SoundFile.o): undefined reference to symbol 'sf_read_short##libsndfile.so.1.0'
/usr/bin/ld: note: 'sf_read_short##libsndfile.so.1.0' is defined in DSO /usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/libsndfile.so so try adding it to the linker command line
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/libsndfile.so: could not read symbols: Invalid operation
The thing is, libsndfile.so is already linked before libsfml21rca.a, so I have no idea where the problem is.
I'm using Code::Blocks 10.05
Thanks for help in advance
EDIT:
Here is the linking command:
g++ -L"Includes and Libs/lib" -L"Includes and Libs/lib/raknet3_731" -L"Includes and Libs/lib/d3d_new/x86" -L"Includes and Libs/lib/ogg" -L"Includes and Libs/lib/sdl" -LBullet/lib -o (filename) ...(a whole lot of object files) -lGLEW -lglfw -lGL -lGLU -lpthread -lopenal -ljpeg -lfreetype -lsndfile -lXrandr -lsfml-system -lsfml-window -lsfml-audio ../Bullet/lib/LinearMath.lib ../Bullet/lib/BulletCollision.lib ../Bullet/lib/BulletDynamics.lib "../Includes and Libs/lib/raknet3_731/RakNetLibStaticDebug.lib" "../Includes and Libs/lib/libsfml21rca.a" ../../../../../../home/msabol/Desktop/SFML/sfml2st/sfmlVideo/sfmlVideo/bin/Release/libsfmlVideo.a ../../../../../../home/msabol/Desktop/SFML/sfmlVideo/bin/Release/libsfmlVideo.a
The linker only runs one pass over the library files. So if you have something in Library A that needs something in Library B, you need to have g++ objects... -llibA -llibB, if you use g++ objects... -llibB -llibA it will fail in the manner you show.
So, in your case, put the -lsndfile after "../Includes and Libs/lib/libsfml21rca.a".
(And whose idea was it to put spaces in a the "Includes and Libs" directory - not the best idea I've seen...)

Static linking failed although the name exists

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.