Skip to content

Feature Request: Built-in VCS revision support (analogous to GNAT.Compile_Time) #160

@flottokarotto

Description

@flottokarotto

Summary

Nearly every Ada project that produces deployable binaries needs to embed VCS information (e.g. Git commit hash) into the binary. Currently this requires an external pre-build step — typically a shell script that generates an Ada spec before calling gprbuild. This is fragile, breaks the self-contained nature of gprbuild, and is a problem every project has to solve independently.

Precedent

GNAT already provides GNAT.Compile_Time which embeds non-deterministic build metadata (date/time) at compile time. A VCS revision is actually more reproducible than a timestamp — the same source state always produces the same hash.

Proposed Solution

Add built-in support for querying VCS information during the build, for example:

Option A — GPR-level external variable from shell command:

Allow a project file to define a scenario variable populated from a shell command:

VERSION := external_command("git rev-parse --short HEAD");

This would be the most flexible approach and not limited to Git.

Option B — Built-in GNAT package (similar to GNAT.Compile_Time):

package GNAT.VCS_Version is
   function Revision return String;     -- e.g. "a1b2c3d"
   function Is_Modified return Boolean;  -- true if working tree has uncommitted changes
end GNAT.VCS_Version;

Option C — Pre/Post-Build hooks in GPR files:

package Builder is
   for Pre_Build_Command use ("./updateVersionInfo.sh");
end Builder;

Rationale

  • Widespread need: This is a universally solved problem outside of Ada. CMake has GIT_HASH, Cargo has env!("GIT_HASH"), Go has -ldflags. Ada projects currently need a Makefile or shell script wrapper around gprbuild.
  • Precedent exists: GNAT.Compile_Time already embeds non-deterministic build metadata. A git hash is more stable and more useful for identifying deployed binaries.
  • Simplicity: A project could replace Makefile + updateVersionInfo.sh + generated vcs_version.ads with a single built-in mechanism.
  • Graceful fallback: If no VCS is detected (e.g. building from a tarball), the revision could default to "unknown".

Current Workaround

A typical workaround looks like this:

#!/bin/bash
VERSION=$(git rev-parse --short HEAD)
GIT_MODS="-M"
if output=$(git status --porcelain) && [ -z "$output" ]; then
    GIT_MODS=""
fi
echo -e "package VCS_Version is VERSION : constant String := \"${VERSION}${GIT_MODS}\"; end VCS_Version;" > src/vcs_version.ads

This must be called before every gprbuild invocation, either manually or via a Makefile/CI script.

Any of the proposed options would eliminate this pattern.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions