1{ stdenv
2, targetPackages
3, cmake
4, coreutils
5, glibc
6, which
7, perl
8, libedit
9, ninja
10, pkgconfig
11, sqlite
12, swig
13, bash
14, libxml2
15, clang
16, python
17, ncurses
18, libuuid
19, libbsd
20, icu
21, autoconf
22, libtool
23, automake
24, libblocksruntime
25, curl
26, rsync
27, git
28, libgit2
29, fetchFromGitHub
30, fetchpatch
31, paxctl
32, findutils
33, makeWrapper
34, gnumake
35, file
36#, systemtap
37}:
38
39let
40 v_major = "4.0.3";
41 version = "${v_major}-RELEASE";
42 version_friendly = "${v_major}";
43
44 tag = "refs/tags/swift-${version}";
45 fetch = { repo, sha256, fetchSubmodules ? false }:
46 fetchFromGitHub {
47 owner = "apple";
48 inherit repo sha256 fetchSubmodules;
49 rev = tag;
50 name = "${repo}-${version}-src";
51 };
52
53 sources = {
54 # FYI: SourceKit probably would work but currently requires building everything twice
55 # For more inforation, see: https://github.com/apple/swift/pull/3594#issuecomment-234169759
56 clang = fetch {
57 repo = "swift-clang";
58 sha256 = "0zm624iwiprk3c3nzqf4p1fd9zqic4yi3jv51cw3249ax4x6vy10";
59 };
60 llvm = fetch {
61 repo = "swift-llvm";
62 sha256 = "11vw6461c0cdvwm1wna1a5709fjj14hzp6br6jg94p4f6jp3yv4d";
63 };
64 compilerrt = fetch {
65 repo = "swift-compiler-rt";
66 sha256 = "1hj4qaj4c9n2wzg2cvarbyl0n708zd1dlw4zkzq07fjxxqs36nfa";
67 };
68 cmark = fetch {
69 repo = "swift-cmark";
70 sha256 = "1nmxp0fj749sgar682c5nsj7zxxigqwg973baxj2r656a7ybh325";
71 };
72 lldb = fetch {
73 repo = "swift-lldb";
74 sha256 = "0yk5qg85008vcn63vn2jpn5ls9pdhda222p2w1cfkrj27k5k8vqr";
75 };
76 llbuild = fetch {
77 repo = "swift-llbuild";
78 sha256 = "0jffw6z1s6ck1i05brw59x6vsg7zrxbz5n2wz72fj29rh3nppc7a";
79 };
80 pm = fetch {
81 repo = "swift-package-manager";
82 sha256 = "0xj070b8fii7ijfsnyq4fxgv6569vdrg0yippi85h2p1l7s9aagh";
83 };
84 xctest = fetch {
85 repo = "swift-corelibs-xctest";
86 sha256 = "0l355wq8zfwrpv044xf4smjwbm0bmib360748n8cwls3vkr9l2yv";
87 };
88 foundation = fetch {
89 repo = "swift-corelibs-foundation";
90 sha256 = "0s7yc5gsbd96a4bs8c6q24dyfjm4xhcr2nzhl2ics8dmi60j15s4";
91 };
92 libdispatch = fetch {
93 repo = "swift-corelibs-libdispatch";
94 sha256 = "0x8zzq3shhvmhq4sbhaaa0ddiv3nw347pz6ayym6jyzq7j9n15ia";
95 fetchSubmodules = true;
96 };
97 swift = fetch {
98 repo = "swift";
99 sha256 = "0a1gq0k5701i418f0qi7kywv16q7vh4a4wp0f6fpyv4sjkq27msx";
100 };
101 };
102
103 devInputs = [
104 curl
105 glibc
106 icu
107 libblocksruntime
108 libbsd
109 libedit
110 libuuid
111 libxml2
112 ncurses
113 sqlite
114 swig
115 # systemtap?
116 ];
117
118 cmakeFlags = [
119 "-DGLIBC_INCLUDE_PATH=${stdenv.cc.libc.dev}/include"
120 "-DC_INCLUDE_DIRS=${stdenv.lib.makeSearchPathOutput "dev" "include" devInputs}:${libxml2.dev}/include/libxml2"
121 "-DGCC_INSTALL_PREFIX=${clang.cc.gcc}"
122 ];
123
124 builder = ''
125 # gcc-6.4.0/include/c++/6.4.0/cstdlib:75:15: fatal error: 'stdlib.h' file not found
126 NIX_CFLAGS_COMPILE="$( echo ${clang.default_cxx_stdlib_compile} ) $NIX_CFLAGS_COMPILE"
127
128 $SWIFT_SOURCE_ROOT/swift/utils/build-script \
129 --preset=buildbot_linux \
130 installable_package=$INSTALLABLE_PACKAGE \
131 install_prefix=$out \
132 install_destdir=$SWIFT_INSTALL_DIR \
133 extra_cmake_options="${stdenv.lib.concatStringsSep "," cmakeFlags}"'';
134
135 # from llvm/4/llvm.nix
136 sigaltstackPatch = fetchpatch {
137 name = "sigaltstack.patch"; # for glibc-2.26
138 url = https://github.com/llvm-mirror/compiler-rt/commit/8a5e425a68d.diff;
139 sha256 = "0h4y5vl74qaa7dl54b1fcyqalvlpd8zban2d1jxfkxpzyi7m8ifi";
140 };
141
142 # https://bugs.swift.org/browse/SR-6409
143 sigunusedPatch = fetchpatch {
144 name = "sigunused.patch";
145 url = "https://github.com/apple/swift-llbuild/commit/303a89bc6da606c115560921a452686aa0655f5e.diff";
146 sha256 = "04sw7ym1grzggj1v3xrzr2ljxz8rf9rnn9n5fg1xjbwlrdagkc7m";
147 };
148in
149stdenv.mkDerivation rec {
150 name = "swift-${version_friendly}";
151
152 buildInputs = devInputs ++ [
153 autoconf
154 automake
155 bash
156 clang
157 cmake
158 coreutils
159 libtool
160 ninja
161 perl
162 pkgconfig
163 python
164 rsync
165 which
166 findutils
167 makeWrapper
168 gnumake
169 ] ++ stdenv.lib.optional stdenv.needsPax paxctl;
170
171 # TODO: Revisit what's propagated and how
172 propagatedBuildInputs = [
173 libgit2
174 python
175 ];
176 propagatedUserEnvPkgs = [ git pkgconfig ];
177
178 hardeningDisable = [ "format" ]; # for LLDB
179
180 configurePhase = ''
181 cd ..
182
183 export INSTALLABLE_PACKAGE=$PWD/swift.tar.gz
184
185 mkdir build install
186 export SWIFT_BUILD_ROOT=$PWD/build
187 export SWIFT_INSTALL_DIR=$PWD/install
188
189 cd $SWIFT_BUILD_ROOT
190
191 unset CC
192 unset CXX
193
194 export NIX_ENFORCE_PURITY=
195 '';
196
197 unpackPhase = ''
198 mkdir src
199 cd src
200 export sourceRoot=$PWD
201 export SWIFT_SOURCE_ROOT=$PWD
202
203 cp -r ${sources.clang} clang
204 cp -r ${sources.llvm} llvm
205 cp -r ${sources.compilerrt} compiler-rt
206 cp -r ${sources.cmark} cmark
207 cp -r ${sources.lldb} lldb
208 cp -r ${sources.llbuild} llbuild
209 cp -r ${sources.pm} swiftpm
210 cp -r ${sources.xctest} swift-corelibs-xctest
211 cp -r ${sources.foundation} swift-corelibs-foundation
212 cp -r ${sources.libdispatch} swift-corelibs-libdispatch
213 cp -r ${sources.swift} swift
214
215 chmod -R u+w .
216 '';
217
218 patchPhase = ''
219 # Just patch all the things for now, we can focus this later
220 patchShebangs $SWIFT_SOURCE_ROOT
221
222 # TODO eliminate use of env.
223 find -type f -print0 | xargs -0 sed -i \
224 -e 's|/usr/bin/env|${coreutils}/bin/env|g' \
225 -e 's|/usr/bin/make|${gnumake}/bin/make|g' \
226 -e 's|/bin/mkdir|${coreutils}/bin/mkdir|g' \
227 -e 's|/bin/cp|${coreutils}/bin/cp|g' \
228 -e 's|/usr/bin/file|${file}/bin/file|g'
229
230 substituteInPlace swift/stdlib/public/Platform/CMakeLists.txt \
231 --replace '/usr/include' "${stdenv.cc.libc.dev}/include"
232 substituteInPlace swift/utils/build-script-impl \
233 --replace '/usr/include/c++' "${clang.cc.gcc}/include/c++"
234 '' + stdenv.lib.optionalString stdenv.needsPax ''
235 patch -p1 -d swift -i ${./patches/build-script-pax.patch}
236 '' + ''
237 patch -p1 -d swift -i ${./patches/0001-build-presets-linux-don-t-require-using-Ninja.patch}
238 patch -p1 -d swift -i ${./patches/0002-build-presets-linux-allow-custom-install-prefix.patch}
239 patch -p1 -d swift -i ${./patches/0003-build-presets-linux-disable-tests.patch}
240 patch -p1 -d swift -i ${./patches/0004-build-presets-linux-plumb-extra-cmake-options.patch}
241 # https://sourceware.org/glibc/wiki/Release/2.26#Removal_of_.27xlocale.h.27
242 patch -p1 -i ${./patches/remove_xlocale.patch}
243 # https://bugs.swift.org/browse/SR-4633
244 patch -p1 -d swift -i ${./patches/icu59.patch}
245
246 # https://bugs.swift.org/browse/SR-5779
247 sed -i -e 's|"-latomic"|"-Wl,-rpath,${clang.cc.gcc.lib}/lib" "-L${clang.cc.gcc.lib}/lib" "-latomic"|' swift/cmake/modules/AddSwift.cmake
248
249 # https://bugs.swift.org/browse/SR-4838
250 sed -i -e '30i#include <functional>' lldb/include/lldb/Utility/TaskPool.h
251
252 substituteInPlace clang/lib/Driver/ToolChains.cpp \
253 --replace ' addPathIfExists(D, SysRoot + "/usr/lib", Paths);' \
254 ' addPathIfExists(D, SysRoot + "/usr/lib", Paths); addPathIfExists(D, "${glibc}/lib", Paths);'
255 patch -p1 -d clang -i ${./purity.patch}
256
257 # Workaround hardcoded dep on "libcurses" (vs "libncurses"):
258 sed -i 's,curses,ncurses,' llbuild/*/*/CMakeLists.txt
259
260 # This test fails on one of my machines, not sure why.
261 # Disabling for now.
262 rm llbuild/tests/Examples/buildsystem-capi.llbuild
263
264 PREFIX=''${out/#\/}
265 substituteInPlace swift-corelibs-xctest/build_script.py \
266 --replace usr "$PREFIX"
267 substituteInPlace swiftpm/Utilities/bootstrap \
268 --replace "usr" "$PREFIX"
269 '' + stdenv.lib.optionalString (stdenv ? glibc) ''
270 patch -p1 -d compiler-rt -i ${sigaltstackPatch}
271 patch -p1 -d compiler-rt -i ${./patches/sigaltstack.patch}
272 patch -p1 -d llbuild -i ${sigunusedPatch}
273 patch -p1 -i ${./patches/sigunused.patch}
274 '';
275
276 doCheck = false;
277
278 buildPhase = builder;
279
280 installPhase = ''
281 mkdir -p $out
282
283 # Extract the generated tarball into the store
284 PREFIX=''${out/#\/}
285 tar xf $INSTALLABLE_PACKAGE -C $out --strip-components=3 $PREFIX
286
287 paxmark pmr $out/bin/swift
288 paxmark pmr $out/bin/*
289
290 # TODO: Use wrappers to get these on the PATH for swift tools, instead
291 ln -s ${clang}/bin/* $out/bin/
292 ln -s ${targetPackages.stdenv.cc.bintools.bintools_bin}/bin/ar $out/bin/ar
293
294 wrapProgram $out/bin/swift \
295 --suffix C_INCLUDE_PATH : $out/lib/swift/clang/include \
296 --suffix CPLUS_INCLUDE_PATH : $out/lib/swift/clang/include
297 '';
298
299 # Hack to avoid TMPDIR in RPATHs.
300 preFixup = ''rm -rf "$(pwd)" '';
301
302 meta = with stdenv.lib; {
303 description = "The Swift Programming Language";
304 homepage = https://github.com/apple/swift;
305 maintainers = with maintainers; [ dtzWill ];
306 license = licenses.asl20;
307 # Swift doesn't support 32bit Linux, unknown on other platforms.
308 platforms = [ "x86_64-linux" ];
309 };
310}
311