1
votes

I am currently porting my OGRE 3D-based C++ application from pure Windows to Linux. I am using Ubuntu 18.04 LTS and a manually build OGRE 3D 1.12.1 which was compiled and installed to /usr/local/lib and /usr/local/lib/OGRE which is the default install location.

See:

$ ls -lah /usr/local/lib/
total 9,2M
drwxr-xr-x  6 root root  4,0K Aug  3 11:38 .
drwxr-xr-x 10 root root  4,0K Feb 10 01:12 ..
lrwxrwxrwx  1 root root    22 Aug  3 11:38 libOgreBites.so -> libOgreBites.so.1.12.1
-rw-r--r--  1 root root  337K Aug  3 11:33 libOgreBites.so.1.12.1
-rw-r--r--  1 root root  681K Aug  3 11:21 libOgreGLSupport.a
lrwxrwxrwx  1 root root    21 Aug  3 11:38 libOgreHLMS.so -> libOgreHLMS.so.1.12.1
-rw-r--r--  1 root root  177K Aug  3 11:36 libOgreHLMS.so.1.12.1
lrwxrwxrwx  1 root root    21 Aug  3 11:38 libOgreMain.so -> libOgreMain.so.1.12.1
-rw-r--r--  1 root root  5,7M Aug  3 11:20 libOgreMain.so.1.12.1
lrwxrwxrwx  1 root root    33 Aug  3 11:38 libOgreMeshLodGenerator.so -> libOgreMeshLodGenerator.so.1.12.1
-rw-r--r--  1 root root  362K Aug  3 11:34 libOgreMeshLodGenerator.so.1.12.1
lrwxrwxrwx  1 root root    24 Aug  3 11:38 libOgreOverlay.so -> libOgreOverlay.so.1.12.1
-rw-r--r--  1 root root  576K Aug  3 11:28 libOgreOverlay.so.1.12.1
lrwxrwxrwx  1 root root    25 Aug  3 11:38 libOgreProperty.so -> libOgreProperty.so.1.12.1
-rw-r--r--  1 root root   79K Aug  3 11:34 libOgreProperty.so.1.12.1
lrwxrwxrwx  1 root root    31 Aug  3 11:38 libOgreRTShaderSystem.so -> libOgreRTShaderSystem.so.1.12.1
-rw-r--r--  1 root root  1,3M Aug  3 11:31 libOgreRTShaderSystem.so.1.12.1
drwxr-xr-x  3 root root  4,0K Aug  3 11:38 OGRE
drwxr-xr-x  2 root root  4,0K Aug  3 11:38 pkgconfig
drwxrwsr-x  4 root staff 4,0K Jun 23 15:36 python2.7
drwxrwsr-x  3 root staff 4,0K Feb 10 01:12 python3.6

$ ls -lah /usr/local/lib/OGRE
total 1,2M
drwxr-xr-x 3 root root 4,0K Aug  3 11:38 .
drwxr-xr-x 6 root root 4,0K Aug  3 11:38 ..
drwxr-xr-x 2 root root 4,0K Aug  3 11:38 cmake
lrwxrwxrwx 1 root root   25 Aug  3 11:38 Codec_FreeImage.so -> Codec_FreeImage.so.1.12.1
-rw-r--r-- 1 root root  70K Aug  3 11:26 Codec_FreeImage.so.1.12.1
lrwxrwxrwx 1 root root   20 Aug  3 11:38 Codec_STBI.so -> Codec_STBI.so.1.12.1
-rw-r--r-- 1 root root 200K Aug  3 11:26 Codec_STBI.so.1.12.1
lrwxrwxrwx 1 root root   30 Aug  3 11:38 RenderSystem_GL3Plus.so -> RenderSystem_GL3Plus.so.1.12.1
-rw-r--r-- 1 root root 886K Aug  3 11:26 RenderSystem_GL3Plus.so.1.12.1

My CMake build is finding all the required libraries (also the ones in /usr/local/lib/OGRE), but after I have compiled my binaries, my Ubuntu is unable to find the shared libraries located under /usr/local/lib/OGRE:

$ ldd client 
    linux-vdso.so.1 (0x00007ffd2fde2000)
    libhoibase.so => /home/thomas/game/build/hoibase/libhoibase.so (0x00007fbcb3b0c000)
    libOgreMain.so.1.12.1 => /usr/local/lib/libOgreMain.so.1.12.1 (0x00007fbcb343e000)
    libOgreBites.so.1.12.1 => /usr/local/lib/libOgreBites.so.1.12.1 (0x00007fbcb31fc000)
    libOgreOverlay.so.1.12.1 => /usr/local/lib/libOgreOverlay.so.1.12.1 (0x00007fbcb2f8a000)
    libOgreRTShaderSystem.so.1.12.1 => /usr/local/lib/libOgreRTShaderSystem.so.1.12.1 (0x00007fbcb2c77000)
    RenderSystem_GL3Plus.so.1.12.1 => not found
    libSDL2-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0 (0x00007fbcb2945000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fbcb25bc000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fbcb221e000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fbcb2006000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbcb1c15000)
    libCGAL.so.13 => /usr/lib/x86_64-linux-gnu/libCGAL.so.13 (0x00007fbcb19f6000)
    libuuid.so.1 => /lib/x86_64-linux-gnu/libuuid.so.1 (0x00007fbcb17ef000)
    libgmp.so.10 => /usr/lib/x86_64-linux-gnu/libgmp.so.10 (0x00007fbcb156e000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fbcb136a000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fbcb114b000)
    libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007fbcb0e13000)
    libXt.so.6 => /usr/lib/x86_64-linux-gnu/libXt.so.6 (0x00007fbcb0baa000)
    libXaw.so.7 => /usr/lib/x86_64-linux-gnu/libXaw.so.7 (0x00007fbcb0936000)
    libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007fbcb0682000)
    libasound.so.2 => /usr/lib/x86_64-linux-gnu/libasound.so.2 (0x00007fbcb037b000)
    libpulse.so.0 => /usr/lib/x86_64-linux-gnu/libpulse.so.0 (0x00007fbcb012b000)
    libsndio.so.6.1 => /usr/lib/x86_64-linux-gnu/libsndio.so.6.1 (0x00007fbcaff1b000)
    libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007fbcafd09000)
    libXcursor.so.1 => /usr/lib/x86_64-linux-gnu/libXcursor.so.1 (0x00007fbcafaff000)
    libXinerama.so.1 => /usr/lib/x86_64-linux-gnu/libXinerama.so.1 (0x00007fbcaf8fc000)
    libXi.so.6 => /usr/lib/x86_64-linux-gnu/libXi.so.6 (0x00007fbcaf6ec000)
    libXrandr.so.2 => /usr/lib/x86_64-linux-gnu/libXrandr.so.2 (0x00007fbcaf4e1000)
    libXss.so.1 => /usr/lib/x86_64-linux-gnu/libXss.so.1 (0x00007fbcaf2dd000)
    libXxf86vm.so.1 => /usr/lib/x86_64-linux-gnu/libXxf86vm.so.1 (0x00007fbcaf0d7000)
    libwayland-egl.so.1 => /usr/lib/x86_64-linux-gnu/libwayland-egl.so.1 (0x00007fbcaeed5000)
    libwayland-client.so.0 => /usr/lib/x86_64-linux-gnu/libwayland-client.so.0 (0x00007fbcaecc6000)
    libwayland-cursor.so.0 => /usr/lib/x86_64-linux-gnu/libwayland-cursor.so.0 (0x00007fbcaeabe000)
    libxkbcommon.so.0 => /usr/lib/x86_64-linux-gnu/libxkbcommon.so.0 (0x00007fbcae87f000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fbcae677000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fbcb4350000)
    libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007fbcae44f000)
    libSM.so.6 => /usr/lib/x86_64-linux-gnu/libSM.so.6 (0x00007fbcae247000)
    libICE.so.6 => /usr/lib/x86_64-linux-gnu/libICE.so.6 (0x00007fbcae02c000)
    libXmu.so.6 => /usr/lib/x86_64-linux-gnu/libXmu.so.6 (0x00007fbcade13000)
    libXpm.so.4 => /usr/lib/x86_64-linux-gnu/libXpm.so.4 (0x00007fbcadc01000)
    libpng16.so.16 => /usr/lib/x86_64-linux-gnu/libpng16.so.16 (0x00007fbcad9cf000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fbcad7b2000)
    libpulsecommon-11.1.so => /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-11.1.so (0x00007fbcad534000)
    libdbus-1.so.3 => /lib/x86_64-linux-gnu/libdbus-1.so.3 (0x00007fbcad2e7000)
    libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007fbcad0d2000)
    libXrender.so.1 => /usr/lib/x86_64-linux-gnu/libXrender.so.1 (0x00007fbcacec8000)
    libXfixes.so.3 => /usr/lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007fbcaccc2000)
    libffi.so.6 => /usr/lib/x86_64-linux-gnu/libffi.so.6 (0x00007fbcacaba000)
    libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007fbcac8b6000)
    libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007fbcac6b0000)
    libsystemd.so.0 => /lib/x86_64-linux-gnu/libsystemd.so.0 (0x00007fbcac42c000)
    libwrap.so.0 => /lib/x86_64-linux-gnu/libwrap.so.0 (0x00007fbcac222000)
    libsndfile.so.1 => /usr/lib/x86_64-linux-gnu/libsndfile.so.1 (0x00007fbcabfa9000)
    libasyncns.so.0 => /usr/lib/x86_64-linux-gnu/libasyncns.so.0 (0x00007fbcabda3000)
    liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007fbcabb7d000)
    liblz4.so.1 => /usr/lib/x86_64-linux-gnu/liblz4.so.1 (0x00007fbcab961000)
    libgcrypt.so.20 => /lib/x86_64-linux-gnu/libgcrypt.so.20 (0x00007fbcab646000)
    libnsl.so.1 => /lib/x86_64-linux-gnu/libnsl.so.1 (0x00007fbcab42c000)
    libFLAC.so.8 => /usr/lib/x86_64-linux-gnu/libFLAC.so.8 (0x00007fbcab1b5000)
    libogg.so.0 => /usr/lib/x86_64-linux-gnu/libogg.so.0 (0x00007fbcaafac000)
    libvorbis.so.0 => /usr/lib/x86_64-linux-gnu/libvorbis.so.0 (0x00007fbcaad81000)
    libvorbisenc.so.2 => /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2 (0x00007fbcaaad8000)
    libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007fbcaa8bd000)
    libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0 (0x00007fbcaa6a8000)

What am I doing wrong? What is the trick to make Ubuntu find my RenderSystem_GL3Plus.so.1.12.1?

1
You might want to add a file /etc/ld.so.conf.d/ogre.conf containing a line with the path /usr/local/lib/OGRE. After that you should run ldconfig once to update its cache.Lars Fischer
The problem, is that /usr/local/lib/OGRE isn't in the run-time linker path. Either solve it as mentioned above (by editing the run-time linker configuration) or tell the linker the path with the option -Wl,-rpath=/usr/local/lib/OGRE when building.Some programmer dude

1 Answers

1
votes

I am currently porting my OGRE 3D-based C++ application from pure Windows to Linux. I am using Ubuntu 18.04 LTS and a manually build OGRE 3D 1.12.1 which was compiled and installed to /usr/local/lib and /usr/local/lib/OGRE which is the default install location...

As others have stated, the various OGRE libraries cannot be found by the runtime linker. When executing in the build folder, you usually use LD_LIBRARY_PATH to provide the override you need to put a library on path.

Once you perform a make install the binary should be able to find the library because either (1) library is in a well known path; or (2) binary has a RUNPATH with the location of the library. Sometimes you use (3) use LD_LIBRARY_PATH after install. Doing (3) kind of sucks and you should avoid it.

It sounds like the program client lacks a RUNPATH with the location of OGRE libraries. client should have a DT_RUNPATH with /usr/local/lib/OGRE (and not a DT_RPATH). Also see Is there a way to inspect the current rpath on Linux?.

You want a DT_RUNPATH because DT_RUNPATH allows LD_LIBRARY_PATH overrides. DT_RPATH does not allow LD_LIBRARY_PATH overrides.

If the RUNPATH is not there, then add it with LDFLAGS += -Wl,-R,/usr/local/lib/OGRE -Wl,--enable-new-dtags. In CMake, you add linker flags using CMAKE_MODULE_LINKER_FLAGS, CMAKE_SHARED_LINKER_FLAGS and CMAKE_STATIC_LINKER_FLAGS. -Wl,-R,/usr/local/lib/OGRE -Wl,--enable-new-dtags should be added to each one you are using. Also see How to set the LDFLAGS in CMakeLists.txt?.

Note: you probably need to add the options to LDFLAGS for both client and the OGRE libraries since the OGRE libraries probably have dependencies on one another.


Something a little more flexible for you may be to use -Wl,-R,'$$ORIGIN/../lib/OGRE' -Wl,--enable-new-dtags. $ORIGIN is where your program is located, and it tells the runtime linker to look in the relative directory ../lib/OGRE for its libraries. It allows you to move your program (in .../bin/) and libraries (in .../lib/ and .../lib/OGRE) around on the filesystem.


You can thank the glibc folks for the Linux path problems that have plagued Linux for the last 25 years or so. They think it is normal to compile against a version of a library, link against a version of the library, and then load the wrong version of the library at runtime or lose the library at runtime. They should get a Darwin Award for not fixing the idiotic decision.

(Making the wrong descision was OK since we all make mistakes. However, they have never fixed it. Instead they allow these problems to fester for decades.)