summaryrefslogtreecommitdiffstats
path: root/pkgs/by-name/ne/newlib/package.nix
blob: 71f98d63ed6e6f4780a7d3eb2a9d45d04ad32864 (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
{
  stdenvNoLibc,
  fetchurl,
  buildPackages,
  lib,
  fetchpatch,
  texinfo,
  # "newlib-nano" is what the official ARM embedded toolchain calls this build
  # configuration that prioritizes low space usage. We include it as a preset
  # for embedded projects striving for a similar configuration.
  nanoizeNewlib ? false,
}:

stdenvNoLibc.mkDerivation (finalAttrs: {
  pname = "newlib";
  version = "4.6.0.20260123";

  src = fetchurl {
    url = "ftp://sourceware.org/pub/newlib/newlib-${finalAttrs.version}.tar.gz";
    sha256 = "sha256-b/J+O/AiZm9D94AiVb5oDu/3IqwYGxcl0h4ugxhgTuM=";
  };

  patches = lib.optionals nanoizeNewlib [
    # https://bugs.gentoo.org/723756
    (fetchpatch {
      name = "newlib-3.3.0-no-nano-cxx.patch";
      url = "https://gitweb.gentoo.org/repo/gentoo.git/plain/sys-libs/newlib/files/newlib-3.3.0-no-nano-cxx.patch?id=9ee5a1cd6f8da6d084b93b3dbd2e8022a147cfbf";
      sha256 = "sha256-S3mf7vwrzSMWZIGE+d61UDH+/SK/ao1hTPee1sElgco=";
    })
  ];

  depsBuildBuild = [
    buildPackages.stdenv.cc
    texinfo # for makeinfo
  ];

  # newlib expects CC to build for build platform, not host platform
  preConfigure = ''
    export CC=cc
  ''
  +
    # newlib tries to disable itself when building for Linux *except*
    # when native-compiling.  Unfortunately the check for "is cross
    # compiling" was written when newlib was part of GCC and newlib
    # was built along with GCC (therefore newlib was built to execute
    # on the targetPlatform, not the hostPlatform).  Unfortunately
    # when newlib was extracted from GCC, this "is cross compiling"
    # logic was not fixed.  So we must disable it.
    ''
      substituteInPlace configure --replace 'noconfigdirs target-newlib target-libgloss' 'noconfigdirs'
      substituteInPlace configure --replace 'cross_only="target-libgloss target-newlib' 'cross_only="'
    '';

  configurePlatforms = [
    "build"
    "target"
  ];
  # flags copied from https://community.arm.com/support-forums/f/compilers-and-libraries-forum/53310/gcc-arm-none-eabi-what-were-the-newlib-compilation-options
  # sort alphabetically
  configureFlags = [
    "--with-newlib"

    # The newlib configury uses `host` to refer to the platform
    # which is being used to compile newlib.  Ugh.  It does this
    # because of its history: newlib used to be distributed with and
    # built as part of gcc.
    #
    # To prevent nixpkgs from going insane, this package presents the
    # "normal" view to the outside world: the binaries in $out will
    # execute on `stdenv.hostPlatform`.  We then fool newlib's build
    # process into doing the right thing.
    "--host=${stdenvNoLibc.targetPlatform.config}"

  ]
  ++ (
    if !nanoizeNewlib then
      [
        "--disable-newlib-supplied-syscalls"
        "--disable-nls"
        "--enable-newlib-io-c99-formats"
        "--enable-newlib-io-long-long"
        "--enable-newlib-reent-check-verify"
        "--enable-newlib-register-fini"
        "--enable-newlib-retargetable-locking"
      ]
    else
      [
        "--disable-newlib-fseek-optimization"
        "--disable-newlib-fvwrite-in-streamio"
        "--disable-newlib-supplied-syscalls"
        "--disable-newlib-unbuf-stream-opt"
        "--disable-newlib-wide-orient"
        "--disable-nls"
        "--enable-lite-exit"
        "--enable-newlib-global-atexit"
        "--enable-newlib-nano-formatted-io"
        "--enable-newlib-nano-malloc"
        "--enable-newlib-reent-check-verify"
        "--enable-newlib-reent-small"
        "--enable-newlib-retargetable-locking"
      ]
  );

  enableParallelBuilding = true;
  # install: cannot create regular file '.../powerpc-none-eabi/lib/crt0.o': File exists
  enableParallelInstalling = false;
  dontDisableStatic = true;

  # apply necessary nano changes from https://developer.arm.com/-/media/Files/downloads/gnu/12.2.rel1/manifest/copy_nano_libraries.sh?rev=4c50be6ccb9c4205a5262a3925317073&hash=1375A7B0A1CD0DB9B9EB0D2B574ADF66
  postInstall =
    lib.optionalString nanoizeNewlib ''
      mkdir -p $out${finalAttrs.passthru.incdir}/newlib-nano
      cp $out${finalAttrs.passthru.incdir}/newlib.h $out${finalAttrs.passthru.incdir}/newlib-nano/

      (
        cd $out${finalAttrs.passthru.libdir}

        for f in librdimon.a libc.a libm.a libg.a libgloss.a; do
          # Some libraries are only available for specific architectures.
          # For example, librdimon.a is only available on ARM.
          if [ -f "$f" ]; then
            dst="''${f%%\.a}_nano.a"
            >&2 echo "$f -> $dst"
            cp "$f" "$dst"
          fi
        done
      )
    ''
    + ''[ "$(find $out -type f | wc -l)" -gt 0 ] || (echo '$out is empty' 1>&2 && exit 1)'';

  passthru = {
    incdir = "/${stdenvNoLibc.targetPlatform.config}/include";
    libdir = "/${stdenvNoLibc.targetPlatform.config}/lib";
  };

  meta = {
    description = "C library intended for use on embedded systems";
    homepage = "https://sourceware.org/newlib/";
    # arch has "bsd" while gentoo has "NEWLIB LIBGLOSS GPL-2" while COPYING has "gpl2"
    # there are 5 copying files in total
    # COPYING
    # COPYING.LIB
    # COPYING.LIBGLOSS
    # COPYING.NEWLIB
    # COPYING3
    license = lib.licenses.gpl2Plus;
  };
})