Linux, C++, ThirdParty libs
Asked Answered
B

3

15

Ok just a simple question. I am programming in Visual C++ on Windows and for learning purposes have changed to Ubuntu and started in Code::Blocks, CodeLite and Eclipse. I have written some simple program using SDL2 and GLEW to make a simple OpenGL application based on SDL2 windowing. I have downloaded libraries with commands:

sudo apt-get install...

My main question is: since this application is rellying on external libraries (SDL2, glew, flu, OIS), it doesn't work on other linux computers. After you install all those libraries using terminal commands then the program works otherwise will not execute. My question is, is it possible to build program that will not need to have those libraries installed. For example, on Windows you link your program to SDL2.lib and include SDL2.dll in .exe folder. How can I do that on linux. I have very little experience with linux programming and how stuff works, so I hope it's just a basic problem. :)

Booking answered 5/9, 2016 at 7:24 Comment(7)
You've started in three IDEs at once?Otha
> started in Code::Blocks, CodeLite and Eclipse .. seem's a bit excessive no?Porkpie
This question definitely deserves an answer, which covers LD_LIBRARY_PATH and rpath.Serrano
@Serrano LD_LIBRARY_PATH isn't really intended to be used for packaging, I'd only use it when where are no other options (like embedded systems with read-only root partition).Holmgren
BTW, have you considered putting your app in a Docker container?Holmgren
@DmitryGrigoryev I don't know about intent, but having a wrapper shell script, which sets LD_LIBRARY before launching the binary, is a popular approach for distro-independent binary packages. It's superior to rpath by not having hard-coded paths.Serrano
@DmitryGrigoryev Isn't Docker kinda... difficult for anything except network based apps? You will still need the launcher outside the docker, and go to extra effort to have seamless file/data access between the app and the host/desktop.Serrano
D
18

In Linux the equivalent to the dll files are .so files. So you need to deliver them with you.

You can also link statically against the libraries. Those should be the ending with .a. With those they get directly compiled into your program and you don't need to deliver those.

A more advanced (Linux-like) approach:

What is usually done in Linux (as an example now Debian/Ubuntu) you create a package (in case of debian a .deb-file - debian package). In those packages you can add meta information like on what other packages it depends (those packages can be installed via apt-get).

When you then install the package manually with dpkg it will tell you dependencies are missing and you can fix those with apt-get -f install. You can also create your own apt repository and it will install your program with the dependencies with just apt-get install ...

Other linux distributions have other package management systems. This is just as an example for debian/ubuntu.

Dewberry answered 5/9, 2016 at 7:31 Comment(9)
Thank you for help :) I have tried the Windows style and found libSDL2.a, libSDL2main.a... among other SDL libs in usr/lib/... I have added them to to executable folder and obviously it doesn't work :) I'm sure this isn't done the right way, I am beginner on Linux programming :) I will do more research on that :) Please let me know if there is anything that I need to try :)Booking
You should research how to link libraries with your compiler and see if you need anything specific for linking static libraries. when you then link the .a files you should not need to have them copied with you but they should be "inside" your binary.Dewberry
Note that the lookup rules for dlls on Windows and sos on Linux are fundamentally different. In Windows, it's enough to just put the dll next to the exe, in Linux stuff is significantly more involved. Also note that shipping binaries on Linux is far less trivial than on Windows. Just because your binary does work on one distro, does not mean it will work on another. There's good reasons why we have projects like Holy Build Box around.Cullen
@Cullen That really depends on some situations. While Linux may have those issues Windows also has the issue that the compiler versions are not binary compatible. So when you have 3rd party libs compiled with VS7 and you use 14 you cannot use them. You also have to have the VC_redistributable installed on the target systems, etc. So I would not call windows more trivial. It just has different issues.Dewberry
@Dewberry Shipping a different VC_redistributable is a relatively straightforward (although slightly annoying) matter, that is well supported. Shipping an incompatible version of GLIBC to a foreign distro is not. While I do agree that both platforms have their quirks to consider when it comes to shipping binaries, I would still argue that Linux is significantly harder to handle in this regard. (Which is not intended as a bashing of Linux; its philosophy of handling these things has lots of advantages as well.)Cullen
I guess it depends also on the "knowledge" to the system. Many things may seem easier for me in hindsight on Linux. (E.g. shipping your own libc/libc++). But I agree getting into how to do this may require more initial work whan windows.Dewberry
One thing to consider: Depending on the license of the library, static linking may have different legal consequences than dynamic linking.Orelee
@Dewberry Wait, you're saying it's straightforward to ship a different libc with your application than the one installed by default? I'd love to see the manual for that one, because you seem to be the only one to have found that (which is why we now have containers in say Ubuntu to actually make this simple).Amann
Not straightforward. As I said, in hindsight it seems more straightforward but you have to research the resources one by one (this is also not topic of the question anymore). But you can find it on google. I just ran into this issue when wanting to use modern c++ on old systems.Dewberry
P
5

In conjunction to the good answer from Hayt, I think it is worth mentioning that the "classical" UNIX approach would be a "compiles out of the box" solution. Meaning: you actually specify "external" dependencies that your program needs in order to be compiled; and you basically enable people to simply download some source archive; and upon extraction ... run

./configure
make
make install

or something like that on their system.

In that case, the "configure" tool checks for all required dependencies. See here for further reading.

Nowadays distributing DEB, RPM, ... packages is much more common; but there is a certain beauty in being able to just download some sources.tar.gz from somewhere; run those three commands and have a working installation, based on a local compile within a few minutes. Especially when your users might want to make changes to the source code. But of course, that requires much more thinking on your end - as you want to restrict your "dependencies" as much as possible; in other words: you want to be "as standard" as possible.

Primp answered 5/9, 2016 at 7:53 Comment(9)
Yeah I was thinking about adding this too. But it looked like he just wanted to distribute the binaries. Though in Linux usually you also provide the source code with you and this approach here is one for them (or other build environments such as automake, cmake etc). So for a "true" Linux approach you usually do both.Dewberry
Ok just to spice things up, I am actually building a simple Game Engine on Visual C++ on Windows. The engine is based on Win32 (for linux will obviously need to use something else, SDL for example ;) ), OpenGL, OIS, FreeImage... And I am currently learning how to program on Linux to be able to build the engine for Linux. So the program will be closed source ;) what is the best option for me then? To use static libraries or something else?Booking
You have to check the licenses of the 3rd party libraries. This depends on how you have to link against them. E.g. Qt you can only dynamically link against them when you have commercial interests etc. So it may be that you cannot link statically. I can also recommend cmake for you if you want to build on linux and windows.Dewberry
Ok thanks for reply :) I will check licences of libraries used. About cmake, I have tried to use it when I tried to build OGRE from source and I found it difficult to understand how it works. Do you have any links with tutorials/resources for learning to build using cmake?Booking
@Booking Two things: avoid getting into "discussions" mode in comments. And: questions about "recommendations" are fully off-topic on this site. Turn to your favorite search engine; I am sure that a person looking forward to do the things that you are describing here ... will be able to find information on cmake suitable for his needs! Just download stuff, and look into thigns.Primp
Wouldn't that replace the initial problem of missing libraries with a new problem of missing dev packages?Holmgren
@DmitryGrigoryev: it would automatize the process of finding the missing libraries/dev packages, and spare the developer the trouble of shipping them.Randall
@QuoraFeans Really? I have never seen configure installing required dev packages for me automatically. It was always "configure, get an error, google for relevant package names, install, repeat" routine.Holmgren
@DmitryGrigoryev: yes, really. But first you have to install auto-apt. When ./configure tries to access a file that doesn’t exist, auto-apt puts the ./configure process on hold, installs the appropriate package and lets the ./configure process continue.Randall
H
2

One way to make your application easy to install is to package it (assuming Ubuntu here). Suppose you have built your application called foobar. Create the following directory structure:

foobar_1.0/
|-- usr/local/bin
|             `-- foobar
`-- DEBIAN/
    `--  control

and put the following text in the DEBIAN/control file:

Package: foobar
Version: 1.0
Section: games
Priority: optional
Architecture: i386
Depends: libsdl2, libglew1.10, anotherLibrary, yetAnotherOne
Maintainer: Your Name <[email protected]>
Description: A neat package which does foo and bar

Now you can build your package with

dpkg-deb --build foobar_1.0

Your users then will have to install foobar with dpkg -i foobar_1.0.deb, which will install foobar in /usr/local/bin. This directory is dedicated for software you build from sources or install from non-official packages, avoiding possible name conflicts in /usr/bin (where binaries from official packages go).

If your users are missing any dependencies you have listed in DEBIAN/control, they will be told about it at installation time. Simply running apt-get -f install will install them. Removing foobar will also mark those dependencies as unused, so users will be prompted to remove them when they uninstall your package.

Holmgren answered 5/9, 2016 at 15:3 Comment(2)
This is good, but there is no free lunch: this gets tedious, if you want to support several distro "families" (.deb, .rpm, ...) and keep the packages compatible between several distros/versions using same packaging (Ubuntu LTS12.04 ... latest Debian unstable). And if you do go this route, it might be worth the effort to have a PPA for the package, so users can get updates automatically, which is a proven approach for established OSS apps.Serrano
@Serrano Of course. I only covered a start, something that could be done in 15 minutes or so.Holmgren

© 2022 - 2024 — McMap. All rights reserved.