summaryrefslogtreecommitdiff
path: root/pkgs/development/compilers/gnat-bootstrap/default.nix
blob: ef7ed876e583280f8d44c38f475f222da76dc12d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
{
  stdenv,
  lib,
  autoPatchelfHook,
  fetchzip,
  xz,
  ncurses5,
  ncurses,
  readline,
  gmp,
  mpfr,
  expat,
  libipt,
  zlib,
  dejagnu,
  sourceHighlight,
  python3,
  elfutils,
  guile,
  glibc,
  zstd,
  majorVersion,
}:

let
  throwUnsupportedSystem = throw "Unsupported system: ${stdenv.hostPlatform.system}";
in
stdenv.mkDerivation (
  finalAttrs:
  let
    versionMap =
      let
        url = "https://github.com/alire-project/GNAT-FSF-builds/releases/download/gnat-${finalAttrs.version}/gnat-${stdenv.hostPlatform.system}-${finalAttrs.version}.tar.gz";
      in
      {
        "12" = {
          gccVersion = "12.1.0";
          alireRevision = "2";
        }
        // {
          x86_64-darwin = {
            inherit url;
            hash = "sha256-zrcVFvFZMlGUtkG0p1wST6kGInRI64Icdsvkcf25yVs=";
            upstreamTriplet = "x86_64-apple-darwin19.6.0";
          };
          x86_64-linux = {
            inherit url;
            hash = "sha256-EPDPOOjWJnJsUM7GGxj20/PXumjfLoMIEFX1EDtvWVY=";
            upstreamTriplet = "x86_64-pc-linux-gnu";
          };
        }
        .${stdenv.hostPlatform.system} or throwUnsupportedSystem;
        "13" = {
          gccVersion = "13.2.0";
          alireRevision = "2";
        }
        // {
          x86_64-darwin = {
            inherit url;
            hash = "sha256-DNHcHTIi7pw0rsVtpyGTyLVElq3IoO2YX/OkDbdeQyo=";
            upstreamTriplet = "x86_64-apple-darwin21.6.0";
          };
          x86_64-linux = {
            inherit url;
            hash = "sha256-DC95udGSzRDE22ON4UpekxTYWOSBeUdJvILbSFj6MFQ=";
            upstreamTriplet = "x86_64-pc-linux-gnu";
          };
        }
        .${stdenv.hostPlatform.system} or throwUnsupportedSystem;
        "14" = {
          gccVersion = "14.2.0";
          alireRevision = "1";
        }
        // {
          x86_64-darwin = {
            inherit url;
            hash = "sha256-3YOnvuI6Qq7huQcqgFSz/o+ZgY2wNkKDqHIuzNz1MVY=";
            upstreamTriplet = "x86_64-apple-darwin21.6.0";
          };
          x86_64-linux = {
            inherit url;
            hash = "sha256-pH3IuOpCM9sY/ppTYcxBmgpsUiMrisIjmAa/rmmZXb4=";
            upstreamTriplet = "x86_64-pc-linux-gnu";
          };
          aarch64-linux = {
            inherit url;
            hash = "sha256-SVW/0yyj6ZH1GAjvD+unII+zSLGd3KGFt1bjjQ3SEFU=";
            upstreamTriplet = "aarch64-linux-gnu";
          };
        }
        .${stdenv.hostPlatform.system} or throwUnsupportedSystem;
      };
    inherit (versionMap.${majorVersion}) gccVersion alireRevision upstreamTriplet;
  in
  {
    pname = "gnat-bootstrap";
    inherit (versionMap.${majorVersion}) gccVersion alireRevision;

    version = "${gccVersion}${lib.optionalString (alireRevision != "") "-"}${alireRevision}";

    src = fetchzip {
      inherit (versionMap.${majorVersion}) url hash;
    };

    nativeBuildInputs = [
      dejagnu
      gmp
      guile
      libipt
      mpfr
      python3
      readline
      sourceHighlight
      zlib
    ]
    ++ lib.optionals stdenv.buildPlatform.isLinux [
      autoPatchelfHook
      glibc
    ]
    ++ lib.optionals (lib.meta.availableOn stdenv.buildPlatform elfutils) [
      elfutils
    ];

    buildInputs = [
      expat
    ]
    ++ lib.optionals (lib.versionAtLeast majorVersion "13") [
      ncurses
    ]
    ++ lib.optionals (lib.versionOlder majorVersion "13") [
      ncurses5
    ]
    ++ [
      xz
    ]
    ++
      lib.optionals
        (
          lib.versionAtLeast majorVersion "14" && stdenv.hostPlatform.isAarch64 && stdenv.hostPlatform.isLinux
        )
        [
          # not sure why the bootstrap binaries link to zstd only on this architecture but they do
          zstd
        ];

    strictDeps = true;

    # https://github.com/alire-project/GNAT-FSF-builds/issues/51
    autoPatchelfIgnoreMissingDeps =
      if (stdenv.buildPlatform.isLinux && majorVersion == "13") then true else null;

    postPatch =
      lib.optionalString (stdenv.hostPlatform.isDarwin) ''
        substituteInPlace lib/gcc/${upstreamTriplet}/${gccVersion}/install-tools/mkheaders.conf \
          --replace "SYSTEM_HEADER_DIR=\"/usr/include\"" "SYSTEM_HEADER_DIR=\"/include\""
      ''
      # The included fixincl binary that is called during header fixup has a
      # hardcoded execvp("/usr/bin/sed", ...) call, but /usr/bin/sed isn't
      # available in the Nix Darwin stdenv.  Fortunately, execvp() will search the
      # PATH environment variable for the executable if its first argument does not
      # contain a slash, so we can just change the string to "sed" and zero the
      # other bytes.
      + ''
        sed -i "s,/usr/bin/sed,sed\x00\x00\x00\x00\x00\x00\x00\x00\x00," libexec/gcc/${upstreamTriplet}/${gccVersion}/install-tools/fixincl
      ''
      # Make sure that collect2 finds binutils-wrapper instead of the included ld binary.
      + ''
        rm -f bin/ld ${upstreamTriplet}/bin/ld
      '';

    installPhase = ''
      mkdir -p $out
      cp -ar * $out/
    ''

    # So far with the Darwin gnat-bootstrap binary packages, there have been two
    # types of dylib path references to other dylibs that need fixups:
    #
    # 1.  Dylibs in $out/lib with paths starting with
    #     /Users/runner/.../gcc/install that refer to other dylibs in $out/lib
    # 2.  Dylibs in $out/lib/gcc/*/*/adalib with paths starting with
    #     @rpath that refer to other dylibs in $out/lib/gcc/*/*/adalib
    #
    # Additionally, per Section 14.4 Fixed Headers in the GCC 12.2.0 manual [2],
    # we have to update the fixed header files in current Alire GCC package, since it
    # was built against macOS 10.15 (Darwin 19.6.0), but Nix currently
    # builds against macOS 10.12, and the two header file structures differ.
    # For example, the current Alire GCC package has a fixed <stdio.h>
    # from macOS 10.15 that contains a #include <_stdio.h>, but neither the Alire
    # GCC package nor macOS 10.12 have such a header (<xlocale/_stdio.h> and
    # <secure/_stdio.h> in 10.12 are not equivalent; indeed, 10.15 <_stdio.h>
    # says it contains code shared by <stdio.h> and <xlocale/_stdio.h>).
    #
    # [2]: https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/Fixed-Headers.html

    + lib.optionalString (stdenv.hostPlatform.isDarwin) ''
      upstreamBuildPrefix="/Users/runner/work/GNAT-FSF-builds/GNAT-FSF-builds/sbx/x86_64-darwin/gcc/install"
      for i in "$out"/lib/*.dylib "$out"/lib/gcc/*/*/adalib/*.dylib; do
        if [[ -f "$i" && ! -h "$i" ]]; then
          install_name_tool -id "$i" "$i" || true
          for old_path in $(otool -L "$i" | grep "$upstreamBuildPrefix" | awk '{print $1}'); do
            new_path=`echo "$old_path" | sed "s,$upstreamBuildPrefix,$out,"`
            install_name_tool -change "$old_path" "$new_path" "$i" || true
          done
          for old_path in $(otool -L "$i" | grep "@rpath" | awk '{print $1}'); do
            new_path=$(echo "$old_path" | sed "s,@rpath,$(dirname "$i"),")
            install_name_tool -change "$old_path" "$new_path" "$i" || true
          done
        fi
      done

    ''

    # x86_64-darwin needs this for the reason above, and aarch64-linux needs it
    # to avoid https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118009,
    # but x86_64-linux doesn't seem to need it.
    + lib.optionalString (stdenv.hostPlatform.system != "x86_64-linux") ''
      "$out"/libexec/gcc/${upstreamTriplet}/${gccVersion}/install-tools/mkheaders -v -v \
        "$out" "${stdenv.cc.libc}"
    '';

    passthru = {
      langC = true; # TRICK for gcc-wrapper to wrap it
      langCC = false;
      langFortran = false;
      langAda = true;
      isGNU = true;
    };

    meta = {
      description = "GNAT, the GNU Ada Translator";
      homepage = "https://www.gnu.org/software/gnat";
      license = lib.licenses.gpl3;
      maintainers = with lib.maintainers; [ ethindp ];
      platforms = [
        "x86_64-linux"
        "x86_64-darwin"
      ]
      ++ lib.optionals (lib.versionAtLeast majorVersion "14") [ "aarch64-linux" ];
      sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ];
    };
  }
)