Embed git commit ID in the .so

833 views Asked by At

In Windows, I can impress or update information including a build version into a DLL after it is built, as a post-process step before deploying.

There does not seem to be such a feature in Linux shared object files. It appears that I need to include this while building.

How can I have meson automatically put the git commit ID of the current repository state into a text file so I can refer to that in the source code? In the end, I want the .so file to "know" its own version and will (for example) log that as part of its operation, or can return that string from a published API of that library.

I understand that meson has "generative" features, but I could not follow how to use it from the online manual.

1

There are 1 answers

13
pmod On

You can use vcs_tag command:

git_version_h = vcs_tag(command : ['git', 'describe', '--tags'],
            input : 'git_version.h.in',
            output :'git_version.h')

This command detects revision control commit information at build time and places it in the specified output file. This file is guaranteed to be up to date on every build.

You should provide git-version.h.in in your code base with @VCS_TAG@ which will be replace with git commit id (result of the command), replacement string can be changed - see docs.

The file will be placed in the configured build directory in the same relative directory, so that output can be used as it's replacing the input in-place, e.g. you can include git_version.h from the directory where git_version.h.in is located.

And note, that

you must add the return value to the sources of that build target. Without that, Meson will not know the order in which to build the targets

e.g.

executable('myprog',
       'myprog.c',
       git_version_h
       )

UPDATE Here is working sample project:

$ cd vcs_sample
$ find        
.
./dir
./dir/meson.build
./dir/git_version.h.in
./meson.build
./main.c

$ cat meson.build 
project('vcs_sample', 'c')
subdir('dir')
executable('myvcs', vcs_dep, 'main.c')

$ cat main.c     
#include "stdio.h"
#include "dir/git_version.h"

int main(int argc, char* argv [])
{
    printf("git version = " MY_GIT_VERSION "\n");
    return 0;
}

$ cat dir/meson.build 
vcs_dep=vcs_tag(input:'git_version.h.in',
        output:'git_version.h',
        replace_string:'@GIT_VERSION@')

$ cat dir/git_version.h.in
#define MY_GIT_VERSION "@GIT_VERSION@"

Building/running

$ meson build/
$ ninja -C build/
$ ./build/myvcs
git version = R0.1.1+

And if we look inside generated ninja file, we can notice this works because dir is added to compiler include paths:

build myvcs@exe/main.c.o: c_COMPILER ../main.c || dir/git_version.h
 DEPFILE = myvcs@exe/main.c.o.d
 ARGS = -Imyvcs@exe -I. -I.. -Idir -fdiagnostics-color=always <...>