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
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
|
# Copyright 1999-2025 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
EAPI=8
LLVM_COMPAT=( {17..22} )
PYTHON_COMPAT=( python3_{13..14} )
inherit flag-o-matic llvm-r2 python-single-r1
DESCRIPTION="A high-level, general-purpose, multi-paradigm, compiled programming language"
HOMEPAGE="https://www.swift.org"
SRC_URI="
https://github.com/apple/swift-argument-parser/archive/refs/tags/1.6.1.tar.gz -> swift-argument-parser-1.6.1.tar.gz
https://github.com/apple/swift-asn1/archive/refs/tags/1.0.0.tar.gz -> swift-asn1-1.0.0.tar.gz
https://github.com/apple/swift-async-algorithms/archive/refs/tags/1.0.1.tar.gz -> swift-async-algorithms-1.0.1.tar.gz
https://github.com/apple/swift-atomics/archive/refs/tags/1.2.0.tar.gz -> swift-atomics-1.2.0.tar.gz
https://github.com/apple/swift-certificates/archive/refs/tags/1.0.1.tar.gz -> swift-certificates-1.0.1.tar.gz
https://github.com/apple/swift-collections/archive/refs/tags/1.1.6.tar.gz -> swift-collections-1.1.6.tar.gz
https://github.com/apple/swift-crypto/archive/refs/tags/3.12.5.tar.gz -> swift-crypto-3.12.5.tar.gz
https://github.com/apple/swift-log/archive/refs/tags/1.5.4.tar.gz -> swift-log-1.5.4.tar.gz
https://github.com/apple/swift-nio/archive/refs/tags/2.65.0.tar.gz -> swift-nio-2.65.0.tar.gz
https://github.com/apple/swift-numerics/archive/refs/tags/1.0.2.tar.gz -> swift-numerics-1.0.2.tar.gz
https://github.com/apple/swift-system/archive/refs/tags/1.5.0.tar.gz -> swift-system-1.5.0.tar.gz
https://github.com/microsoft/mimalloc/archive/refs/tags/v3.0.1.tar.gz -> mimalloc-v3.0.1.tar.gz
https://github.com/swiftlang/indexstore-db/archive/refs/tags/${P}-RELEASE.tar.gz -> indexstore-db-${PV}.tar.gz
https://github.com/swiftlang/llvm-project/archive/refs/tags/${P}-RELEASE.tar.gz -> llvm-project-${PV}.tar.gz
https://github.com/swiftlang/sourcekit-lsp/archive/refs/tags/${P}-RELEASE.tar.gz -> sourcekit-lsp-${PV}.tar.gz
https://github.com/swiftlang/swift-build/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-build-${PV}.tar.gz
https://github.com/swiftlang/swift-cmark/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-cmark-${PV}.tar.gz
https://github.com/swiftlang/swift-corelibs-foundation/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-corelibs-foundation-${PV}.tar.gz
https://github.com/swiftlang/swift-corelibs-libdispatch/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-corelibs-libdispatch-${PV}.tar.gz
https://github.com/swiftlang/swift-corelibs-xctest/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-corelibs-xctest-${PV}.tar.gz
https://github.com/swiftlang/swift-docc-render-artifact/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-docc-render-artifact-${PV}.tar.gz
https://github.com/swiftlang/swift-docc-symbolkit/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-docc-symbolkit-${PV}.tar.gz
https://github.com/swiftlang/swift-docc/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-docc-${PV}.tar.gz
https://github.com/swiftlang/swift-driver/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-driver-${PV}.tar.gz
https://github.com/swiftlang/swift-experimental-string-processing/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-experimental-string-processing-${PV}.tar.gz
https://github.com/swiftlang/swift-format/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-format-${PV}.tar.gz
https://github.com/swiftlang/swift-foundation-icu/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-foundation-icu-${PV}.tar.gz
https://github.com/swiftlang/swift-foundation/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-foundation-${PV}.tar.gz
https://github.com/swiftlang/swift-installer-scripts/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-installer-scripts-${PV}.tar.gz
https://github.com/swiftlang/swift-integration-tests/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-integration-tests-${PV}.tar.gz
https://github.com/swiftlang/swift-llbuild/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-llbuild-${PV}.tar.gz
https://github.com/swiftlang/swift-llvm-bindings/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-llvm-bindings-${PV}.tar.gz
https://github.com/swiftlang/swift-lmdb/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-lmdb-${PV}.tar.gz
https://github.com/swiftlang/swift-markdown/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-markdown-${PV}.tar.gz
https://github.com/swiftlang/swift-package-manager/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-package-manager-${PV}.tar.gz
https://github.com/swiftlang/swift-stress-tester/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-stress-tester-${PV}.tar.gz
https://github.com/swiftlang/swift-subprocess/archive/refs/tags/0.2.1.tar.gz -> swift-subprocess-0.2.1.tar.gz
https://github.com/swiftlang/swift-syntax/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-syntax-${PV}.tar.gz
https://github.com/swiftlang/swift-testing/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-testing-${PV}.tar.gz
https://github.com/swiftlang/swift-toolchain-sqlite/archive/refs/tags/1.0.7.tar.gz -> swift-toolchain-sqlite-1.0.7.tar.gz
https://github.com/swiftlang/swift-tools-protocols/archive/refs/tags/0.0.9.tar.gz -> swift-tools-protocols-0.0.9.tar.gz
https://github.com/swiftlang/swift-tools-support-core/archive/refs/tags/${P}-RELEASE.tar.gz -> swift-tools-support-core-${PV}.tar.gz
https://github.com/swiftlang/swift/archive/refs/tags/${P}-RELEASE.tar.gz -> ${P}.tar.gz
"
PATCHES=(
"${FILESDIR}/${PF}/backtracing-noexecstack.patch"
"${FILESDIR}/${PF}/disable-libdispatch-private-header-check.patch"
"${FILESDIR}/${PF}/disable-libdispatch-werror.patch"
"${FILESDIR}/${PF}/fix-issues-caused-by-build-system-updates.patch"
"${FILESDIR}/${PF}/link-ncurses-tinfo.patch"
"${FILESDIR}/${PF}/link-with-lld.patch"
"${FILESDIR}/${PF}/remove-linux-scc_h.patch"
"${FILESDIR}/${PF}/respect-c-cxx-flags.patch"
)
S="${WORKDIR}"
LICENSE="Apache-2.0"
SLOT="6/3"
KEYWORDS="~amd64"
IUSE="libcxx"
REQUIRED_USE="${PYTHON_REQUIRED_USE}"
RESTRICT="strip"
RDEPEND="
${PYTHON_DEPS}
!~dev-lang/swift-5.10.1:0
>=app-arch/zstd-1.5
>=app-eselect/eselect-swift-1.0-r1
>=dev-db/sqlite-3
>=dev-libs/icu-69
>=dev-libs/libedit-20221030
>=dev-libs/libxml2-2.11.5
>=net-misc/curl-8.9.1
>=sys-libs/ncurses-6
>=virtual/zlib-1.3.1:=
dev-lang/python
$(llvm_gen_dep 'llvm-core/lld:${LLVM_SLOT}=')
libcxx? ( $(llvm_gen_dep '=llvm-runtimes/libcxx-${LLVM_SLOT}*') )
"
# Adapted from `llvm-r2.eclass`'s `llvm_gen_dep` to output conditional
# dependency alocks, which isn't currently supported. If llvm-r2 or a future
# eclass introduces `llvm_gen_cond_dep`, this definition should be dropped in
# favor of that.
#
# Used to conditionally depend on GCC <16 for LLVM_SLOT <22; see `src_configure`
# for more.
_swift_llvm_gen_cond_dep() {
debug-print-function ${FUNCNAME} "$@"
[[ $# -ge 2 ]] || die "Usage: ${FUNCNAME} <dependency> <slot>..."
local dep=${1}
shift
local slot
for slot in "${_LLVM_SLOTS[@]}"; do
for match in $*; do
if [[ "$slot" == "${match}" ]]; then
echo "llvm_slot_${slot}? ( ${dep//\$\{LLVM_SLOT\}/${slot}} )"
fi
done
done
}
BDEPEND="
${PYTHON_DEPS}
>=dev-build/cmake-3.30.2
>=dev-build/ninja-1.13.1
>=dev-db/sqlite-3
>=dev-libs/icu-69
>=dev-libs/libedit-20221030
>=dev-libs/libxml2-2.11.5
>=dev-util/patchelf-0.18
>=dev-vcs/git-2.39
>=sys-apps/coreutils-9
>=sys-devel/gcc-11
>=sys-libs/ncurses-6
>=virtual/zlib-1.3.1:=
|| (
dev-lang/swift
dev-lang/swift-bootstrap
)
$(llvm_gen_dep '
llvm-core/clang:${LLVM_SLOT}=
llvm-core/lld:${LLVM_SLOT}=
')
libcxx? ( $(llvm_gen_dep '=llvm-runtimes/libcxx-${LLVM_SLOT}*') )
!libcxx? ( $(_swift_llvm_gen_cond_dep '<sys-devel/gcc-16' {17..21}) )
dev-lang/python
$(python_gen_cond_dep 'dev-python/setuptools[${PYTHON_USEDEP}]')
"
SWIFT_BUILD_PRESETS_INI_PATH="${S}/gentoo-build-presets.ini"
SWIFT_BUILD_PRESET='gentoo'
PKG_PREINST_SWIFT_INTENTIONALLY_SET='true'
# Adapted from `flag-o-matic.eclass`'s `raw-ldflags`: turns GCC-style flags
# (`-Wl,-foo`) into Clang-style flags (`-Xlinker -foo`).
clang-ldflags() {
local flag input="$@"
[[ -z ${input} ]] && input=${LDFLAGS}
set --
for flag in ${input//,/ } ; do
case ${flag} in
-Wl) ;;
*) set -- "$@" "-Xlinker ${flag}" ;;
esac
done
echo "$@"
}
pkg_setup() {
# Sets `${EPYTHON}` according to `PYTHON_SINGLE_TARGET`, sets up
# `${T}/${EPYTHON}` with that version, and adds it to the `PATH`.
python_setup
# Sets up `PATH` to point to the appropriate LLVM toolchain, and ensure
# we're using the toolchain for compilation.
llvm-r2_pkg_setup
}
src_unpack() {
default
# The Swift project expects a specific directory structure that we have to
# match. For most directories, it's enough to trim the version number at the
# end:
find "${S}" \
-mindepth 1 -maxdepth 1 \
-execdir sh -c \
"mv '{}' \"\$(echo '{}' | sed -e 's_-\(swift-${PV}-RELEASE\|\([0-9]\+\.\)*[0-9]\+\)\$__' | tr '[:upper:]' '[:lower:]')\"" ';' \
|| die
# Some one-off fixups:
pushd "${S}" \
&& mv 'swift-cmark' 'cmark' \
&& mv 'swift-llbuild' 'llbuild' \
&& mv 'swift-package-manager' 'swiftpm' \
&& popd \
|| die
}
src_configure() {
CC="$(type -P clang)"
CXX="$(type -P clang++)"
LD="$(type -P ld.lld)"
# Swift builds with CMake, which picks up `LDFLAGS` from the environment and
# populates `CMAKE_EXE_LINKER_FLAGS` with them. `LDFLAGS` are typically
# given as GCC-style flags (`-Wlinker,foo`), which Clang understands;
# unfortunately, CMake passes these flags to all compilers under the
# assumption they support the same syntax, but `swiftc` _only_ understands
# Clang-style flags (`-Xlinker -foo`). In order to pass `LDFLAGS` in, we
# have to turn them into a format that `swiftc` will understand.
#
# We can do this because we know we're compiling with Clang specifically.
export LDFLAGS="$(clang-ldflags)"
# Extend the 'gentoo' build preset with user-specified flags and flags for
# libc++ systems.
cp "${FILESDIR}/${PF}/gentoo.ini" "${SWIFT_BUILD_PRESETS_INI_PATH}"
local extra_build_flags=()
# Setting `-j<n>`/`--jobs=<n>` in MAKEOPTS needs to be manually exposed to
# the Swift build system.
if [[ -n "${MAKEOPTS}" ]]; then
local num_jobs make_opts=( $(getopt -qu -o 'j:' -l 'jobs:' -- ${MAKEOPTS}) )
while [[ "${#make_opts[@]}" -gt 1 ]]; do
case "${make_opts[0]}" in
-j | --jobs )
num_jobs="${make_opts[1]}"
make_opts=("${make_opts[@]:2}") ;;
-- ) break ;;
* ) make_opts=("${make_opts[@]:1}") ;;
esac
done
if [[ -n "${num_jobs}" ]]; then
extra_build_flags+=(--jobs="${num_jobs}")
fi
fi
if use libcxx; then
extra_build_flags+=(
--libcxx
--extra-cmake-options=-DCLANG_DEFAULT_CXX_STDLIB=libc++
)
elif [[ "${LLVM_SLOT}" -ge 22 ]]; then
# While `__COUNTER__` is being standardized, Clang 22 considers it a C2Y
# extension, and produces compilation errors by default. The semantics
# haven't changed, so these can be downgraded to warnings.
append-cxxflags '-Wno-error=c2y-extensions'
else
# Swift is going to be building against GCC's libstdc++ using Clang, and
# GCC 16 libstdc++ headers can only be parsed by Clang 22 and later.
# Swift's LLVM will automatically pick up on the latest headers on disk,
# so we need to point Clang to a specific GCC install dir if GCC 16 or
# later are installed.
#
# Adapted from `toolchain-func.eclass`'s `_gcc_install_dir`.
local gcc_install_dir="$(LC_ALL=C gcc -print-search-dirs 2>/dev/null \
| awk '$1=="install:" {print $2}')" \
|| die "Failed to get GCC install dir"
if [[ "$(basename "${gcc_install_dir}")" -ge 16 ]]; then
local base="$(dirname "${gcc_install_dir}")"
gcc_install_dir=""
while read -r -d '' dir; do
if [[ "$(basename "${dir}")" -lt 16 ]]; then
gcc_install_dir="${dir}"
break
fi
done < <(find "${base}" -mindepth 1 -maxdepth 1 -print0 | sort -rVz) \
|| die "Failed to find GCC install dirs"
fi
[[ -n "${gcc_install_dir}" ]] || die "Failed to find GCC <16 install dir"
append-cxxflags "--gcc-install-dir=${gcc_install_dir}"
fi
extra_build_flags+=(${SWIFT_EXTRA_BUILD_FLAGS})
local orig_preset="${SWIFT_BUILD_PRESET}"
local preset="${orig_preset}"
local n=1
{
for arg in "${extra_build_flags[@]}"; do
local next="${orig_preset},${n}"
printf '[preset: %s]\n' "${next}"
printf 'mixin-preset=%s\n' "${preset}"
echo "${arg#--}"
preset="${next}"
n="$((n + 1))"
done
} >> "${SWIFT_BUILD_PRESETS_INI_PATH}"
SWIFT_BUILD_PRESET="${preset}"
}
src_compile() {
# Building swift-driver writes to this directory for some reason, but the
# contents are irrelevant.
addpredict /var/lib/portage/home/.swiftpm
# Versions of Swift 6.0 and later require an existing Swift compiler to
# bootstrap from. We can use any version from 5.10.1 and on.
local swift_version="$(eselect swift show | tail -n1 | xargs)"
if [[ "${swift_version}" != swift-* ]]; then
# Swift may be unset; we can use the latest available.
swift_version="$(eselect swift show --latest | tail -n1 | xargs)"
fi
[[ "${swift_version}" == swift-* ]] || die "No Swift version found for bootstrapping."
local original_path="${PATH}"
export PATH="/usr/lib64/${swift_version}/usr/bin:${original_path}"
"${S}/swift/utils/build-script" \
--preset-file="${S}/swift/utils/build-presets.ini" \
--preset-file="${SWIFT_BUILD_PRESETS_INI_PATH}" \
--preset="${SWIFT_BUILD_PRESET}" \
install_destdir="${S}/${P}" \
installable_package="" \
|| die
export PATH="${original_path}"
}
src_install() {
# `libTesting` as built has its RPATH set to the absolute path to its
# containing dir, which is in the build sandbox. This directory won't exist
# after installation, and is the same as '$ORIGIN'.
patchelf --set-rpath '$ORIGIN' "${S}/${P}/usr/lib/swift/linux/libTesting.so" || die
# The Swift build output is intended to be self-contained, and is
# _significantly_ easier to leave as-is than attempt to splat onto the
# filesystem; we'll install the output versioned into `/usr/$(get_libdir)`
# and expose the relevant binaries via linking.
local dest_dir="/usr/$(get_libdir)/${P}"
mkdir -p "${ED}/${dest_dir}" \
&& cp -pPR "${S}/${P}/." "${ED}/${dest_dir}" \
|| die
# Swift ships with its own `clang`, `lldb`, etc.; we don't want these to be
# exposed externally, so we'll just symlink Swift-specific binaries into
# `/usr/bin`. (The majority of executables don't need to be exposed as
# `swift <command>` calls `swift-<command>` directly.)
local bin
for bin in swift swiftc sourcekit-lsp; do
# We only install versioned symlinks; non-versioned links are maanged
# via `eselect swift`.
dosym -r "${dest_dir}/usr/bin/${bin}" "/usr/bin/${bin}-${PV}"
done
}
pkg_preinst() {
# After installation, we ideally want the system to have the latest Swift
# version set -- but if the system already has a Swift version set and it
# isn't the latest version, that's likely an intentional decision that we
# don't want to override.
local current_swift_version="$(eselect swift show | tail -n1 | xargs)"
local latest_swift_version="$(eselect swift show --latest | tail -n1 | xargs)"
[[ "${current_swift_version}" == '(unset)' ]] \
|| [[ "${current_swift_version}" == "${latest_swift_version}" ]] \
&& PKG_PREINST_SWIFT_INTENTIONALLY_SET='false'
}
pkg_postinst() {
# If the system doesn't have Swift intentionally set to an older version, we
# can update to the latest.
if [[ "${PKG_PREINST_SWIFT_INTENTIONALLY_SET}" == 'false' ]]; then
eselect swift update
fi
# We also want to provide a stable directory which matches our SLOT to avoid
# revdep breakages, as patch updates use the same SLOT but otherwise move
# the install location on disk.
#
# See https://bugs.gentoo.org/957730
#
# We do this in `pkg_postinst` instead of calling `dosym` in `src_install`
# because when upgrading from a major version to a patch version, the major
# version is still on disk while the patch version is being installed, so
# the existing directory is in use and the symlink fails to install.
local major_ver="$(ver_cut 1-2)"
if [[ "${PV}" != "${major_ver}" ]]; then
local libdir="${EROOT}/usr/$(get_libdir)"
ln -fsT "${libdir}/${P}" "${libdir}/${PN}-${major_ver}" || die
fi
}
pkg_postrm() {
# We don't want to leave behind symlinks pointing to this Swift version on
# removal.
local current_swift_version="$(eselect swift show | tail -n1 | xargs)"
if [[ "${current_swift_version}" == "${P}" ]]; then
eselect swift update
fi
# If we installed a SLOT symlink, we also want to remove it here.
local major_ver="$(ver_cut 1-2)"
local link="${EROOT}/usr/$(get_libdir)/${PN}-${major_ver}"
if [[ -L "${link}" && "${PV}" != "${major_ver}" ]]; then
rm -f "${link}"
fi
}
|