[PATCH] llvm-config: add svn revision to --version

At the moment llvm-config outputs "2.6svn" if llvm is build from trunk

$ llvm-config --version
2.6svn

Some external projects (built out-of-tree) need to know which revision of llvm is installed. LDC currently asks llvm-config --src-root for the source directory and then parses svn info's output to get the revision number. This requires the user to keep the llvm source tree around even if it is not needed to build ldc.

The attached patch modifies the llvm build system (both autotools and cmake) to write the revision into PACKAGE_VERSION:

$ llvm-config --version
2.6-71981

or, if it couldn't find svn during the build:

$ llvm-config --version
2.6-svn

revversion.patch (1.8 KB)

Benjamin Kramer wrote:

At the moment llvm-config outputs "2.6svn" if llvm is build from trunk

$ llvm-config --version
2.6svn

Some external projects (built out-of-tree) need to know which revision of llvm is installed. LDC currently asks llvm-config --src-root for the source directory and then parses svn info's output to get the revision number. This requires the user to keep the llvm source tree around even if it is not needed to build ldc.

Not technically true; it's not *required*. However, if this isn't done you need to set it manually in the cmake configuration...

The attached patch modifies the llvm build system (both autotools and cmake) to write the revision into PACKAGE_VERSION:

$ llvm-config --version
2.6-71981

I don't think that's enough for LDC; we want to be able to compare the version with #if, so we need it to produce something like '#define LLVM_REV 71981' (i.e. a raw integer, not a string).

I don't think that's enough for LDC; we want to be able to compare the version
with #if, so we need it to produce something like '#define LLVM_REV 71981' (i.e.
a raw integer, not a string).

Why don't introduce some another option for it? E.g. llvm-config --revision ?

Frits van Bommel wrote:

I don't think that's enough for LDC; we want to be able to compare the version
with #if, so we need it to produce something like '#define LLVM_REV 71981' (i.e.
a raw integer, not a string).

Here is another patch which adds a new option to llvm-config:

$ llvm-config --revision

or, if the build script couldn't find svn:

$ llvm-config --revision
0

I think this is also a safer approach, it won't break anything that relies on the
current llvm-config behavior.

revv2.patch (2.89 KB)

Frits van Bommel skrev:

Benjamin Kramer wrote:
  

At the moment llvm-config outputs "2.6svn" if llvm is build from trunk

$ llvm-config --version
2.6svn

Some external projects (built out-of-tree) need to know which revision of llvm is installed. LDC currently asks llvm-config --src-root for the source directory and then parses svn info's output to get the revision number. This requires the user to keep the llvm source tree around even if it is not needed to build ldc.
    
Not technically true; it's not *required*. However, if this isn't done you need to set it manually in the cmake configuration...

The attached patch modifies the llvm build system (both autotools and cmake) to write the revision into PACKAGE_VERSION:

$ llvm-config --version
2.6-71981
    
I don't think that's enough for LDC; we want to be able to compare the version with #if, so we need it to produce something like '#define LLVM_REV 71981' (i.e. a raw integer, not a string).
  

When we build Icedtea shark JIT we use the llvm-config version to make the icedtea code compatible with api changes in llvm.
I belive you are trying to do something similarwith LDC. This can be done without changing the llvm codebase.

I suggest the following:
add to the LDC configure.

LLVM_CFLAGS="$LLVM_CFLAGS -DLLVM_VERSION=`$LLVM_CONFIG --version | sed 's/\.//;s/svn.*//'`"

this will take the llvm-config --version output and truncates the versionnumber from

2.6svn to 26

now the LLVM_VERSION can be used in your source code like this:

#if LLVM_VERSION >= 26
/*llvm 2.6 and above compatible code*/
#endif

#if LLVM_VERSION >= 25
// etc...
#endif

cheers
Xerxes

Xerxes Rånby wrote:

Frits van Bommel skrev:

Benjamin Kramer wrote:

The attached patch modifies the llvm build system (both autotools and cmake) to write the revision into PACKAGE_VERSION:

$ llvm-config --version
2.6-71981
    

I don't think that's enough for LDC; we want to be able to compare the version with #if, so we need it to produce something like '#define LLVM_REV 71981' (i.e. a raw integer, not a string).
  

When we build Icedtea shark JIT we use the llvm-config version to make the icedtea code compatible with api changes in llvm.
I belive you are trying to do something similarwith LDC. This can be done without changing the llvm codebase.

I suggest the following:
add to the LDC configure.

LLVM_CFLAGS="$LLVM_CFLAGS -DLLVM_VERSION=`$LLVM_CONFIG --version | sed 's/\.//;s/svn.*//'`"

this will take the llvm-config --version output and truncates the versionnumber from

2.6svn to 26

now the LLVM_VERSION can be used in your source code like this:

#if LLVM_VERSION >= 26
/*llvm 2.6 and above compatible code*/
#endif

#if LLVM_VERSION >= 25
// etc...
#endif

That's not precise enough. API changes are introduced in svn all the time, and bugs are fixed (obsoleting workarounds). We currently test for 5 different trunk revisions after 2.5.

Though I suppose a similar technique could be used with the original version of the patch, sed'ing out the revision nr. It'd certainly be less error-prone than the current approach.

I think you don't need to support all trunk revisions.
People using trunk could be told to either update to a certain revision,
or stick to a released version.

This should suffice:

#if LLVM_VERSION >= 25
....
#endif

#if LLVM_VERSION == 26
#if LLVM_REVISION < MINIMUM_THAT_CONTAINS_ALLYOUNEED
#error "Please update to SVN rXYZ"
#else
//code for SVN API
#endif

Best regards,
--Edwin

Török Edwin wrote:

I think you don't need to support all trunk revisions.
People using trunk could be told to either update to a certain revision,
or stick to a released version.

We don't support /all/ trunk revisions, but we don't like to force upgrades unless it's really needed so we try to at least support most recent revisions.

One of the reasons is that not all of our developers use the same trunk revision, and recompiling LLVM trunk is not something everyone likes to do once a day. (It's nice if you can put it off for a couple of days without things breaking)

I agree that this is a really useful thing to support. On side of being willing to break APIs is that we should work hard to make people with out-of-tree code be able to cope with this, even though we shouldn't be afraid of breaking APIs.

The idea of the patch to add the new option to llvm-config sounds great to me. One concern: does an svn up now cause a complete relink of all llvm tools? Ideally, I'd like to see something like this:

$ svn up
u docs/LangRef.html
$ make
... only llvm-config is "rebuilt" ...

-Chris

Chris Lattner wrote:

The idea of the patch to add the new option to llvm-config sounds
great to me. One concern: does an svn up now cause a complete relink
of all llvm tools? Ideally, I'd like to see something like this:

In the current version of my patch the revision is only updated on a re-configure/CMake. On a second thought that is quite stupid. But I'm not sure what's the best way to fix this. I guess we need to add a target which is always run to llvm-config's Makefile ...

Benjamin Kramer <benny.kra@googlemail.com> writes:

In the current version of my patch the revision is only updated on a
re-configure/CMake. On a second thought that is quite stupid. But I'm
not sure what's the best way to fix this. I guess we need to add a
target which is always run to llvm-config's Makefile ...

This is easy: see the logic for regenerating llvm-config when the file
that contains the library dependencies changes.

Why do you use `svn info' and not `svnversion'?

And this brings another question: how do you deal with modified working
copies?

Óscar Fuentes wrote:

Why do you use `svn info' and not `svnversion'?

bad habit. I'm not very familiar with svnversion and its output.

And this brings another question: how do you deal with modified working
copies?

We could add a M or "dirty" to the revision number. But I don't know how this would affect things like "if (revision >= 12345)".

This is easy: see the logic for regenerating llvm-config when the file
that contains the library dependencies changes.

hmm, sounds reasonable since it's in the same Makefile. But I probably won't have time to look into this until thursday. Damn exams. If anyone likes to volunteer: just do it :wink:

There's an easy way to fix these kinds of problems. Deprecate interfaces for
one release. I brought this up before but the idea was quickly shot down.
It's insane to litter your code with #ifdefs based on SVN revisions.

This is exactly the kind of situation that the LLVM community needs to
address. Changing APIs is fine. Ripping out old versions without first
deprecating them for a release causes nightmares all around.

                           -Dave

Óscar Fuentes wrote:

Why do you use `svn info' and not `svnversion'?

He probably copied this from LDC.

We used to use `svnversion` for LDC, but I changed it to `svn info` because it was noticeably faster[1]. This may be less of an issue for LLVM where builds take more time anyway, decreasing the relative impact.

And this brings another question: how do you deal with modified working
copies?

If you use svnversion it will append an 'M' to the revision number; see `svnversion --help`.

[1]: IIRC svnversion took several times longer than the rest of an incremental build if little had changed.

Benjamin Kramer wrote:

Óscar Fuentes wrote:

And this brings another question: how do you deal with modified working
copies?

We could add a M or "dirty" to the revision number. But I don't know how this would affect things like "if (revision >= 12345)".

It should be easy enough to sed out.

David Greene wrote:

There's an easy way to fix these kinds of problems. Deprecate interfaces for
one release. I brought this up before but the idea was quickly shot down.
It's insane to litter your code with #ifdefs based on SVN revisions.

This is exactly the kind of situation that the LLVM community needs to address. Changing APIs is fine. Ripping out old versions without first
deprecating them for a release causes nightmares all around.

On the other hand, I've found code breakage to be a very good motivator to fix it right away :).
(In some cases, even before anyone (including me) ever saw the error...)

But what kind of breakage? The risk of upgrading is that not only do
APIs change, so do the algorithms, etc. So you have to track down bugs
as well as fix APIs. Then you have the problem sorting out whether you
caused the bug by not converting APIs correctly or the bug exists upstream.

Really, it's much better to isolate points of failure. We're talking about
basic software engineering and maintenance practice.

The current situation is fine for single-user projects or small research
graoups. It absolutely does not work well for even mid-sized teams in a
time-to-market commercial setting where stability is king.

I'm curious to hear from the other commercial vendors out there. How do
you deal with the current process?

                             -Dave