how I get version of a program in linux - c++

In Windows you can do:
CSystemInfo info;
this->m_strVersion = info.GetFileVersion( CFileSystemHelper::GetApplicationPath() + _T("/test.exe") );
to get the version number.
How would I do it in C++ on linux ?

Windows adopts a version resource system with standard API support, Linux and UNIX have no such high level concepts for a variety of reasons ranging from legacy to redundancy.
Best options are to query the local packaging system (RPM, APT, etc), or try executing with --version command line parameter which is a recommended GNU standard.
Example RPM query on command line for the Samba tool smbget:
# rpm -q -f /usr/bin/smbget --queryformat '%{version}\n'
3.0.33

You probably want to retrieve the path of the currently executing executable.
On Linux, you could use the /proc/ pseudo-file system. Read the proc(5) man page for more.
Specifically, you probably want to do something like
char myexepath[512];
memset (myexepath, 0, sizeof(myexepath);
readlink ("/proc/self/exe", myexepath, sizeof(myexepath));
(but you really should check for runtime errors above)
If you simply wanted to display the version of a program, you should have a convention about it. Usually accepting --version as the program first argument.
I invite you to read Advanced Linux Programming.

Related

Installing HDF5 library on Cygwin: "make check" stuck at testswmr.sh, no error message

I am currently installing the HDF5 library, more precisely the hdf5-1.10.0-patch1, on Cygwin, as I want to use it with Fortran. Following the instructions from the hdfgroup website
(here is the link), I did the following:
./configure --enable-fortran
make > "out1_check.txt" 2> "warn1_check.txt" &
make check > "out2_check.txt" 2> "warn2_check.txt" &
The execution of the last command (make check) proceeds as it should, until it gets stuck. The process does not stop and something is happening (8-12% CPU are in use by sh.exe, already 39 hours of CPU time) but "out2_check.txt" looks like
Making check in src
...
[many successful checks]
...
============================
No need to test testlinks_env.sh again.
============================
============================
Testing testswmr.sh
Unfortunately, I do not have the output file from the first run of make check, but it did not contain more information on Testing testswmr.sh. There was never any error message.
So, what is this testswmr.sh, why does it get stuck and how can I finalize the installation process? Maybe I can skip the remaining checks and just proceed to make install?
Important note: an older version of HDF5 is already installed from the Cygwin repo. It does not seem to support Fortran however, so I decided to install the current version myself.
Available (and used) compilers are gcc and gfortran.
As far as I can tell, only Intel Fortran is supported on Windows. There is no Cygwin download here https://support.hdfgroup.org/HDF5/release/obtain518.html and I have never come across a report of experience for Cygwin/Fortran/HDF5.
Your options:
Use Intel Fortran
Use Linux or Mac
Sorry

in the code (.c file) how I can find the linux distribution name version

I'd like to know in the code (.c file) how I can find the linux distribution name version (like ubuntu 10.0.4, or centOS 5.5...)?
The c function that I'm looking for should be like the uname() system call used in (.c files) to get kernel version.
it will be appreciated that the function is working for all linux distribution (standard)
I 'm not looking to get distribution name and version by the use of command line linux from code (.c file) (like the use of system("cat /etc/release");).
Any suggestion will be appreciated!
Regards
There is no standard for this yet. You can query following files or check for existence:
/etc/lsb-release
/etc/issue
/etc/*release
/etc/*version
Well, you can (and should) use fopen and fgets instead of system("cat"), for reading /etc/release.
There's no universal method though, I can even build a linux image which has no filesystem at all (except initramfs) and definitely no distribution name.
AFAIK there isn't a standard system call to get this if uname(2) doesn't give you enough info.
Safest approach is probably to check for "/proc/version" and read that
You could fopen("/etc/lsb-release") and parse its contents. It looks like this:
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=10.04
DISTRIB_CODENAME=lucid
DISTRIB_DESCRIPTION="Ubuntu 10.04.3 LTS"
This method is not universal. You'll need to make sure that it works on all distros that you care about (if it doesn't, I suggest you go with #ott--'s answer).
Is it acceptable to run some shell commands?
$ /usr/bin/lsb_release -r
Release: 11.04
$ /usr/bin/lsb_release -d
Description: Ubuntu 11.04
$ /usr/bin/lsb_release -rd
Description: Ubuntu 11.04
Release: 11.04
There is no portable way to do that, you'll have to use some OS detection tool/library.
Fortunately, there are a few out there. I know those 2 :
Facter, a professional (yet free/open) information gathering program in ruby : http://puppetlabs.com/puppet/related-projects/facter/
a shell script : http://www.novell.com/coolsolutions/feature/11251.html
(I used facter via puppet and it is very good.)
With a little additional scripting, you can use one of those program's output to generate a .h that you can then use in your code.
You can even integrate this generation as a step in your makefile.
I usually inspect /etc/issue; while (as others pointed out) it is not guaranteed, I've fount in the field that's quite reliable.
As far as I've experienced, it works on ubuntu, debian, redhat, centos, slackware and archlinux.

How does the OS language represented in Linux

My Application is running in Linux.
it would be localized.
how can I get the OS Language?
is it represented in Linux?
as a numeric values?
See the question at SuperUser:
https://superuser.com/questions/62031/how-to-change-the-linux-localization
If you just want to know which locales are supported, you can see which are installed, which can be done in Debian by doing a:
ls -l /usr/share/locale
I guess the locale named "C" (the default locale name, which is just english) should always be installed.
And if you want to set the locale, just use:
export -n LC_ALL=de_DE
for German, e.g.
Since most of your other questions relate to Qt, you might want to read the documentation of the static function QLocale::system()
You can find some useful information in the GLibC Manual.

Mac OSX and Unix quick questions

I have 3 questions. I am making a C++ executable to launch a Perl program I made. I will compile it for Winows, Mac OSX and Linux. It's pretty much just: system("perl progam.pl");
When compiled with Mac OSX, the program starts in ~. How would I get it to start in the dir it was launched from, or is it just a problem with the compiler?
I'm using - echo -n -e "\033[0;Program\007" - in an attempt to make the windows title "Program". Is this is best way?
I'm using - echo -n -e "\033[7;30;47m" - to make the background of the window black. Is this the best way?
Thanks.
This sounds like something Finder is doing. Launching the app from a shell should work as you expect.
Use tput
See answer to 2, above.
On Mac OS/Unix, invoking system does not change the current working dir. When executing program.pl the current working directory is the same from which you executed the C++ executable. When you launch the executable using Launch Services (e.g. the Finder) the working directory should be /.
On #1 you can refer to the current directory with ./ so system("perl ./progam.pl"); should do it assuming both scripts are sitting in the same folder. ../program.pl would be one level higher.
For #1, use getcwd & then pass an explicit path to system:
cwd=getcwd(NULL, PATH_MAX);
sprintf(cmd, "perl %s/program.pl", cwd);
system(cmd);
free(cwd);
If your perl program itself relies on a specific working directory, then do this instead:
sprintf(cmd, "cd %s && perl program.pl", cwd);
This is probably a silly question, but why are you making an application to launch a perl script? Just add the following to the top of your perl script and use "chmod a+x" to make it executable:
#! /usr/bin/perl
When you use the system command from C and C++, you are basically launching the default system shell and executing the given command in that shell. Doing that is not very portable and somewhat defeats the purpose of using C or C++ (since you could simply create a shell script that does the same thing). If you want to actually do this with C++, you should probably use popen or fork+exec to launch perl. Generally speaking, it isn't nice to end users to play with their Terminal in the manner that you have proposed; most users, by default, have the Terminal configured to display the most recently executed command or their current directory or some other information of their choosing, and changing that is -- on UNIX systems such as Mac OS X and Linux -- considered improper etiquitte. If you are trying to create a terminal interface, though, you might want to look at the curses library.

Profiling C++ with Google Perf tools and Dynamic Libraries

I'm trying to profile a C++ application, that I did not write, to get a sense for where the major computation points are. I'm not a C++ expert and even less so C++ debugging/profiling expert. I believe I am running into a (common?) problem with dynamic libraries.
I compile link to Google CPU Profiler using (OS X, G++):
env LIBS=-lprofiler ./configure
make
make install
I then run profile the installed application (jags) with:
env CPUPROFILE=./jags.prof /usr/local/bin/jags regression.cmd
pprof /usr/local/bin/jags jags.prof
Unfortunately, I get the error:
pprof /usr/local/bin/jags jags.prof Can't exec "objdump":
No such file or directory at /usr/local/bin/pprof line 2833.
objdump /System/Library/Frameworks/Accelerate.framework/Versions/A/
Frameworks/vecLib.framework/Versions/A/libLAPACK.dylib: No such file or directory
The program dynamically links to libLAPACK.dylib. So prof does not seem to understand it (?). I thought about trying to statically link, but the documents associated with the program say that it is impossible to statically link in LAPACK or BLAS (two required libraries).
Is there a way to have the profiler ignore libLAPACK? I'm okay if it doesn't sample within libLAPACK. Or how might I get profiling to work?
This error was caused by jags being a shell script, that subsequently called profilable code.
pprof /usr/local/bin/REAL_EXEC jags.prof
fixes the problem.
I don't see a clean way to do it, but maybe there's a hacky workaround -- what happens if you hack the pprof perl script (or better a copy thereof;-), line 2834, so that instead of calling error it emits the message and then does return undef;?
If you're profiling on OSX, the Shark tool is really great as well. It's very simple to use, and has worked out of the box for me when I've tried it.