1{ stdenv
2, cmake
3, coreutils
4, glibc
5, which
6, perl
7, libedit
8, ninja
9, pkgconfig
10, sqlite
11, swig
12, bash
13, libxml2
14, clang
15, python
16, ncurses
17, libuuid
18, libbsd
19, icu
20, autoconf
21, libtool
22, automake
23, libblocksruntime
24, curl
25, rsync
26, git
27, libgit2
28, fetchFromGitHub
29, fetchpatch
30, findutils
31, makeWrapper
32, gnumake
33, file
34}:
35
36let
37 version = "5.1.1";
38
39 fetch = { repo, sha256, fetchSubmodules ? false }:
40 fetchFromGitHub {
41 owner = "apple";
42 inherit repo sha256 fetchSubmodules;
43 rev = "swift-${version}-RELEASE";
44 name = "${repo}-${version}-src";
45 };
46
47 sources = {
48 llvm = fetch {
49 repo = "swift-llvm";
50 sha256 = "00ldd9dby6fl6nk3z17148fvb7g9x4jkn1afx26y51v8rwgm1i7f";
51 };
52 compilerrt = fetch {
53 repo = "swift-compiler-rt";
54 sha256 = "1431f74l0n2dxn728qp65nc6hivx88fax1wzfrnrv19y77br05wj";
55 };
56 clang = fetch {
57 repo = "swift-clang";
58 sha256 = "0n7k6nvzgqp6h6bfqcmna484w90db3zv4sh5rdh89wxyhdz6rk4v";
59 };
60 clangtools = fetch {
61 repo = "swift-clang-tools-extra";
62 sha256 = "0snp2rpd60z239pr7fxpkj332rkdjhg63adqvqdkjsbrxcqqcgqa";
63 };
64 indexstore = fetch {
65 repo = "indexstore-db";
66 sha256 = "1gwkqkdmpd5hn7555dpdkys0z50yh00hjry2886h6rx7avh5p05n";
67 };
68 sourcekit = fetch {
69 repo = "sourcekit-lsp";
70 sha256 = "0k84ssr1k7grbvpk81rr21ii8csnixn9dp0cga98h6i1gshn8ml4";
71 };
72 cmark = fetch {
73 repo = "swift-cmark";
74 sha256 = "079smm79hbwr06bvghd2sb86b8gpkprnzlyj9kh95jy38xhlhdnj";
75 };
76 lldb = fetch {
77 repo = "swift-lldb";
78 sha256 = "0j787475f0nlmvxqblkhn3yrvn9qhcb2jcijwijxwq95ar2jdygs";
79 };
80 llbuild = fetch {
81 repo = "swift-llbuild";
82 sha256 = "1n2s5isxyl6b6ya617gdzjbw68shbvd52vsfqc1256rk4g448v8b";
83 };
84 pm = fetch {
85 repo = "swift-package-manager";
86 sha256 = "1a49jmag5mpld9zr96g8a773334mrz1c4nyw38gf4p6sckf4jp29";
87 };
88 xctest = fetch {
89 repo = "swift-corelibs-xctest";
90 sha256 = "0rxy9sq7i0s0kxfkz0hvdp8zyb40h31f7g4m0kry36qk82gzzh89";
91 };
92 foundation = fetch {
93 repo = "swift-corelibs-foundation";
94 sha256 = "1iiiijsnys0r3hjcj1jlkn3yszzi7hwb2041cnm5z306nl9sybzp";
95 };
96 libdispatch = fetch {
97 repo = "swift-corelibs-libdispatch";
98 sha256 = "0laqsizsikyjhrzn0rghvxd8afg4yav7cbghvnf7ywk9wc6kpkmn";
99 fetchSubmodules = true;
100 };
101 swift = fetch {
102 repo = "swift";
103 sha256 = "0m4r1gzrnn0s1c7haqq9dlmvpqxbgbkbdfmq6qaph869wcmvdkvy";
104 };
105 };
106
107 devInputs = [
108 curl
109 glibc
110 icu
111 libblocksruntime
112 libbsd
113 libedit
114 libuuid
115 libxml2
116 ncurses
117 sqlite
118 swig
119 ];
120
121 cmakeFlags = [
122 "-DGLIBC_INCLUDE_PATH=${stdenv.cc.libc.dev}/include"
123 "-DC_INCLUDE_DIRS=${stdenv.lib.makeSearchPathOutput "dev" "include" devInputs}:${libxml2.dev}/include/libxml2"
124 "-DGCC_INSTALL_PREFIX=${clang.cc.gcc}"
125 ];
126
127in
128stdenv.mkDerivation {
129 name = "swift-${version}";
130
131 nativeBuildInputs = [
132 autoconf
133 automake
134 bash
135 cmake
136 coreutils
137 findutils
138 gnumake
139 libtool
140 makeWrapper
141 ninja
142 perl
143 pkgconfig
144 python
145 rsync
146 which
147 ];
148 buildInputs = devInputs ++ [
149 clang
150 ];
151
152 # TODO: Revisit what's propagated and how
153 propagatedBuildInputs = [
154 libgit2
155 python
156 ];
157 propagatedUserEnvPkgs = [ git pkgconfig ];
158
159 hardeningDisable = [ "format" ]; # for LLDB
160
161 unpackPhase = ''
162 mkdir src
163 cd src
164 export SWIFT_SOURCE_ROOT=$PWD
165
166 cp -r ${sources.llvm} llvm
167 cp -r ${sources.compilerrt} compiler-rt
168 cp -r ${sources.clang} clang
169 cp -r ${sources.clangtools} clang-tools-extra
170 cp -r ${sources.indexstore} indexstore-db
171 cp -r ${sources.sourcekit} sourcekit-lsp
172 cp -r ${sources.cmark} cmark
173 cp -r ${sources.lldb} lldb
174 cp -r ${sources.llbuild} llbuild
175 cp -r ${sources.pm} swiftpm
176 cp -r ${sources.xctest} swift-corelibs-xctest
177 cp -r ${sources.foundation} swift-corelibs-foundation
178 cp -r ${sources.libdispatch} swift-corelibs-libdispatch
179 cp -r ${sources.swift} swift
180
181 chmod -R u+w .
182 '';
183
184 patchPhase = ''
185 # Just patch all the things for now, we can focus this later
186 patchShebangs $SWIFT_SOURCE_ROOT
187
188 # TODO eliminate use of env.
189 find -type f -print0 | xargs -0 sed -i \
190 -e 's|/usr/bin/env|${coreutils}/bin/env|g' \
191 -e 's|/usr/bin/make|${gnumake}/bin/make|g' \
192 -e 's|/bin/mkdir|${coreutils}/bin/mkdir|g' \
193 -e 's|/bin/cp|${coreutils}/bin/cp|g' \
194 -e 's|/usr/bin/file|${file}/bin/file|g'
195
196 substituteInPlace swift/stdlib/public/Platform/CMakeLists.txt \
197 --replace '/usr/include' "${stdenv.cc.libc.dev}/include"
198 substituteInPlace swift/utils/build-script-impl \
199 --replace '/usr/include/c++' "${clang.cc.gcc}/include/c++"
200 patch -p1 -d swift -i ${./patches/glibc-arch-headers.patch}
201 patch -p1 -d swift -i ${./patches/0001-build-presets-linux-don-t-require-using-Ninja.patch}
202 patch -p1 -d swift -i ${./patches/0002-build-presets-linux-allow-custom-install-prefix.patch}
203 patch -p1 -d swift -i ${./patches/0003-build-presets-linux-don-t-build-extra-libs.patch}
204 patch -p1 -d swift -i ${./patches/0004-build-presets-linux-plumb-extra-cmake-options.patch}
205
206 sed -i swift/utils/build-presets.ini \
207 -e 's/^test-installable-package$/# \0/' \
208 -e 's/^test$/# \0/' \
209 -e 's/^validation-test$/# \0/' \
210 -e 's/^long-test$/# \0/' \
211 -e 's/^stress-test$/# \0/' \
212 -e 's/^test-optimized$/# \0/' \
213 \
214 -e 's/^swift-install-components=autolink.*$/\0;editor-integration/'
215
216 substituteInPlace clang/lib/Driver/ToolChains/Linux.cpp \
217 --replace 'SysRoot + "/lib' '"${glibc}/lib" "'
218 substituteInPlace clang/lib/Driver/ToolChains/Linux.cpp \
219 --replace 'SysRoot + "/usr/lib' '"${glibc}/lib" "'
220 patch -p1 -d clang -i ${./patches/llvm-toolchain-dir.patch}
221 patch -p1 -d clang -i ${./purity.patch}
222
223 # Workaround hardcoded dep on "libcurses" (vs "libncurses"):
224 sed -i 's/curses/ncurses/' llbuild/*/*/CMakeLists.txt
225 # uuid.h is not part of glibc, but of libuuid
226 sed -i 's|''${GLIBC_INCLUDE_PATH}/uuid/uuid.h|${libuuid.dev}/include/uuid/uuid.h|' swift/stdlib/public/Platform/glibc.modulemap.gyb
227
228 # Compatibility with glibc 2.30
229 # Adapted from https://github.com/apple/swift-package-manager/pull/2408
230 patch -p1 -d swiftpm -i ${./patches/swift-package-manager-glibc-2.30.patch}
231 # https://github.com/apple/swift/pull/27288
232 patch -p1 -d swift -i ${fetchpatch {
233 url = "https://github.com/apple/swift/commit/f968f4282d53f487b29cf456415df46f9adf8748.patch";
234 sha256 = "1aa7l66wlgip63i4r0zvi9072392bnj03s4cn12p706hbpq0k37c";
235 }}
236
237 PREFIX=''${out/#\/}
238 substituteInPlace indexstore-db/Utilities/build-script-helper.py \
239 --replace usr "$PREFIX"
240 substituteInPlace sourcekit-lsp/Utilities/build-script-helper.py \
241 --replace usr "$PREFIX"
242 substituteInPlace swift-corelibs-xctest/build_script.py \
243 --replace usr "$PREFIX"
244 '';
245
246 configurePhase = ''
247 cd ..
248
249 mkdir build install
250 export SWIFT_BUILD_ROOT=$PWD/build
251 export SWIFT_INSTALL_DIR=$PWD/install
252
253 export INSTALLABLE_PACKAGE=$PWD/swift.tar.gz
254 export NIX_ENFORCE_PURITY=
255
256 cd $SWIFT_BUILD_ROOT
257 '';
258
259 buildPhase = ''
260 # gcc-6.4.0/include/c++/6.4.0/cstdlib:75:15: fatal error: 'stdlib.h' file not found
261 export NIX_CFLAGS_COMPILE="$( echo ${clang.default_cxx_stdlib_compile} ) $NIX_CFLAGS_COMPILE"
262 # During the Swift build, a full local LLVM build is performed and the resulting clang is invoked.
263 # This compiler is not using the Nix wrappers, so it needs some help to find things.
264 export NIX_LDFLAGS_BEFORE="-rpath ${clang.cc.gcc.lib}/lib -L${clang.cc.gcc.lib}/lib $NIX_LDFLAGS_BEFORE"
265 # However, we want to use the wrapped compiler whenever possible.
266 export CC="${clang}/bin/clang"
267
268 # fix for https://bugs.llvm.org/show_bug.cgi?id=39743
269 # see also https://forums.swift.org/t/18138/15
270 export CCC_OVERRIDE_OPTIONS="#x-fmodules s/-fmodules-cache-path.*//"
271
272 $SWIFT_SOURCE_ROOT/swift/utils/build-script \
273 --preset=buildbot_linux \
274 installable_package=$INSTALLABLE_PACKAGE \
275 install_prefix=$out \
276 install_destdir=$SWIFT_INSTALL_DIR \
277 extra_cmake_options="${stdenv.lib.concatStringsSep "," cmakeFlags}"
278 '';
279
280 doCheck = true;
281
282 checkInputs = [ file ];
283
284 checkPhase = ''
285 # FIXME: disable non-working tests
286 rm $SWIFT_SOURCE_ROOT/swift/test/Driver/static-stdlib-linux.swift # static linkage of libatomic.a complains about missing PIC
287 rm $SWIFT_SOURCE_ROOT/swift/validation-test/Python/build_swift.swift # install_prefix not passed properly
288
289 # match the swift wrapper in the install phase
290 export LIBRARY_PATH=${icu}/lib:${libuuid.out}/lib
291
292 checkTarget=check-swift-all
293 ninjaFlags='-C buildbot_linux/swift-${stdenv.hostPlatform.parsed.kernel.name}-${stdenv.hostPlatform.parsed.cpu.name}'
294 ninjaCheckPhase
295 '';
296
297 installPhase = ''
298 mkdir -p $out
299
300 # Extract the generated tarball into the store
301 tar xf $INSTALLABLE_PACKAGE -C $out --strip-components=3 ''${out/#\/}
302 find $out -type d -empty -delete
303
304 # fix installation weirdness, also present in Apple’s official tarballs
305 mv $out/local/include/indexstore $out/include
306 rmdir $out/local/include $out/local
307 rm -r $out/bin/sdk-module-lists $out/bin/swift-api-checker.py
308
309 wrapProgram $out/bin/swift \
310 --suffix C_INCLUDE_PATH : $out/lib/swift/clang/include \
311 --suffix CPLUS_INCLUDE_PATH : $out/lib/swift/clang/include \
312 --suffix LIBRARY_PATH : ${icu}/lib:${libuuid.out}/lib
313 '';
314
315 # Hack to avoid build and install directories in RPATHs.
316 preFixup = ''rm -rf $SWIFT_BUILD_ROOT $SWIFT_INSTALL_DIR'';
317
318 meta = with stdenv.lib; {
319 description = "The Swift Programming Language";
320 homepage = https://github.com/apple/swift;
321 maintainers = with maintainers; [ dtzWill ];
322 license = licenses.asl20;
323 # Swift doesn't support 32bit Linux, unknown on other platforms.
324 platforms = platforms.linux;
325 badPlatforms = platforms.i686;
326 broken = stdenv.isAarch64; # 2018-09-04, never built on Hydra
327 };
328}