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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions