Advertisement

Self-contained programs :)

Started by August 19, 2005 12:49 AM
6 comments, last by 255 19 years, 2 months ago
For the lack of a better word I know with "Self-contained programs" I mean a linux program, that I untar and run without the need to check for package dependancies, etc. I want all of the necessary packages to be included in the distribution. How can I do it? Any ideas? In Windows this is fairly easy but I have no idea how to do it in Linux.
Another nameless person in the virtual space...
I've found this to be a bit of a problem myself.
You can link your program statically, just give -static flag to gcc. Problem is that you'll likely want to link to at least some dynamic libraries for various reasons and for some libraries there aren't static libraries.
I guess the best way is to just check which libraries your program links to with ldd and then try to link statically to libraries that you don't expect to be installed on the users PC.
Advertisement
You could package any library dependencies along with your program, so you have a file structure like:
/path/to/program:     program    data/    lib/      

Put all of the dependency libraries into /path/to/program/lib/. Instead of linking via ldd, have your program manually dlopen the libraries you want, and if they're not found in the global directories, dlopen the library from /path/to/program/lib/. Here's a short example program which looks for libSDL.so and libsomelib.so
#include "cstdio"   // printf#include "unistd.h" // getcwd#include "dlfcn.h"  // dlopen#include "string"   // std::stringint main () {   std::string libraries [] = { "libSDL", "libsomelib" };   char cwd_buf[80] = {0};   void *handle [2];   int i;   for (i = 0; i < 2; i++) {      handle = dlopen ((libraries + ".so").c_str(), RTLD_NOW);      if (NULL == handle) {         std::string local_path = "";         printf ("Can't find %s globally, falling back ... ",            libraries.c_str());         getcwd (cwd_buf, 79);         local_path = cwd_buf;         local_path += "/lib/";         handle = dlopen ((local_path + libraries + ".so").c_str(), RTLD_LAZY);         if (NULL == handle) {            printf ("Still cant open in ./lib/ -- FAIL\n");         } else {            printf ("Found locally.  Success!\n");         }      } else {         printf ("Found %s globally. Success!\n", libraries.c_str());      }   }   return 0;}


The plusses in the code seemed to disappear in the preview, so I hope they're visible to you -- otherwise, assume where there are arbitrary spaces in the code that there is a +.

Hope that helps.
__KB
Thank you! This is very interesting. I have to try it. Unfortunately I don't know much about Linux programming, that's why I'm going to do my project mostly on Linux.

What about starting the program with some script, that sets the PATH to the libs location? I think Neverwinter Nights does this for the SDL library but I couldn't make it work :) for me for some reason. Is it possible that way?


Another nameless person in the virtual space...
Yes. Many games do this.
The variable you are looking for is LD_LIBRARY_PATH, however. PATH is only searched for executable binaries.
Yes, you are right! I tried to use this env. variable but it wouldn't work.

BTW if I have one library version installed and another one in the application folder, which one will the application use? How can I know that?
Another nameless person in the virtual space...
Advertisement
id depends on what is set in LD_LIBRARY_PATH and in ld.so.cache (generated from /etc/ld.so.conf). First LD_LIBRARY_PATH is searched, then entries in ld.so.cache, then standard locations like /lib,/usr/lib,etc. Some steps are skipped for some programs(setuid/gid for example)

see man ld.so
Quote: Original post by NamelessTwo
BTW if I have one library version installed and another one in the application folder, which one will the application use? How can I know that?

If you are using LD_LIBRARY_PATH then the paths that are listed first are preferred.

This topic is closed to new replies.

Advertisement