1

I want to add a program to my $PATH, but its code is split into various files that it imports at run-time from a lib/ in its root directory.

projectRootDirectory
├ programBinary
└ lib
  ├ someLibrary
  └ someLibrary2

How do I add such a program to my $PATH without it complaining about missing dependencies?


I'd normally get the binary into /usr/local/bin by

  • copying

    cp /path/to/programBinary /usr/local/bin
    
  • or symlinking

    cd /usr/local/bin
    ln -s /path/to/programBinary programBinary
    

but both make it fail to find its dependencies.

I can't move the whole directory into /usr/local/bin because some of the required files are executables too, which I don't want cluttering my $PATH.

How should I be doing this?

3
  • What is the error? Mar 9, 2015 at 12:38
  • It's expecting particular libraries to be present in the same directory as the executable. (For this particular program, the message is : "Unable to access jarfile: /usr/local/bin/savilerow.jar" when symlinked in /usr/local/bin.)
    – Anko
    Mar 9, 2015 at 12:42
  • 1
    This is what binary packages are for. I recommend learning how to make a binary package for your distribution, if you don't know how to do so already. You'll find most of these issues go away. The two major flavors are, of course, rpm and deb. Mar 9, 2015 at 13:23

2 Answers 2

2

You can of course add projectRootDirectory to your $PATH, but this has at least two drawbacks:

  • It looks like, the way you are describing it, this particular project does not organize its project nicely into bin and lib subdirectories like so:

    projectRootDirectory
    ├ bin
    │ └ programBinary
    └ lib
      ├ someLibrary
      └ someLibrary2
    

    therefore you'd be forced to put projectRootDirectory itself into the $PATH, and since that contains other things besides binaries intended for execution, it's a bit ugly.

  • If you have many similar projects, the contents of your $PATH will proliferate out of control.

Instead, the simplest thing you can probably do in this particular case is to place a wrapper executable in /usr/local/bin, which is a very simple shell script that just runs the "real" program from the location where it lives.

#!/bin/sh
exec projectRootDirectory/programBinary "$@"

Since the wrapper script is calling it with its full pathname, it will probably be able to locate its auxiliary files in the manner it normally does.

1

There are many ways of different complexity to approach that issue, and what fits best depends on your "packaging philosophy".

The approach I'd probably choose is to have a wrapper script in your /usr/local/bin directory that does nothing but setting the exported PATH variable, modified by your library path, and call the main program in your library path; in this case all executables would reside in your lib directory, only the initial wrapper script in /usr/local/bin. (The locally defined PATH variable will only be inherited by the called processes and not taint the calling environment.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.