Skip to content

[cmake] Regenerate git version in config.h at build time - #9299

Merged
sbc100 merged 1 commit into
mainfrom
cmake_git_version
Oct 23, 2026
Merged

sbc100 merged 1 commit into
mainfrom
cmake_git_version

Conversation

@sbc100

@sbc100 sbc100 commented Oct 23, 2026 •

Copy link
Copy Markdown
Member

Previously git describe was only executed when configuring CMake, so switching git revisions and running an incremental build left PROJECT_VERSION (and --version output) stale unless CMake happened to re-run.

This change (or something like this) is needed to make the version check in emscripten-core/emscripten#28053 work. Right now --version lies which is not great.

Inspired by LLVM's GenerateVersionFromVCS.cmake / VCSRevision.h setup, move config.h generation into scripts/gen-version.cmake and wire it up via add_custom_command depending on .git/logs/HEAD.

Because configure_file only updates config.h's timestamp when its contents actually change, and only src/support/command-line.cpp includes config.h, incremental rebuilds only recompile that single file when HEAD changes. config.h is also still generated at configure time so tools like clang-tidy that run before a build can find it.

@sbc100
sbc100 requested a review from a team as a code owner October 23, 2026 17:17
@sbc100
sbc100 requested review from kripken and removed request for a team October 23, 2026 17:17

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the generation of config.h to occur at build time whenever the Git HEAD changes, ensuring the version string stays up-to-date without requiring a full CMake re-run. Feedback on these changes suggests removing the warning when git describe fails to prevent build output spam on shallow clones, and replacing the non-existent __fake_config.h output with a dummy custom target to avoid Ninja build warnings.

Comment thread scripts/gen-version.cmake
Comment thread CMakeLists.txt
@sbc100
sbc100 removed the request for review from kripken October 23, 2026 17:23
@sbc100
sbc100 marked this pull request as draft October 23, 2026 17:23

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Google Antigravity Code Review

I have reviewed the changes in this Pull Request and left inline feedback.

Comment thread CMakeLists.txt
Comment thread scripts/gen-version.cmake
Previously `git describe` was only executed when configuring CMake, so
switching git revisions and running an incremental build left
`PROJECT_VERSION` (and `--version` output) stale unless CMake happened
to re-run.

Inspired by LLVM's `GenerateVersionFromVCS.cmake` / `VCSRevision.h`
setup, move `config.h` generation into `scripts/gen-version.cmake` and
wire it up via `add_custom_command` depending on `.git/logs/HEAD`.

Because `configure_file` only updates `config.h`'s timestamp when its
contents actually change, and only `src/support/command-line.cpp`
includes `config.h`, incremental rebuilds only recompile that single
file when `HEAD` changes. `config.h` is also still generated at
configure time so tools like `clang-tidy` that run before a build can
find it.
@sbc100
sbc100 force-pushed the cmake_git_version branch from c745635 to 4c08908 Compare October 23, 2026 18:40

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Google Antigravity Code Review

I have reviewed the changes in this Pull Request and left inline feedback.

Comment thread CMakeLists.txt
@sbc100
sbc100 marked this pull request as ready for review October 23, 2026 20:59

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the version generation logic to update config.h at build time when switching git commits, rather than only at configure time. It introduces a new scripts/gen-version.cmake script and configures a custom build target to handle this process. Feedback on these changes suggests changing a warning message to a status message in the new script to prevent noisy build outputs in shallow-clone CI environments, and marking the fallback fake header file as SYMBOLIC in CMake to avoid IDE warnings and properly handle the missing file.

Comment thread scripts/gen-version.cmake
OUTPUT_VARIABLE GIT_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(GIT_VERSION_RESULT)
message(WARNING "Error running git describe to determine version")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using message(WARNING ...) here can be very noisy, especially in CI environments (like GitHub Actions) where shallow clones are the default and git describe will fail because tags are not fetched. Since this script runs at build time, this warning will be printed repeatedly, cluttering the build output. Changing this to message(STATUS ...) or removing it entirely is recommended.

    message(STATUS "Could not run git describe to determine version")

Comment thread CMakeLists.txt
Comment on lines +112 to +117
else()
# Some checkouts (e.g. 'repo' or reflog-disabled) may not have
# .git/logs/HEAD; use a non-existent output to force checking git at
# build time.
list(APPEND GENERATED_VERSION_FILES "${CMAKE_CURRENT_BINARY_DIR}/__fake_config.h")
endif()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To prevent IDEs (like Visual Studio or Xcode) from displaying warnings about the missing __fake_config.h file, and to explicitly signal to CMake that this file is not expected to be created on disk, you should mark it with the SYMBOLIC source file property. This is the standard CMake way to force a custom command to run on every build.

      else()\n        # Some checkouts (e.g. 'repo' or reflog-disabled) may not have\n        # .git/logs/HEAD; use a non-existent output to force checking git at\n        # build time.\n        set(FAKE_HEADER "${CMAKE_CURRENT_BINARY_DIR}/__fake_config.h")\n        list(APPEND GENERATED_VERSION_FILES "${FAKE_HEADER}")\n        set_source_files_properties("${FAKE_HEADER}" PROPERTIES SYMBOLIC TRUE)\n      endif()

@kripken kripken left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this cause us to do more work in incremental builds?

@sbc100

sbc100 commented Oct 23, 2026

Copy link
Copy Markdown
Member Author

It means that there will always be at least one object file dirty whenever you change your HEAD (src/support/command-line.cpp). This is the only file that includes config.h.

This is the same in LLVM. Whenever you commit or change your HEAD you get a very minimal forced rebuild.

If you prefer we can work around this in emscripten-core/emscripten#28064... but just note that --version will report bad info in many local builds.

@kripken kripken left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not a cmake expert so not sure about the fine details but if this works it sounds good, and seems low risk.

@sbc100

sbc100 commented Oct 23, 2026

Copy link
Copy Markdown
Member Author

Lets see if anyone complains :)

@sbc100
sbc100 merged commit f1f3a48 into main Oct 23, 2026
17 checks passed
@sbc100
sbc100 deleted the cmake_git_version branch October 23, 2026 23:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants