I am making a small application with glfw. I'm not using CMake and instead opted to make a custom build system for more control, but I'm getting an error when trying to run my program:
error while loading shared libraries: libglfw.so.3: cannot open shared object file: No such file or directory
I know that shared objects are typically used for system packages that multiple applications will be relying on, and thus they have versions at the end (i.e. .so.3 or .so.3.5 in glfw), but I will be distributing my application with GLFW built in. For example, when I build my app, I have the following binaries built in the dist/ folder:
dist/
app
libengine.so
libglfw.so
libimgui.so
libbackend.so
As I'd rather not force users to install glfw system-wide just to try out my app. For this reason, I'd like to avoid having both libglfw.so and libglfw.so.3.
When I try and replace libglfw.so with libglfw.so.3 in the dist/ folder, I get a new compile-time error saying
/usr/bin/ld: cannot find -lglfw: No such file or directory
Having both libglfw.so and libglfw.so.3 obviously increases the total app size, which is also undesirable. And making a symlink makes it much more difficult to distribute. For this reason, I'd like to just keep my current setup with dist/ including only libglfw.so. But I can't get it to work for some reason (my -L path is just my dist/ directory, so I don't know why it's even looking for a libglfw.so.3). Does anyone know how to prevent my app from looking for a libglfw.so.3 file when being run?
I know that shared objects are typically used for system packages that multiple applications will be relying on, and thus they have versions at the end (i.e. .so.3 or .so.3.5 in glfw),
Shared objects are used for almost all programs these days. Even those that bundle (most of) their own dependencies.
but I will be distributing my application with GLFW built in.
I presume that you mean you will be bundling a copy of GLFW. If it were "built in" in the sense of being statically linked then the issue you are asking about would not arise. Plus, it's reasonably likely that you don't have GLFW available to you as a static library anyway.
As I'd rather not force users to install glfw system-wide just to try out my app. For this reason, I'd like to avoid having both libglfw.so and libglfw.so.3.
One has nothing to do with the other. If you're bundling GLFW then your application can rely on the bundled version. But that version does need to be named in a way that matches the library soname built into the application binary.
When I try and replace libglfw.so with libglfw.so.3 in the dist/ folder, I get a new compile-time error saying
/usr/bin/ld: cannot find -lglfw: No such file or directory
It sounds like you're not doing a good job of separating your build requirements from your runtime requirements. If you use -lglfw as a link option at build time, then the linker is going to look for a corresponding file named libglfw.so or libglfw.a. For build convenience, unversioned shared library names such as the former are commonly symbolic links to shared library files with versioned names, such as libglfw.so.3, in which case you need both at build / link time. But normally in such a case, the linked binary references only the latter name, so that's the only one you need at runtime.
Having both libglfw.so and libglfw.so.3 obviously increases the total app size
You don't need both in a binary distribution, but even if you did, the total size would be increased by a few bytes. Even a "Hello, World!" program in ELF format is going to be tens of kilobytes, so sweating the few bytes of symbolic link is kinda ludicrous.
And making a symlink makes it much more difficult to distribute.
I'm not clear on why that would be. Including symlinks in the distribution should be a minor inconvenience at most. Not that you should need to include the symlinks in a binary distribution anyway. Nor that you should be including shared library binaries in a source distribution.
I'd like to just keep my current setup with
dist/including onlylibglfw.so. But I can't get it to work for some reason (my-Lpath is just mydist/directory, so I don't know why it's even looking for alibglfw.so.3).
Again, you need to distinguish between build requirements and runtime requirements. The -L path is a build consideration. It is not directly relevant at runtime. If you bundle shared libraries in your binary distribution then they don't need to be at the same path as the copies that were used to link the executable at build time.
Does anyone know how to prevent my app from looking for a
libglfw.so.3file when being run?
This is a function of the library's soname, which is a property of the library binary. You could, in principle, build a bespoke copy of libglfw that has soname "libglfw.so", and build you application against that. Or perhaps even modify a copy of an existing binary. But don't do that. It would be much more trouble than it's worth.
For a source distribution, don't include library binaries at all. For a binary distribution, distribute only the versioned library binaries. For building a binary distribution from source, you need both, but not necessarily in your staging area for the distribution.