Compiling OpenGL Program (Linux) - Cannot find -lGL - c++

I am attempting to compile a test opengl program on ubuntu. I have installed bumblebee, the nvidia 304 driver and libgl1-mesa-dev, using apt-get.
I can see the file /usr/lib/libGL.so.1 - and yet compiling with g++ and the flag -lGL returns the error: error: cannot find -lGL.
Any ideas on what I can do to fix this?
Output of dpkg -L libgl1-mesa-dev
/.
/usr
/usr/share
/usr/share/bug
/usr/share/bug/libgl1-mesa-dev
/usr/share/bug/libgl1-mesa-dev/script
/usr/share/bug/libgl1-mesa-dev/control
/usr/share/doc
/usr/share/doc/libgl1-mesa-dev
/usr/share/doc/libgl1-mesa-dev/copyright
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/mesa
/usr/lib/x86_64-linux-gnu/pkgconfig
/usr/lib/x86_64-linux-gnu/pkgconfig/gl.pc
/usr/share/doc/libgl1-mesa-dev/changelog.Debian.gz
/usr/lib/x86_64-linux-gnu/mesa/libGL.so
/usr/lib/x86_64-linux-gnu/libGL.so
/usr/lib/x86_64-linux-gnu/libglapi.so
Update
The command ldconfig -p | grep libGL.so gives the output:
libGL.so.1 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libGL.so.1
libGL.so.1 (libc6,x86-64) => /usr/lib/libGL.so.1
libGL.so.1 (libc6) => /usr/lib/i386-linux-gnu/libGL.so.1
libGL.so (libc6) => /usr/lib/i386-linux-gnu/libGL.so
I don't know if that's useful or correct?

Related

How to configure CMake/CMakeLists.txt to link generic shared library filename rather than the specific one

I have an application configured using CMake and build with GCC. I'm building on one Linux system and try to run it on another. Unfortunately both systems supply different versions of the same lib. For example GLEW, so whenever I try to run executable on the second system I'm getting this:
./app
./app: error while loading shared libraries: libGLEW.so.2.0: cannot open shared object file: No such file or directory
Here are relevant outputs of app reference and what I have in my system.
ldd ./app | awk '{print $1}' | grep GLEW
libGLEW.so.2.0
ldconfig -p | grep GLEW
libGLEW.so.2.2 (libc6,x86-64) => /usr/lib/libGLEW.so.2.2
libGLEW.so.2.2 (ELF) => /usr/lib32/libGLEW.so.2.2
libGLEW.so.2.1 (libc6,x86-64) => /usr/lib/libGLEW.so.2.1
libGLEW.so (libc6,x86-64) => /usr/lib/libGLEW.so
libGLEW.so (ELF) => /usr/lib32/libGLEW.so
I actually would like to configure CMake or whatever to reference the "least common denominator" filename, so instead of libGLEW.so.2.0 it should ref to libGLEW.so
[EDIT]
Some additional outputs from the builder OS:
cat CMakeCache.txt | grep GLEW
...
GLEW_LIBRARIES:FILEPATH=/usr/lib/x86_64-linux-gnu/libGLEW.so
...
ls -al /usr/lib/x86_64-linux-gnu/libGLEW.so
lrwxrwxrwx 1 root root 16 Jan 12 2019 /usr/lib/x86_64-linux-gnu/libGLEW.so -> libGLEW.so.2.1.0
So basically CMake gets it right, but then the GCC linker follows the link and actually places a version specific filename as a reference.
In this case I would instruct cmake to link against the shared library generic name, which should be libGLEW.so or similar and be a symbolic link to a specific version of the library. Check in /usr/lib. If it does not exist on the build machine or the execution machine, you may need to create it. However, note that there may not be binary compatibility between two versions of libGLEW, as #AlanBirtles pointed out.
As of cmake 3.15 there is now a cmake module to find glew and handle this better.
Here is a link to the module:
https://cmake.org/cmake/help/latest/module/FindGLEW.html?highlight=glew
You should be able to figure it out from there.
For now I have converged on using patchelf. The solution is based on How can I change the filename of a shared library after building a program that depends on it?
Install patchelf on your linux build host. In my case it's ubuntu,
so apt-get install -y patchelf
Check the app dependencies: patchelf --print-needed ./app, which in my case yields:
libSDL2-2.0.so.0
libpthread.so.0
libGL.so.1
libGLU.so.1
libGLEW.so.2.1
libfontconfig.so.1
libfreetype.so.6
libXcursor.so.1
libX11.so.6
libdl.so.2
libIL.so.1
libminizip.so.1
libz.so.1
libunwind.so.8
libvorbisfile.so.3
libopenal.so.1
libcurl.so.4
libstdc++.so.6
libm.so.6
libgcc_s.so.1
libc.so.6
Next replace the links to all missing libraries. In my case it was only libGLEW.so.2.1, so patchelf --replace-needed libGLEW.so.2.1 libGLEW.so ./app
Now re-verify of the list of linked libs: patchelf --print-needed ./app
libSDL2-2.0.so.0
libpthread.so.0
libGL.so.1
libGLU.so.1
libGLEW.so
libfontconfig.so.1
libfreetype.so.6
libXcursor.so.1
libX11.so.6
libdl.so.2
libIL.so.1
libminizip.so.1
libz.so.1
libunwind.so.8
libvorbisfile.so.3
libopenal.so.1
libcurl.so.4
libstdc++.so.6
libm.so.6
libgcc_s.so.1
libc.so.6
Note libGLEW.so.2.1 got changed into libGLEW.so
P.S. I don't consider this a proper solution, so any suggestions how to handle linking properly in the first place are more than welcome.

Can't build boost on linux with bz2 support

Downloaded boost 1.66, unbzipped, launching bootstrap:
Bootstrapping is done. To build, run:
./b2
b2 reports:
...blablabla..
- zlib : yes (cached)
- bzip2 : yes (cached)
...blablabla..
The following directory should be added to linker library paths:
/home/steve/boost_1_66_0/stage/lib
...blablabla..
No errors during build, only warnings. I am looking into /home/steve/boost_1_66_0/stage/lib, but there is no files with bz in their name. On windows prebuilt binaries I have:
boost_bzip2-vc140-mt-gd-x64-1_66.dll
boost_bzip2-vc140-mt-gd-x64-1_66.lib
boost_bzip2-vc140-mt-x64-1_66.dll
boost_bzip2-vc140-mt-x64-1_66.lib
As a result my project builds fine on Windows and fails on Linux because of missing bz2 dependencies. Any ideas?
My linux is ubuntu 14.
Thanx.
Any ideas?
Yup. You're looking for ghosts. On linux, libz and libbz2 are the packaged versions by default:
cd custom/boost_1.66.0/
ldd ldd stage/lib/libboost_iostreams.so.1.66.0
Prints
linux-vdso.so.1 => (0x00007fffe9708000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fc3399af000)
libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x00007fc33979f000)
liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007fc33957d000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fc3391f5000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fc338fde000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc338dc1000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc3389f7000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc3387f3000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fc3384ea000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc339de5000)
The library is part of the ``libbz2-1.0` package as you can find with
dpkg --search /lib/x86_64-linux-gnu/libbz2.so.1.0
libbz2-1.0:amd64: /lib/x86_64-linux-gnu/libbz2.so.1.0
So if you want to build boost with bzip2 support, make sure you installed the development pacakage:
sudo apt install libbz2-dev
In fact, I'm often "lazy" and just install the dependencies from the distro boost packages:
sudo apt build-dep libboost-all-dev
It looks like you got that part covered, so you were looking for "extra libraries" that donot exist.
Ok, what I've found out is that on Linux and Windows you need different libraries for bz2 streams to function. I am using cmake and this is how I've solved it:
if (MSVC)
find_package(Boost COMPONENTS system filesystem bzip2 REQUIRED)
endif()
if(LINUX)
find_package(Boost COMPONENTS system filesystem iostreams REQUIRED)
endif()
otherwise linker produces errors both on Windows and Linux.

Linker can't find mathgl library

I try to make mathgl work, but the linker can't find the library. I installed it through the user repository from arch linux.
I just copied the example program:
#include <mgl2/mgl.h>
int main()
{
mglGraph gr;
gr.FPlot("sin(pi*x)");
gr.WriteFrame("test.png");
}
The official website states you need to link lmgl, but I get this error:
$ g++ main.cpp -lmgl
/usr/bin/ld: cannot find -lmgl
collect2: error: ld returned 1 exit status
I couldn't figure out where to start looking for the library. How can I see where it was installed?
I was looking for libmgl with ldconfig -p getting these results:
$ ldconfig -p | grep libmgl
libmgl2.so.7.5.0 (libc6,x86-64) => /usr/lib/libmgl2.so.7.5.0
libmgl2.so (libc6,x86-64) => /usr/lib/libmgl2.so
libmgl2-qt5.so.7.5.0 (libc6,x86-64) => /usr/lib/libmgl2-qt5.so.7.5.0
libmgl2-qt5.so (libc6,x86-64) => /usr/lib/libmgl2-qt5.so
libmgl2-qt.so.7.5.0 (libc6,x86-64) => /usr/lib/libmgl2-qt.so.7.5.0
libmgl2-qt.so (libc6,x86-64) => /usr/lib/libmgl2-qt.so
libmgl2-glut.so.7.5.0 (libc6,x86-64) => /usr/lib/libmgl2-glut.so.7.5.0
libmgl2-glut.so (libc6,x86-64) => /usr/lib/libmgl2-glut.so
As Amadeus indicated, using
$ g++ main.cpp -lmgl2
should work.

How can one build openssl on ubuntu with a specific version of zlib?

Background
I'd like to build OpenSSL against a specific version of zlib so that all of my code is built by me. I do this for many of the libraries I use so that I don't get different behaviour on different versions of the operating system. I understand that this isn't strictly necessary, but I wanna.
What I've Done
I've built zlib in ~/zlib/zlib-1.2.7, and installed zlib to ~/zlib/lib and ~/zlib/include.
(Note that I've simplified all paths in this post by substituting my working directory for '~')
I've built openssl passing these arguments to ./config
--with-zlib-lib=~/zlib/lib
--with-zlib-include=~/zlib/include
When I build openssl, I can see that the appropriate -I argument is being passed to GCC
./config --prefix=~/openssl --openssldir=openssl/ssl threads zlib-dynamic shared --with-zlib-lib=~/zlib/lib --with-zlib-include=~/zlib/include && make && make install
. . .
...many lines of output...
. . .
gcc -I.. -I../.. -I../modes -I../asn1 -I../evp -I../../include -I/home/ubuntu/zlib/include -fPIC -DOPENSSL_PIC -DZLIB_SHARED -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -Wa,--noexecstack -m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -c -o cm_pmeth.o cm_pmeth.c
OpenSSL builds successfully.
The Problem
I check what version of zlib is being linked with the command ldd libssl.so.
ubuntu#lemming012:~/ben/code/optimiser/libs/3rdParty/openssl/lib$ ldd libssl.so
linux-vdso.so.1 => (0x00007fff3e7ff000)
libcrypto.so.1.0.0 => /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 (0x00007f
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f289bcab000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f289baa6000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f289b88f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f289c6c7000)
I expect to see ldd reporting my own libz file in the list.
Instead, ldd reports that libssl is linked to my system installed version of libz. The results are identical if I copy my own version libz.so.1 into the libssl 'lib' directory before running ldd in that same directory.
Question
What have I done wrong? How can I get OpenSSL to link to my version of zlib instead of the version installed on the system?
Environment
uBuntu 13.04 x64
compiling with GCC
building with Make
The answer turns out to be, you need to set an rpath with a syntax similar to the following. I do mine in a Makefile, which is the reason for the double '$'.
LDFLAGS += -Wl,-rpath,'$$ORIGIN/../lib'
Now, I don't necessarily need to do this on the library (openssl) itself. I can do this on the calling executable instead. If the library has no rpath, the rpath on the executable gets used next. In short, I don't need to stress that ldd -r <library> is returning the wrong path, provided that ldd -r <executable> returns the correct path.
I can test by library with the following command:
env LD_LIBRARY_PATH=$PWD ldd -r <library>
And once my executable is compiled, I can verify everything like this:
ldd -r <executable>
Long story short, everything is working just fine, don't get hung up on what ldd -r <library> is returning, just worry about ldd -r <executable>.
./config --prefix=/data/services/openssl-1.0.2g shared zlib -I/data/services/zlib-1.2.7/include -L/data/services/zlib-1.2.7/lib

/usr/bin/ld: cannot find -lGL (Nvidia, (L)Ubuntu 12.10)

I'm failing to link against OpenGL in my C++/Qt5 projects. I link using the following command:
g++ -m64 -Wl,[...] -o [...] [...].o \
-L/usr/X11R6/lib64 -L[...]/qt-5.0.0/5.0.0/gcc_64/lib \
-lQt5Widgets -lQt5Network -lQt5Gui -lQt5Core -lGL -lpthread
I hope the [...] aren't hiding something important. If you think they are, please let me know.
I get the following error:
/usr/bin/ld: cannot find -lGL
I'm on an Lubuntu 12.10 system and using Qt5 from http://qt-project.org/downloads. Since the system is newly installed, the first thing I did was installing Ubuntu's nvidia-current package and I rebooted. Among others, the following libraries have been installed on my system:
$ ll /usr/lib/nvidia-current/
[...]
lrwxrwxrwx 1 root root 10 Oct 6 04:58 libGL.so -> libGL.so.1
lrwxrwxrwx 1 root root 15 Oct 6 04:58 libGL.so.1 -> libGL.so.304.43
-rw-r--r-- 1 root root 1076560 Oct 6 04:58 libGL.so.304.43
[...]
I googled on how to add this path to the default library search path, as I guessed that g++ doesn't look in the subfolder nvidia-current but only in /usr/lib. So I added the path to ld.conf.d in Ubuntu. I updated ldconfig and checked with the following command:
$ ldconfig -p | grep libGL.so
libGL.so.1 (libc6,x86-64) => /usr/lib/nvidia-current/libGL.so.1
libGL.so.1 (libc6) => /usr/lib32/nvidia-current/libGL.so.1
libGL.so (libc6,x86-64) => /usr/lib/nvidia-current/libGL.so
libGL.so (libc6) => /usr/lib32/nvidia-current/libGL.so
So everything looks just fine!
Still (even after rebooting), the error from above appears. Am I missing something?
Edit:
After adding -L/usr/lib/nvidia-current/, everything works fine. But it seems that this is not the correct way to link against a library in a default path.
It's common for distributions to install graphics drivers' libGL not into the system library path, but some additional directory in /usr/lib to allow for installing different variants of libGL.so on the same system. Then symlinks to the active libGL.so are created by some centralized configuration system, for example alternatives as used by Ubuntu and Debian. It may very well be, that this configuration step failed.
/usr/lib/nvidia-current is not a standard library path and hence the library is not found; this also should mean, that OpenGL programs should not work. Maybe the Ubuntu folks do something with the LD_LIBRARY_PATH environment variable to circumvent this.
Personally I suggest that you add symlinks, as you should always have libGL.so in the defaul library path, preferrably /usr/lib or on 32/64 bit multilib systems in /usr/lib64 and /usr/lib32
/usr/lib/libGL.so.1 => /usr/lib/nvidia-current/libGL.so.1
/usr/lib32/libGL.so.1 => /usr/lib32/nvidia-current/libGL.so.1
/usr/lib/libGL.so => /usr/lib/nvidia-current/libGL.so
/usr/lib32/libGL.so => /usr/lib32/nvidia-current/libGL.so
You can also do this using the alternatives system, adding a new alternative.