cmake: (release) version handling is broken #31898

issue fanquake openend this issue on February 18, 2025
  1. fanquake commented at 3:52 pm on February 18, 2025: member

    Create a test tag: v99.99 Checkout v99.99 and perform a guix build:./contrib/guix/guix-build. Take the dist-archive tarball: /bitcoin/guix-build-99.99/output/dist-archive/bitcoin-99.99.tar.gz and perform a build:

    0tar xf bitcoin-99.99.tar.gz
    1cd bitcoin-99.99
    2cmake -B build
    3cmake --build build
    4# ./build/src/bitcoind --version 
    5Bitcoin Core daemon version v28.99.0-g43e287b3ff5f0d223b0911b6ef90054ce5eb69d2
    
  2. fanquake added the label Build system on Feb 18, 2025
  3. fanquake added this to the milestone 29.0 on Feb 18, 2025
  4. hebasto commented at 4:27 pm on February 18, 2025: member

    Shouldn’t this behaviour be tested for releases:

     0--- a/CMakeLists.txt
     1+++ b/CMakeLists.txt
     2@@ -21,7 +21,7 @@ set(CLIENT_VERSION_MAJOR 28)
     3 set(CLIENT_VERSION_MINOR 99)
     4 set(CLIENT_VERSION_BUILD 0)
     5 set(CLIENT_VERSION_RC 0)
     6-set(CLIENT_VERSION_IS_RELEASE "false")
     7+set(CLIENT_VERSION_IS_RELEASE "true")
     8 set(COPYRIGHT_YEAR "2025")
     9 
    10 # During the enabling of the CXX and CXXOBJ languages, we modify
    

    ?

  5. fanquake commented at 4:37 pm on February 18, 2025: member

    CLIENT_VERSION_IS_RELEASE only influences the version suffix information. https://github.com/bitcoin/bitcoin/blob/43e287b3ff5f0d223b0911b6ef90054ce5eb69d2/src/clientversion.cpp#L40-L44

    So even if that was set we’d stil be producing a tarball from a tag v99.99, which contained the version information 28.99.

  6. maflcko commented at 4:40 pm on February 18, 2025: member
    What was the autotools behavior, to compare?
  7. fanquake commented at 4:41 pm on February 18, 2025: member

    What was the autotools behavior, to compare?

    The tarball for 28.1 contains the version information 28.1.

  8. fanquake commented at 4:42 pm on February 18, 2025: member

    i.e

    0wget https://bitcoincore.org/bin/bitcoin-core-28.1/bitcoin-28.1.tar.gz
    1tar xf bitcoin-28.1.tar.gz
    2cd bitcoin-28.1
    3./autogen.sh
    4./configure
    5make
    6# ./src/bitcoind --version
    7Bitcoin Core version v28.1.0
    8Copyright (C) 2009-2024 The Bitcoin Core developers
    
  9. fanquake commented at 5:05 pm on February 18, 2025: member

    Shouldn’t this behaviour be tested for releases: CLIENT_VERSION_IS_RELEASE only influences the version suffix information.

    Looking at the code further, if BUILD_GIT_TAG is defined, which should be the case when the top commit is tagged according to https://github.com/bitcoin/bitcoin/blob/43e287b3ff5f0d223b0911b6ef90054ce5eb69d2/src/clientversion.cpp#L28-L40

    then CLIENT_VERSION_IS_RELEASE shouldn’t be used in creating the version string. So it shouldn’t matter if that is set or not.

  10. hebasto commented at 5:19 pm on February 18, 2025: member

    Shouldn’t this behaviour be tested for releases: CLIENT_VERSION_IS_RELEASE only influences the version suffix information.

    Looking at the code further, if BUILD_GIT_TAG is defined, which should be the case when the top commit is tagged according to

    I don’t think BUILD_GIT_TAG is defined:

    0$ wget https://bitcoincore.org/bin/bitcoin-core-28.1/bitcoin-28.1.tar.gz
    1$ tar xf bitcoin-28.1.tar.gz
    2$ cd bitcoin-28.1
    3$ ./autogen.sh
    4$ ./configure
    5$ make
    6$ cat src/obj/build.h
    7// No build information available
    
  11. hebasto commented at 6:08 pm on February 18, 2025: member

    What was the autotools behavior, to compare?

    I’ve reproduced all steps from #31898#issue-2860887337 for the pre-CMake commit:

     0$ tar xf bitcoin-99.99.tar.gz
     1$ cd bitcoin-99.99/
     2$ ./autogen.sh
     3$ ./configure 
     4$ make -j $(nproc)
     5$ ./src/bitcoind --version
     6Bitcoin Core version v28.99.0-g80f00cafdeef0600fa1a5e906686720786c2336c
     7Copyright (C) 2009-2024 The Bitcoin Core developers
     8
     9Please contribute if you find Bitcoin Core useful. Visit
    10<https://bitcoincore.org/> for further information about the software.
    11The source code is available from <https://github.com/bitcoin/bitcoin>.
    12
    13This is experimental software.
    14Distributed under the MIT software license, see the accompanying file COPYING
    15or <https://opensource.org/licenses/MIT>
    

    Thus, there is no change in behaviour during the migration from Autotools to CMake.

  12. fanquake commented at 6:09 pm on February 18, 2025: member
    So then the bug was just ported/these code paths untested during the transition?
  13. hebasto commented at 6:11 pm on February 18, 2025: member

    So then the bug was just ported/these code paths untested during the transition?

    The mirroring of behaviour was tested.

  14. fanquake commented at 6:22 pm on February 18, 2025: member

    I guess I’m just confused why something that is obviously a bug would be ported as-is. There’s no scenario where it makes sense to have a binary output version information that doesn’t match the tag it was built from.

    In any case, we’ll have to fix the nonsensical behaviour in master.

  15. hebasto commented at 6:27 pm on February 18, 2025: member

    @fanquake

    Could you demonstrate how a release source tarball becomes broken when all steps in the release process have been followed?

  16. maflcko commented at 6:49 pm on February 18, 2025: member

    For reference, I reviewed and tested this specifically for the cmake switch last year and I concluded that everything has been ported accurately. So I don’t think there is a regression or a release-blocker.

    In any case, it would be good to include full steps to reproduce here, starting from a fresh clone, because IIRC in some edge cases, the parent directory structure may influence the result if it is a git dir. The edge-cases aren’t well documented, sometimes only mentioned in the release notes:

    https://github.com/bitcoin/bitcoin/blame/43e287b3ff5f0d223b0911b6ef90054ce5eb69d2/doc/release-notes/release-notes-0.20.0.md#L56

    It would be nice to flatten the complexity here to something simple, but I don’t see how this can be achieved without possibly breaking someones build-setup.

  17. achow101 commented at 2:24 am on February 19, 2025: member

    Since guix builds from this tarball, how is it that the guix build results in binaries the output the correct version, prior to cmake?

    Edit:

    I don’t see these issues when performing all of the release steps. When setting the version numbers and tagging as laid out in release-process.md, everything works as expected.

    Looking at the code further, if BUILD_GIT_TAG is defined, which should be the case when the top commit is tagged according to

    It looks like it’s only defined when building inside of a git tree. This is the same behavior as with autotools. My understanding is that the version numbers are also put in the build system because builds will not always occur inside of a git tree.

  18. hebasto commented at 10:25 am on February 19, 2025: member

    Since guix builds from this tarball, how is it that the guix build results in binaries the output the correct version, prior to cmake?

    The correct version comes from CLIENT_VERSION_STRING, which is set in:https://github.com/bitcoin/bitcoin/blob/785649f3977517a4ba45c5d2fedfbda778fb52cb/CMakeLists.txt#L50

    It looks like it’s only defined when building inside of a git tree. This is the same behavior as with autotools. My understanding is that the version numbers are also put in the build system because builds will not always occur inside of a git tree.

    BUILD_GIT_TAG or BUILD_GIT_COMMIT are defined in the bitcoin-build-info.h header, which is generated by the build system depending on the build environment.

    Additionally, the source archive has a commit hash hardcoded in:https://github.com/bitcoin/bitcoin/blob/785649f3977517a4ba45c5d2fedfbda778fb52cb/src/clientversion.cpp#L33

    A tag can probably also be hardcoded.

  19. fanquake commented at 12:12 pm on February 20, 2025: member

    but I don’t see how this can be achieved without possibly breaking someones build-setup.

    Given we are already breaking all build setups in the CMake switch, it seems like the right time to make any further changes?

    It’s pretty clear the code here is convoluted/overcomplicated. Just the fact that the release process derives the same version number from two different places is odd (and is what hides the bug here).

  20. maflcko commented at 1:00 pm on February 20, 2025: member

    Given that the commit id is hardcoded into the git archive, it could make sense to hardcode everything else as well and then just prefer that over any external environment influences. This should allow to drop BITCOIN_GENBUILD_NO_GIT, because whatever result it will calculate will be ignored.

    In theory, it could be implemented with a small helper script to inject the hardcoded values into the source code (along with the current commit id), then create a new “dummy” commit, then call git archive on it. The dummy commit id wouldn’t end up in the archive and everything should still be deterministic.


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2025-02-22 06:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me