views:

111

answers:

4

I have an application which had optional extras depending on if the user has the software installed.

On Linux what is the best way to determine if something like python and PyUsb is installed?

I am developing a C++ Qt application if that helps.

+1  A: 

You can require that they be in the path, etc. Check for the existence of the executable files you will require (using which or similar). You can also use the executable files' arguments and check for required versions as well, if needed.

Kris Kumler
+1  A: 

I'm not aware of a way to do that for Linux in general, since each distro can have its own package manager. But assuming you want to support the most popular distros, you can query their package manager for installed software (I'd suggest as a start to support apt-get, rpm and yum) and parse the output to look for the packages you recognize. Each manager has a way to list the installed packages, my suggestion as a start:

apt-get --no-act check
rpm -qa
yum list installed
Fabio Ceconello
There's a caveat: if the user installed something without using the corresponding package manager (using make install directly), you won't detect it.
Fabio Ceconello
A: 

One other possibility is to present all the features to the user and prompt them to install extras if they try to use them (e.g. see http://0install.net).

Thomas Leonard
+1  A: 

This is inefficient (requires forking and exec'ing /bin/sh). There has to be a better way! But as a generic approach... There's always system().

(Remember to use WEXITSTATUS()! Watch out for making programs uninterruptable!)

#define SHOW(X)  cout << # X " = " << (X) << endl

int main()
{
  int status;

  SHOW( status = system( "which grep > /dev/null 2>&1" ) );
  SHOW( WEXITSTATUS(status) );

  SHOW( status = system( "which no_matching_file > /dev/null 2>&1" ) );
  SHOW( WEXITSTATUS(status) );
}

There is also popen(), which can be useful for grabbing output from programs to verify version numbers, libraries, or whatnot.

If you need bidirectional (read&write) access to a subprocess, best to use pipe(), fork(), exec(), close(), & dup2().

Mr.Ree