views:

155

answers:

2

I want my C++ program to include a "--version" option which causes it to print out:

  • Architecture it's compiled for
  • Version of the source (e.g., v0.1.0)
  • Name of the application

I'm also using autoconf/automake for the first time, and I notice that configure.ac has both the binary and the version. It doesn't currently have architecture information in it, and I don't want to add such info, since I'll be compiling under multiple arches.

Is there an easy way to automate the insertion of the version/arch/appname information in a header or source file? How do most C++ coders do this?

+1  A: 

Write a python script that generate your version source file. Then make it run by whatever build scripts/tool you're using.

Choose a rule to actually rewrite the version file and enforce it in the python script : it's really dependent on the type of project and release organisation you're doing.


In my home project I use a script that generate a version file each time I build, because I need to know wich computer-developer built the version and at wich time.

But in a lot of job works I used a script that generated the version file but only if I wanted it to. That's because the dev team decided when a specific version was a "release".

I suggested using a Python script because Python runs on all developement platforms and is really powerful and easy when it comes to text files manipulations. It can then be called by whatever build system (Visual Studio, CMake, etc.) you use.

Klaim
or a shell/perl script if your running under a *nix.(both are more likely to be installed by default than python)
Earlz
I was thinking of some sort of way to get the compiler stored macros into your code, but I really like this idea.
Lyndsey Ferguson
since config.h already contains the information (see ephemient's answer), there is no need to write your own script
adl
I assumed the question was not automake-specific. After all, he asks for "How do most C++ coders do this?".Relying too heavily on build system might be problematic in future change for some long-life softwares.
Klaim
+3  A: 

autoconf gives you a config.h, which provides string macros such as PACKAGE, PACKAGE_NAME, PACKAGE_STRING, PACKAGE_VERSION, and VERSION.

(When I use the Argp argument parser, I simply use

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <argp.h>
const char *argp_program_version = PACKAGE_STRING;
const char *argp_program_bug_address = PACKAGE_BUGREPORT;
/* et cetera */
int main(int argc, char **argv) {
    error_t argp_result = argp_parse(&argp, argc, argv, 0, 0, NULL);
    if (argp_result) return argp_result;
    /* et cetera */
}

and then --help, --version, etc. just automatically work.)

You could also add

AC_CANONICAL_HOST
AC_DEFINE_UNQUOTED([CHOST], ["$host"], [Canonical host])
AC_CANONICAL_BUILD
AC_DEFINE_UNQUOTED([CBUILD], ["$build"], [Canonical build])
AC_CANONICAL_TARGET
AC_DEFINE_UNQUOTED([CTARGET], ["$target"], [Canonical target])

to your configure.ac, if you want to have those string macros in your config.h too. These are typically strings of the form $arch-$vendor-$kernel-$libc, where
CHOST is the platform that will run the software after it is built,
CBUILD is the platform that is currently building the software, and
CTARGET is the platform the software will act on.
(These are all the same unless you are cross-compiling or building a cross-compile toolchain.)

ephemient
The second part is exactly what I was looking for. Thanks so much.
mohawkjohn
So, interestingly, when I include config.h in that manner, I get this error on the very next line of code:main.cpp:11: error: expected unqualified-id before string constantmake[2]: *** [phenomatrix-main.o] Error 1There's nothing in the auto-generated config.h except for #defines, and I haven't modified it.Only thing I can think of is that config.h is in ../ instead of in src, but even when I move it into src and #include it with quotation marks instead of carats, I get the same error.
mohawkjohn
Works for me, with autoconf 2.65 and automake 1.10. Could you post your versions, a bit of your `configure.ac` and the resulting `config.h`, and maybe how you're trying to use the C macros?
ephemient
Sure. I stuck them in a gist: http://gist.github.com/282960I've tried a couple different ways. The only way it compiles is if I don't use the macros at all.It's GNU autoconf 2.64, GNU automake 1.7.9.
mohawkjohn
That's because you wrote `const std::string VERSION = PACKAGE_STRING;`. `VERSION` gets substituted into `"0.1.0"` and `PACKAGE_STRING` gets substituted into `"phenomatrix 0.1.0"`, turning the whole line into `const std::string "0.1.0" = "phenomatrix 0.1.0";` -- clearly illegal.
ephemient
God. That's embarrassing. Thanks.
mohawkjohn