Skip to content

Commit 2bdd14f

Browse files
committed
fix build with 64-bit time_t/off_t on 32-bit platforms
It is possible to build with 64-bit timestamps and file offsets on 32-bit platforms such as armv7 (e.g. for avoiding Y2038), and indeed this is the default for Yocto. This is (presently) broken in upstream Swift, so workaround until we can get PRs merged upstream.
1 parent f25ce41 commit 2bdd14f

7 files changed

+159
-0
lines changed

recipes-devtools/swift/swift-foundation-essentials.bb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ SRC_URI = "git://github.com/swiftlang/swift-foundation.git;protocol=https;name=f
1313
SRC_URI += "git://github.com/swiftlang/swift-foundation-icu.git;protocol=https;name=icu;tag=swift-${SWIFT_VERSION}-RELEASE;nobranch=1;destsuffix=swift-foundation-icu;"
1414
SRC_URI += "git://github.com/swiftlang/swift-syntax.git;protocol=https;name=syntax;tag=swift-${SWIFT_VERSION}-RELEASE;nobranch=1;destsuffix=swift-foundation-icu;"
1515
SRC_URI += "git://github.com/apple/swift-collections.git;protocol=https;nobranch=1;name=collections;tag=1.1.4;destsuffix=swift-collections;"
16+
SRC_URI += "file://0001-build-with-64-bit-fsblkcnt_t-on-32-bit-glibc-platfor.patch;striplevel=1;"
17+
SRC_URI += "file://0002-build-with-64-bit-time_t-on-32-bit-platforms.patch;striplevel=1;"
1618

1719
S = "${WORKDIR}/git"
1820

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
From 3eb8a04f9597ed71ddd3eb54db77a9d5e37f032d Mon Sep 17 00:00:00 2001
2+
From: Luke Howard <[email protected]>
3+
Date: Sat, 28 Jun 2025 11:58:13 +1000
4+
Subject: [PATCH 1/2] build with 64-bit fsblkcnt_t on 32-bit glibc platforms
5+
6+
It is possible to build with 64-bit file offsets on 32-bit platforms such as
7+
armv7, and indeed this is the default for some build environments such as
8+
Yocto. Use fsblkcnt_t, which is an alias to a type of the correct width, when
9+
computing blockSize.
10+
---
11+
.../FoundationEssentials/FileManager/FileManager+Files.swift | 4 ++++
12+
1 file changed, 4 insertions(+)
13+
14+
diff --git a/Sources/FoundationEssentials/FileManager/FileManager+Files.swift b/Sources/FoundationEssentials/FileManager/FileManager+Files.swift
15+
index 64f8e21..824c3ac 100644
16+
--- a/Sources/FoundationEssentials/FileManager/FileManager+Files.swift
17+
+++ b/Sources/FoundationEssentials/FileManager/FileManager+Files.swift
18+
@@ -727,8 +727,12 @@ extension _FileManagerImpl {
19+
let blockSize = UInt64(result.f_bsize)
20+
#else
21+
let fsNumber = result.f_fsid
22+
+ #if canImport(Glibc)
23+
+ let blockSize = fsblkcnt_t(result.f_frsize) // support 64-bit block sizes on 32-bit platforms
24+
+ #else
25+
let blockSize = UInt(result.f_frsize)
26+
#endif
27+
+ #endif
28+
var totalSizeBytes = result.f_blocks * blockSize
29+
var availSizeBytes = result.f_bavail * blockSize
30+
var totalFiles = result.f_files
31+
--
32+
2.43.0
33+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
From ad2b4b35979caf1d66d77933dda66012f7108294 Mon Sep 17 00:00:00 2001
2+
From: Luke Howard <[email protected]>
3+
Date: Sat, 28 Jun 2025 11:59:30 +1000
4+
Subject: [PATCH 2/2] build with 64-bit time_t on 32-bit platforms
5+
6+
It is good practice to build with 64-bit time_t/timeval on 32-bit platforms to
7+
avoid the Y2038 issue. This is the default when building on Yocto for armv7,
8+
for example. Unfortunately suseconds_t is not an alias to a type of the correct
9+
width (unlike time_t), so for Glibc make it a private alias of time_t to fix
10+
the build.
11+
---
12+
.../FileManager/FileManager+Files.swift | 6 ++++++
13+
1 file changed, 6 insertions(+)
14+
15+
diff --git a/Sources/FoundationEssentials/FileManager/FileManager+Files.swift b/Sources/FoundationEssentials/FileManager/FileManager+Files.swift
16+
index 824c3ac..c7ea78c 100644
17+
--- a/Sources/FoundationEssentials/FileManager/FileManager+Files.swift
18+
+++ b/Sources/FoundationEssentials/FileManager/FileManager+Files.swift
19+
@@ -951,6 +951,12 @@ extension _FileManagerImpl {
20+
#endif
21+
}
22+
23+
+ #if canImport(Glibc)
24+
+ // support for 64-bit timestamps on 32-bit platforms; unfortunately
25+
+ // suseconds_t is not an alias of the appropriate type, but time_t is
26+
+ typealias suseconds_t = time_t
27+
+ #endif
28+
+
29+
if let date = attributes[.modificationDate] as? Date {
30+
let (isecs, fsecs) = modf(date.timeIntervalSince1970)
31+
if let tv_sec = time_t(exactly: isecs),
32+
--
33+
2.43.0
34+

recipes-devtools/swift/swift-foundation.bb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ SRC_URI += "git://github.com/swiftlang/swift-foundation.git;protocol=https;name=
1414
SRC_URI += "git://github.com/swiftlang/swift-foundation-icu.git;protocol=https;name=icu;tag=swift-${SWIFT_VERSION}-RELEASE;nobranch=1;destsuffix=swift-foundation-icu;"
1515
SRC_URI += "git://github.com/swiftlang/swift-syntax.git;protocol=https;name=syntax;tag=swift-${SWIFT_VERSION}-RELEASE;nobranch=1;destsuffix=swift-syntax;"
1616
SRC_URI += "file://0001-CFRunLoopTimerGetTolerance-CFRunLoopTimerSetToleranc.patch;striplevel=1;"
17+
SRC_URI += "file://0002-build-with-64-bit-time_t-on-32-bit-platforms.patch;striplevel=1;"
1718

1819
S = "${WORKDIR}/git"
1920

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
From 214f7205f8a4065c6b4b5ac3471167bd1edc475f Mon Sep 17 00:00:00 2001
2+
From: Luke Howard <[email protected]>
3+
Date: Sat, 28 Jun 2025 12:04:30 +1000
4+
Subject: [PATCH] build with 64-bit time_t on 32-bit platforms
5+
6+
It is good practice to build with 64-bit time_t/timeval on 32-bit platforms to
7+
avoid the Y2038 issue. This is the default when building on Yocto for armv7,
8+
for example. Unfortunately suseconds_t is not an alias to a type of the correct
9+
width (unlike time_t), so for Glibc make it a private alias of time_t to fix
10+
the build.
11+
---
12+
Sources/Foundation/NSDate.swift | 6 ++++++
13+
1 file changed, 6 insertions(+)
14+
15+
diff --git a/Sources/Foundation/NSDate.swift b/Sources/Foundation/NSDate.swift
16+
index ac7bd1bc..77579282 100644
17+
--- a/Sources/Foundation/NSDate.swift
18+
+++ b/Sources/Foundation/NSDate.swift
19+
@@ -30,6 +30,12 @@ extension TimeInterval {
20+
#else
21+
extension timeval {
22+
internal init(_timeIntervalSince1970: TimeInterval) {
23+
+ #if canImport(Glibc)
24+
+ // support for 64-bit timestamps on 32-bit platforms; unfortunately
25+
+ // suseconds_t is not an alias of the appropriate type, but time_t is
26+
+ typealias suseconds_t = time_t
27+
+ #endif
28+
+
29+
let (integral, fractional) = modf(_timeIntervalSince1970)
30+
self.init(tv_sec: time_t(integral), tv_usec: suseconds_t(1.0e6 * fractional))
31+
}
32+
--
33+
2.43.0
34+

recipes-devtools/swift/swift-stdlib.bb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ SRC_URI = "\
1818
git://github.com/swiftlang/swift-experimental-string-processing.git;protocol=https;name=stringproc;tag=swift-${SWIFT_VERSION}-RELEASE;nobranch=1;destsuffix=swift-experimental-string-processing; \
1919
git://github.com/swiftlang/swift-syntax.git;protocol=https;name=syntax;tag=swift-${SWIFT_VERSION}-RELEASE;nobranch=1;destsuffix=swift-syntax; \
2020
file://0001-add-arm-to-float16support-for-armv7.patch;striplevel=1; \
21+
file://0002-build-with-64-bit-time_t-on-32-bit-platforms.patch;striplevel=1; \
2122
"
2223

2324
S = "${WORKDIR}/swift"
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
From 06073712f137bd1db7f0b94f4526b00be81ec3fb Mon Sep 17 00:00:00 2001
2+
From: Luke Howard <[email protected]>
3+
Date: Sat, 28 Jun 2025 15:01:30 +1000
4+
Subject: [PATCH] build with 64-bit time_t on 32-bit platforms
5+
6+
It is good practice to build with 64-bit time_t/timeval on 32-bit platforms to
7+
avoid the Y2038 issue. This is the default when building on Yocto for armv7,
8+
for example. Unfortunately suseconds_t is not an alias to a type of the correct
9+
width (unlike time_t).
10+
---
11+
stdlib/public/Platform/Platform.swift | 18 +++++++++++-------
12+
1 file changed, 11 insertions(+), 7 deletions(-)
13+
14+
diff --git a/stdlib/public/Platform/Platform.swift b/stdlib/public/Platform/Platform.swift
15+
index 0c2d63a0cff..4949fc66456 100644
16+
--- a/stdlib/public/Platform/Platform.swift
17+
+++ b/stdlib/public/Platform/Platform.swift
18+
@@ -439,7 +439,7 @@ extension timespec {
19+
@available(SwiftStdlib 5.7, *)
20+
public init(_ duration: Duration) {
21+
let comps = duration.components
22+
- self.init(tv_sec: Int(comps.seconds),
23+
+ self.init(tv_sec: time_t(comps.seconds),
24+
tv_nsec: Int(comps.attoseconds / 1_000_000_000))
25+
}
26+
}
27+
@@ -458,14 +458,18 @@ extension timeval {
28+
public init(_ duration: Duration) {
29+
let comps = duration.components
30+
#if os(Linux)
31+
- // Linux platforms define timeval as Int/Int
32+
- self.init(tv_sec: Int(comps.seconds),
33+
- tv_usec: Int(comps.attoseconds / 1_000_000_000_000))
34+
+ // Linux platforms define timeval as Int/Int, except on 32-bit platforms
35+
+ // where _TIME_BITS=64 is defined. Abuse time_t as an alias for the correct
36+
+ // suseconds_t type, as it is not an alias to the 64-bit type on 32-bit
37+
+ // platforms.
38+
+ typealias _Seconds = time_t
39+
+ typealias _Microseconds = time_t
40+
#else
41+
- // Darwin platforms define timeval as Int/Int32
42+
- self.init(tv_sec: Int(comps.seconds),
43+
- tv_usec: Int32(comps.attoseconds / 1_000_000_000_000))
44+
+ typealias _Seconds = Int
45+
+ typealias _Microseconds = Int32
46+
#endif
47+
+ self.init(tv_sec: _Seconds(comps.seconds),
48+
+ tv_usec: _Microseconds(comps.attoseconds / 1_000_000_000_000))
49+
}
50+
}
51+
52+
--
53+
2.39.5 (Apple Git-154)
54+

0 commit comments

Comments
 (0)