swift-argument-parser
swift-argument-parser copied to clipboard
Use FoundationEssentials if it's available
Use FoundationEssentials if it's available. This stops all of Foundation being linked when not needed and reduces binary sizes
Checklist
- [x] I've added at least one test that validates that my change is working, if appropriate
- [x] I've followed the code style of the rest of the project
- [x] I've read the Contribution Guidelines
- [x] I've updated the documentation if necessary
@swift-ci test
@swift-ci test
This feature will also be very useful to me. After applying the patch locally I still see libFoundationInternationalization.so being pulled in, though:
lukeh@liebling:~/CVSRoot/apple/swift-argument-parser$ ldd .build/debug/color
linux-vdso.so.1 (0x0000fe8b15062000)
libFoundationInternationalization.so => /opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/linux/libFoundationInternationalization.so (0x0000fe8b14800000)
libFoundationEssentials.so => /opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/linux/libFoundationEssentials.so (0x0000fe8b14200000)
libswiftSwiftOnoneSupport.so => /opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/linux/libswiftSwiftOnoneSupport.so (0x0000fe8b14fd0000)
libswiftCore.so => /opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/linux/libswiftCore.so (0x0000fe8b13a00000)
libswift_Concurrency.so => /opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/linux/libswift_Concurrency.so (0x0000fe8b14f20000)
libswift_StringProcessing.so => /opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/linux/libswift_StringProcessing.so (0x0000fe8b14b10000)
libswift_RegexParser.so => /opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/linux/libswift_RegexParser.so (0x0000fe8b140e0000)
libswiftGlibc.so => /opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/linux/libswiftGlibc.so (0x0000fe8b14ef0000)
libBlocksRuntime.so => /opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/linux/libBlocksRuntime.so (0x0000fe8b14ec0000)
libdispatch.so => /opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/linux/libdispatch.so (0x0000fe8b14a90000)
libswiftDispatch.so => /opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/linux/libswiftDispatch.so (0x0000fe8b14e70000)
libFoundation.so => /opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/linux/libFoundation.so (0x0000fe8b13200000)
libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000fe8b13950000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000fe8b13040000)
/lib/ld-linux-aarch64.so.1 (0x0000fe8b15025000)
lib_FoundationICU.so => /opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/linux/lib_FoundationICU.so (0x0000fe8b10a00000)
libgcc_s.so.1 => /lib/aarch64-linux-gnu/libgcc_s.so.1 (0x0000fe8b14a40000)
libswiftSynchronization.so => /opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/linux/libswiftSynchronization.so (0x0000fe8b14a10000)
libstdc++.so.6 => /lib/aarch64-linux-gnu/libstdc++.so.6 (0x0000fe8b10600000)
This is my last Foundation dependency for a particular daemon which will shrink the stripped/release/static stdlib size from 62MB to 14MB.
After applying the patch:
lukeh@liebling:~/CVSRoot/apple/swift-argument-parser/.build/debug/ArgumentParser.build$ nm *.o|grep Foundation|grep -v FoundationEssentials|sort|uniq|grep "U "|awk '{print $2}'|xargs swift-demangle
$s10Foundation7NSErrorCMa ---> type metadata accessor for Foundation.NSError
$ss5ErrorP10FoundationE20localizedDescriptionSSvg ---> (extension in Foundation):Swift.Error.localizedDescription.getter : Swift.String
$sSy10FoundationE20replacingOccurrences2of4with7options5rangeSSqd___qd_0_SS0A10EssentialsE14CompareOptionsVSnySS5IndexVGSgtSyRd__SyRd_0_r0_lF ---> (extension in Foundation):Swift.StringProtocol.replacingOccurrences<A, B where A1: Swift.StringProtocol, B1: Swift.StringProtocol>(of: A1, with: B1, options: (extension in FoundationEssentials):Swift.String.CompareOptions, range: Swift.Range<Swift.String.Index>?) -> Swift.String
$sSy10FoundationE5range2of7optionsAB6localeSnySS5IndexVGSgqd___SS0A10EssentialsE14CompareOptionsVAiJ6LocaleVSgtSyRd__lF ---> (extension in Foundation):Swift.StringProtocol.range<A where A1: Swift.StringProtocol>(of: A1, options: (extension in FoundationEssentials):Swift.String.CompareOptions, range: Swift.Range<Swift.String.Index>?, locale: FoundationEssentials.Locale?) -> Swift.Range<Swift.String.Index>?
$sSy10FoundationE8containsySbqd__SyRd__lF ---> (extension in Foundation):Swift.StringProtocol.contains<A where A1: Swift.StringProtocol>(A1) -> Swift.Bool
It turns out we need to enable Swift 6 language mode for the #if swift(>=6.0) guards to work. If we remove those:
/home/lukeh/CVSRoot/apple/swift-argument-parser/Sources/ArgumentParser/Usage/MessageInfo.swift: 0:
/home/lukeh/CVSRoot/apple/swift-argument-parser/Sources/ArgumentParser/Usage/MessageInfo.swift:14:23: error: class 'NSError' does not exist in module 'FoundationEssentials'
12 | #if canImport(FoundationEssentials)
13 | internal import protocol FoundationEssentials.LocalizedError
14 | internal import class FoundationEssentials.NSError
| `- error: class 'NSError' does not exist in module 'FoundationEssentials'
What we could do is only use LocalisedError and localizedDescription on Darwin.
That still leaves replacingOccurrences(of:with:), range(of:) and contains(). I suppose these shouldn't be difficult to reimplement.
@swift-ci Please test
This still isn't working for me on Linux.
lukeh@liebling:~/CVSRoot/apple/swift-argument-parser$ swift --version
Swift version 6.0.2 (swift-6.0.2-RELEASE)
Target: aarch64-unknown-linux-gnu
lukeh@liebling:~/CVSRoot/apple/swift-argument-parser$ ldd .build/debug/color|grep libFoundation
libFoundationInternationalization.so => /opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/linux/libFoundationInternationalization.so (0x0000f81b2a400000)
libFoundationEssentials.so => /opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/linux/libFoundationEssentials.so (0x0000f81b29e00000)
libFoundation.so => /opt/swift-6.0.2-RELEASE-ubuntu24.04-aarch64/usr/lib/swift/linux/libFoundation.so (0x0000f81b28e00000)
The issue is the one I described before:
lukeh@liebling:~/CVSRoot/apple/swift-argument-parser/.build/debug$ nm color|grep ' U $sSy10Foundation'
U $sSy10FoundationE20replacingOccurrences2of4with7options5rangeSSqd___qd_0_SS0A10EssentialsE14CompareOptionsVSnySS5IndexVGSgtSyRd__SyRd_0_r0_lF
U $sSy10FoundationE5range2of7optionsAB6localeSnySS5IndexVGSgqd___SS0A10EssentialsE14CompareOptionsVAiJ6LocaleVSgtSyRd__lF
U $sSy10FoundationE8containsySbqd__SyRd__lF
superseded by: #804