diff --git a/pkgs/development/compilers/llvm/git/default.nix b/pkgs/development/compilers/llvm/git/default.nix index 27fdea9d4553e..c7b5e03226ef3 100644 --- a/pkgs/development/compilers/llvm/git/default.nix +++ b/pkgs/development/compilers/llvm/git/default.nix @@ -15,24 +15,72 @@ then null else pkgs.bintools , darwin +# LLVM release information; specify one of these but not both: +, gitRelease ? null + # i.e.: + # { + # version = /* i.e. "15.0.0" */; + # rev = /* commit SHA */; + # rev-version = /* human readable version; i.e. "unstable-2022-26-07" */; + # sha256 = /* checksum for this release, can omit if specifying your own `monorepoSrc` */; + # } +, officialRelease ? { version = "15.0.7"; sha256 = "sha256-wjuZQyXQ/jsmvy6y1aksCcEDXGBjuhpgngF3XQJ/T4s="; } + # i.e.: + # { + # version = /* i.e. "15.0.0" */; + # candidate = /* optional; if specified, should be: "rcN" */ + # sha256 = /* checksum for this release, can omit if specifying your own `monorepoSrc` */; + # } +# By default, we'll try to fetch a release from `github:llvm/llvm-project` +# corresponding to the `gitRelease` or `officialRelease` specified. +# +# You can provide your own LLVM source by specifying this arg but then it's up +# to you to make sure that the LLVM repo given matches the release configuration +# specified. +, monorepoSrc ? null }: - +assert let + int = a: if a then 1 else 0; + xor = a: b: ((builtins.bitXor (int a) (int b)) == 1); +in + lib.assertMsg + (xor + (gitRelease != null) + (officialRelease != null)) + ("must specify `gitRelease` or `officialRelease`" + + (lib.optionalString (gitRelease != null) " — not both")); let - release_version = "15.0.0"; - candidate = ""; # empty or "rcN" - dash-candidate = lib.optionalString (candidate != "") "-${candidate}"; - rev = "a5640968f2f7485b2aa4919f5fa68fd8f23e2d1f"; # When using a Git commit - rev-version = "unstable-2022-26-07"; # When using a Git commit - version = if rev != "" then rev-version else "${release_version}${dash-candidate}"; - targetConfig = stdenv.targetPlatform.config; - - monorepoSrc = fetchFromGitHub { + monorepoSrc' = monorepoSrc; +in let + releaseInfo = if gitRelease != null then rec { + original = gitRelease; + release_version = original.version; + version = gitRelease.rev-version; + } else rec { + original = officialRelease; + release_version = original.version; + version = if original ? candidate then + "${release_version}-${original.candidate}" + else + release_version; + }; + + monorepoSrc = if monorepoSrc' != null then + monorepoSrc' + else let + sha256 = releaseInfo.original.sha256; + rev = if gitRelease != null then + gitRelease.rev + else + "llvmorg-${releaseInfo.version}"; + in fetchFromGitHub { owner = "llvm"; repo = "llvm-project"; - rev = if rev != "" then rev else "llvmorg-${version}"; - sha256 = "1sh5xihdfdn2hp7ds3lkaq1bfrl4alj36gl1aidmhlw65p5rdvl7"; + inherit rev sha256; }; + inherit (releaseInfo) release_version version; + llvm_meta = { license = lib.licenses.ncsa; maintainers = lib.teams.llvm.members; diff --git a/pkgs/development/compilers/llvm/git/llvm/default.nix b/pkgs/development/compilers/llvm/git/llvm/default.nix index ef7ff66e74641..76a66cc886081 100644 --- a/pkgs/development/compilers/llvm/git/llvm/default.nix +++ b/pkgs/development/compilers/llvm/git/llvm/default.nix @@ -241,6 +241,38 @@ in stdenv.mkDerivation (rec { ) ''; + # Defensive check: some paths (that we make symlinks to) depend on the release + # version, for example: + # - https://github.com/llvm/llvm-project/blob/406bde9a15136254f2b10d9ef3a42033b3cb1b16/clang/lib/Headers/CMakeLists.txt#L185 + # + # So we want to sure that the version in the source matches the release + # version we were given. + # + # We do this check here, in the LLVM build, because it happens early. + postConfigure = let + v = lib.versions; + major = v.major release_version; + minor = v.minor release_version; + patch = v.patch release_version; + in '' + # $1: part, $2: expected + check_version() { + part="''${1^^}" + part="$(cat include/llvm/Config/llvm-config.h | grep "#define LLVM_VERSION_''${part} " | cut -d' ' -f3)" + + if [[ "$part" != "$2" ]]; then + echo >&2 \ + "mismatch in the $1 version! we have version ${release_version}" \ + "and expected the $1 version to be '$2'; the source has '$part' instead" + exit 3 + fi + } + + check_version major ${major} + check_version minor ${minor} + check_version patch ${patch} + ''; + # E.g. mesa.drivers use the build-id as a cache key (see #93946): LDFLAGS = optionalString (enableSharedLibraries && !stdenv.isDarwin) "-Wl,--build-id=sha1";