0

I have a C project running in Linux using OpenGL that's managed in git. Computer X and computer Y have the same version of the code pulled from git. We'd like to send the executable to a third-party machine, Z, for running. However, only the executable built on X computer works; the one that built in the VM of the Y computer failed to run on machine Z. Console on machine Z showed - error while loading shared library: libglut.so.3: cannot open shared object file: No such file or directory.

Question: why do the same code and the same project setting yield different results?

I'm looking into the difference between the X machine and Y machine. The first thing I tried was to look into the version of the OpenGL. ref:Terminal command to show OpenGL version?

X computer:

emilylin@linux:/lib/x86_64-linux-gnu$ glxinfo | grep "OpenGL version"
emilylin@linux:/lib/x86_64-linux-gnu$ 

VM of Y computer:

emilylin@linux:/usr/lib/x86_64-linux-gnu$ glxinfo | grep "OpenGL version"
OpenGL version string: 3.1 Mesa 21.2.6
emilylin@linux:/usr/lib/x86_64-linux-gnu$

Question: why I cannot find the gl version by using this command on X computer? Then, I looked into the executable linking path to see what I could find there. X computer:

emilylin@T:~/git/riv_port_replay_v2/Debug$ ldd ./riv_port_replay_v2 
linux-vdso.so.1 (0x00007ffdbc7fc000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007b317dbd7000)
libGL.so.1 => /lib/x86_64-linux-gnu/libGL.so.1 (0x00007b317db50000)
libglut.so.3.12 => /lib/x86_64-linux-gnu/libglut.so.3.12 (0x00007b317d747000)
libGLU.so.1 => /lib/x86_64-linux-gnu/libGLU.so.1 (0x00007b317daf7000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007b317d400000)
/lib64/ld-linux-x86-64.so.2 (0x00007b317dcd3000)
libGLdispatch.so.0 => /lib/x86_64-linux-gnu/libGLdispatch.so.0 (0x00007b317d68f000)
libGLX.so.0 => /lib/x86_64-linux-gnu/libGLX.so.0 (0x00007b317d65c000)
libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6 (0x00007b317d2c3000)
libXxf86vm.so.1 => /lib/x86_64-linux-gnu/libXxf86vm.so.1 (0x00007b317daee000)
libXi.so.6 => /lib/x86_64-linux-gnu/libXi.so.6 (0x00007b317d649000)
libOpenGL.so.0 => /lib/x86_64-linux-gnu/libOpenGL.so.0 (0x00007b317d61e000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007b317d000000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007b317d296000)
libxcb.so.1 => /lib/x86_64-linux-gnu/libxcb.so.1 (0x00007b317cfd7000)
libXext.so.6 => /lib/x86_64-linux-gnu/libXext.so.6 (0x00007b317d282000)
libXau.so.6 => /lib/x86_64-linux-gnu/libXau.so.6 (0x00007b317dae4000)
libXdmcp.so.6 => /lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007b317d616000)
libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007b317cfc1000)
libmd.so.0 => /lib/x86_64-linux-gnu/libmd.so.0 (0x00007b317cfb2000)

VM of Y computer:

emilylin@linux:~/git/remote_connect/riv_port_replay_v2/Debug$ ldd ./riv_port_replay_v2
linux-vdso.so.1 (0x00007ffc7974c000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f152923d000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f15290ee000)
libGL.so.1 => /lib/x86_64-linux-gnu/libGL.so.1 (0x00007f1529066000)
libglut.so.3 => /lib/x86_64-linux-gnu/libglut.so.3 (0x00007f1528e1d000)
libGLU.so.1 => /lib/x86_64-linux-gnu/libGLU.so.1 (0x00007f1528dab000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f1528da1000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1528bad000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1529556000)
libGLdispatch.so.0 => /lib/x86_64-linux-gnu/libGLdispatch.so.0 (0x00007f1528af5000)
libGLX.so.0 => /lib/x86_64-linux-gnu/libGLX.so.0 (0x00007f1528ac1000)
libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6 (0x00007f1528984000)
libXi.so.6 => /lib/x86_64-linux-gnu/libXi.so.6 (0x00007f1528972000)
libXxf86vm.so.1 => /lib/x86_64-linux-gnu/libXxf86vm.so.1 (0x00007f152896b000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f1528787000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f152876c000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f1528766000)
libxcb.so.1 => /lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f152873c000)
libXext.so.6 => /lib/x86_64-linux-gnu/libXext.so.6 (0x00007f1528727000)
libXau.so.6 => /lib/x86_64-linux-gnu/libXau.so.6 (0x00007f152871f000)
libXdmcp.so.6 => /lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f1528717000)
libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007f15286fd000)

Question: do libglut.so.3 and libglut.so.3.12 make a difference in the result? Further, I went to the /usr/lib to try to find the .so itself, but couldn't find it on the X computer! So why did it print /lib/x86_64-linux-gnu/libglut.so.3.12 (0x00007b317d747000) when I couldn't find it in the /usr/lib folder? While in the VM of Y computer I found a shared library named libglut.so as expected.

Update: I also gave the same command to machine Z. It has two executables that are built from machine X and machine Y. One of them has problem linking the libglut.so. console screenshot on machine Z running ldd Any idea on what caused this to happen?

1 Answers1

0

Question: do libglut.so.3 and libglut.so.3.12 make a difference in the result?

Yes they do. Programs that are dynamically linked are not guaranteed to be portable across different versions of Ubuntu.

In particular, when your program is built on Machine Y (Ubuntu 20.04, amd64 architecture), the linker ld will resolve the library directive -lglut as /usr/lib/x86_64-linux-gnu/libglut.so.3, which is a symbolic link to major.minor version /usr/lib/x86_64-linux-gnu/libglut.so.3.9.0 provided by the freeglut3 package. The library major version libglut.so.3 gets "baked in" to the executable program.

In Ubuntu 24.04, the GLUT runtime library is provided by the libglut3.12 package, which only provides /usr/lib/x86_64-linux-gnu/libglut.so.3.12, as a symbolic link to /usr/lib/x86_64-linux-gnu/libglut.so.3.12.0 - so the dynamic linker fails to resolve libglut.so.3.

This may just be a packaging oversight - it's possible that the newer library is actually ABI-compatible with the older one, and creating a symbolic link to libglut.so.3.12 named libglut.so.3 on the target Ubuntu 24.04 machine may allow your 20.04-built executable to run there (although I wouldn't recommend that as a solution).

See also How do SO (shared object) numbers work?

steeldriver
  • 142,475