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.
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.
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.
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
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).
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().