Jakobeha
(Jakob Hain)
March 25, 2023, 4:10am
1
I may submit a proposal if the Swift community needs better Linux support. Or tooling in general that is not tied to Xcode/Apple.
I think Swift is an excellent language and serious contender, especially since it's like Kotlin/Java but actually has value types (or at least pretends to. I remember reading they're CoW / not actually value types under the hood). But last time I tried using it the lack of Linux and non-Xcode/AppCode support was a dealbreaker.
3 Likes
FWIW CoW is a manual optimization done for certain specific value types, not a characteristic of value types in Swift in general.
2 Likes
sspringer
(Stefan Springer)
March 25, 2023, 3:55pm
3
Swift runs fine on Linux overall , and the Foundation library is planned to be equal on all supported platforms . AppCode (and the Swift plugin for CLion) are deprecated, use the excellent Swift extension for Visual Studio Code as development environment (tip: set Editor › Inlay Hints: offUnlessPressed). So you might again give it try on Linux
1 Like
mickeyl
(Dr. Mickey Lauer)
March 25, 2023, 4:19pm
4
The interest is there, but is held back by the devastating state of swift-corelibs-foundation. The implementation gaps are widening and no one seems to be assigned to review pull requests and make it smaller. Instead a vague new Swift-native implementation of Foundation is being worked on that is missing crucial infrastructure.
If we can get enough people behind such an initiative, it might be worth it to fork swift-corelibs-foundation for a better experience on !APPLE platforms.
3 Likes
sspringer
(Stefan Springer)
March 25, 2023, 5:49pm
5
mickeyl:
Instead a vague new Swift-native implementation of Foundation is being worked on that is missing crucial infrastructure.
If we can get enough people behind such an initiative, it might be worth it to fork swift-corelibs-foundation for a better experience on !APPLE platforms.
I would rather put the energy into the proposed re-implementation which I think is a good idea and avoid any fork and in the meantime do early checks on Linux while developing.
1 Like
Foundation is a no-go on constrained server deployment targets, it is too large and uses too much memory. the framework should be broken up or replaced with smaller, more specialized packages.
Foundation does not harm consumer-grade macOS/iOS applications, because the library ships with the OS and can be shared between many applications. but Foundation unfortunately is a killer on platforms like linux where static linking is the standard.
i personally have sunk thousands of hours over many years into developing server-friendly, Foundation-free alternatives. but it gobbles up a lot of time and it is a very aggravating process, when you consider that users of other languages do not need to waste time reinventing everything from scratch.
5 Likes
sspringer
(Stefan Springer)
March 25, 2023, 9:20pm
7
That‘s the plan for the re-implementation according to the blog entry already mentioned .
…BTW what about the flto option of the LLVM linker , shouldn‘t this linker option remove parts that you do not need?
tera
March 26, 2023, 7:19am
8
Without disagreeing that it makes sense splitting a large monolithic framework into pieces,
If you replace "Foundation" with something else (like"large image processing library", etc) in this sentence what difference would it make? Couldn't dynamic linking be used on linux?
hassila
(Joakim Hassila)
March 26, 2023, 7:36am
9
Isn’t the answer more to improve dead/unused code stripping also, I’ve seen a few cases like e.g.
opened 08:44AM - 20 Oct 21 UTC
bug
| | |
|------------------|-----------------|…
|Previous ID | SR-15358 |
|Radar | rdar://problem/84458616 |
|Original Reporter | @fabianfett |
|Type | Bug |
<details>
<summary>Environment</summary>
macOS environment
``` bash
$> swift --version
swift-driver version: 1.26.17 Apple Swift version 5.5.1 (swiftlang-1300.0.39.3 clang-1300.0.29.21)
Target: x86_64-apple-macosx12.0
```
linux environment
``` bash
root@ec5ed00cab8b:/src# swift --version
Swift version 5.6-dev (LLVM 7aef0efea99e2c6, Swift e4f71c8e118fc09)
Target: x86_64-unknown-linux-gnu
```
</details>
<details>
<summary>Additional Detail from JIRA</summary>
| | |
|------------------|-----------------|
|Votes | 1 |
|Component/s | |
|Labels | Bug |
|Assignee | None |
|Priority | Medium |
md5: fb0b4346cb60710bf9f4b087c40051ca
</details>
**Issue Description:**
Considering a very simple Swift program:
``` swift
// swift-tools-version:5.5
import PackageDescription
let package = Package(
name: "FatRepro",
dependencies: [
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.0.0"),
],
targets: [
.executableTarget(
name: "FatRepro",
dependencies: [
.product(name: "ArgumentParser", package: "swift-argument-parser")
],
path: "."
),
]
)
```
With a very simple `main.swift`:
``` swift
print("Hello, world!")
```
Compiling the code to a binary in release mode creates an executable that is **1.7MB** in size on Darwin. If we don't add `ArgumentParser` to the target's dependencies in the Package.swift the resulting executable is only **78KB** on Darwin.
Given that we don't even `import ArgumentParser` anywhere in the code I would expect that Swift is smart enough not to emit ArgumentParser symbols into the resulting binary, even when it is part of the target's dependencies.
On Linux (nightly-main-focal from October 18, 2021) the size difference is even larger:
**2.9MB vs 17KB**.
Stripping the 2.9MB executable on Linux reduces the size down to 811KB, which is an improvement. However this is still 47x larger than what could be possible.
opened 06:33AM - 24 May 20 UTC
bug
| | |
|------------------|-----------------|…
|Previous ID | SR-12872 |
|Radar | None |
|Original Reporter | Walter (JIRA User) |
|Type | Bug |
<details>
<summary>Additional Detail from JIRA</summary>
| | |
|------------------|-----------------|
|Votes | 0 |
|Component/s | |
|Labels | Bug |
|Assignee | None |
|Priority | Medium |
md5: 61a887ce47e57d13e3f175b10c7eb55b
</details>
**Issue Description:**
Symbols declared with public visibility are never dead stripped by the linker, even when linking an executable where there is no expectation that the result would be linked into anything else (build setting "Exported symbols files" refrence to an empty file and thus unused symbols could be safely discarded).
Stripping these symbols is important when building an executable that links to a large library that it only uses a portion of, to prevent code bloat.
STEPS TO REPRODUCE
``` java
public class Foo {
func foo1() {
print("1111")
}
}
```
we can write the code above in an empty project and build with linkmap generated, and we will still find symbol "Foo" in the linkmap even though we never call "Foo"
opened 07:52PM - 19 Apr 21 UTC
bug
compiler
| | |
|------------------|-----------------|…
|Previous ID | SR-14509 |
|Radar | None |
|Original Reporter | mren (JIRA User) |
|Type | Bug |
<details>
<summary>Additional Detail from JIRA</summary>
| | |
|------------------|-----------------|
|Votes | 0 |
|Component/s | Compiler |
|Labels | Bug |
|Assignee | None |
|Priority | Medium |
md5: 9a43f214c5ecb7b52410c36f2eb50cd1
</details>
**Issue Description:**
Some high level information about emit-dead-strippable:
Kuba is working on stripping Swift symbols if they are not used statically via a LTO pass GlobalDCE, which is guarded by emit-dead-strippable flag. This optimization has a great potential to reduce binary size. While testing this with an iOS app, we are hitting a few runtime crashes.
The goal is to figure out cases of dynamic references to Swift symbols without a static reference, because that will break GlobalDCE in the sense it will incorrectly strip off symbols that are needed at runtime. objc_classes and objc_categories are such Swift symbols that we may need to selectively keep. Protocol conformances are another case, where instantiateConcreteTypeFromMangledName seems to need some conformance data at runtime where there are no static references to them and they are stripped off by GlobalDCE. Another potential case for runtime protocol conformance check is \`as? Protocol\` casts.
We had some email exchanges about this, a quick summary of the issues and potential fixes:
1\> Dynamic lookup of Swift classes via ObjC interop
Potential solution: symbolic encoding for ObjC classes as suggested by Joe: Currently we always refer to ObjC classes in mangled names by their runtime name, but we could introduce an escape code to embed a relative reference to the classref, which should be a small performance win for instantiation and also help the linker statically understand the dependency on the classref.
2\> Dynamic lookup of Swift symbols in objc_categories
Potential solution: keep them for now
3\> Dynamic lookup of protocol conformances
Joe has been working on an encoding for protocol conformances. Joe suggested a shorter-term hack that could unblock dead-stripping in the near-term: what if we emit the mangled strings, but then after the \`\0\` terminator, we can append relative references to all of the runtime entities that the mangled name needs but doesn't directly reference, like ObjC classrefs and protocol conformances? That way we don't need to implement type decoder support for new manglings, and for a nominal cost of 4 const bytes per reference, we prevent the linker from dead-stripping.
We have a standalone test case that seems to cause runtime issue when checking conformance at runtime. The test case is currently on a private branch, specifically this commit: https://github.com/apple/swift/commit/13375542ea8d0206498a4368919e8bf834fdaa5b
Thanks,
Manman
opened 11:01AM - 12 May 16 UTC
bug
Linux
compiler
| | |
|------------------|-----------------|…
|Previous ID | SR-1495 |
|Radar | None |
|Original Reporter | @drewcrawford |
|Type | Bug |
<details>
<summary>Environment</summary>
swift-DEVELOPMENT-SNAPSHOT-2016-05-09-a
Linux x64
</details>
<details>
<summary>Additional Detail from JIRA</summary>
| | |
|------------------|-----------------|
|Votes | 0 |
|Component/s | Compiler |
|Labels | Bug, Linux |
|Assignee | None |
|Priority | Medium |
md5: 266a4de7d827887d8a431b075afc052f
</details>
**Issue Description:**
On OSX, we have the `-dead_strip` linker option to remove dead code.
On Linux, the usual procedure is linker options `--gc-sections`, however, this removes many sections that should not be removed. You can see an example with `--print-gc-sections` which outputs, for my program:
``` java
/usr/bin/ld: Removing unused section '.data' in file '/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/crtbegin.o'
/usr/bin/ld: Removing unused section '.swift2_protocol_conformances' in file '.atllbuild/objects/main.swift.o'
/usr/bin/ld: Removing unused section '.swift3_typeref' in file '/usr/local/lib/swift_static/linux/libswiftCore.a(Swift.o)'
/usr/bin/ld: Removing unused section '.swift3_fieldmd' in file '/usr/local/lib/swift_static/linux/libswiftCore.a(Swift.o)'
/usr/bin/ld: Removing unused section '.swift3_assocty' in file '/usr/local/lib/swift_static/linux/libswiftCore.a(Swift.o)'
/usr/bin/ld: Removing unused section '.swift2_protocol_conformances' in file '/usr/local/lib/swift_static/linux/libswiftCore.a(Swift.o)'
/usr/bin/ld: Removing unused section '.swift2_type_metadata' in file '/usr/local/lib/swift_static/linux/libswiftCore.a(Swift.o)'
/usr/bin/ld: Removing unused section '.swift3_builtin' in file '/usr/local/lib/swift_static/linux/libswiftCore.a(Swift.o)'
/usr/bin/ld: Removing unused section '.swift_modhash' in file '/usr/local/lib/swift_static/linux/libswiftCore.a(Swift.o)'
/usr/bin/ld: Removing unused section '.text._ZN5swift15nameForMetadataEPKNS_14TargetMetadataINS_9InProcessEEEb' in file '/usr/local/lib/swift_static/linux/libswiftCore.a(Casting.cpp.o)'
/usr/bin/ld: Removing unused section '.text.swift_dynamicCastUnknownClass' in file '/usr/local/lib/swift_static/linux/libswiftCore.a(Casting.cpp.o)'
/usr/bin/ld: Removing unused section '.text._ZNR5swift8Demangle16DemanglerPrinterlsEy' in file '/usr/local/lib/swift_static/linux/libswiftCore.a(Demangle.cpp.o)'
/usr/bin/ld: Removing unused section '.text._ZNR5swift8Demangle16DemanglerPrinterlsEx' in file '/usr/local/lib/swift_static/linux/libswiftCore.a(Demangle.cpp.o)'
/usr/bin/ld: Removing unused section '.rodata.cst16' in file '/usr/local/lib/swift_static/linux/libswiftCore.a(Demangle.cpp.o)'
/usr/bin/ld: Removing unused section '.text._ZN5swift8Punycode14encodePunycodeERKSt6vectorIjSaIjEERSs' in file '/usr/local/lib/swift_static/linux/libswiftCore.a(Demangle.cpp.o)'
/usr/bin/ld: Removing unused section '.rodata..L.str1' in file '/usr/local/lib/swift_static/linux/libswiftCore.a(Demangle.cpp.o)'
/usr/bin/ld: Removing unused section '.rodata..L.str230' in file '/usr/local/lib/swift_static/linux/libswiftCore.a(Demangle.cpp.o)'
...
```
In other words, it looks like it's stripping practically the entire program, including things that are obviously wrong, like protocol conformances and the whole standard library.
I'm not totally sure why these are being removed or why the behavior is different on one platform than another. I guess swift is not emitting the usage in a format that GCC ld understands.
Then it should matter less how the code is structured when linking statically.
2 Likes
mickeyl
(Dr. Mickey Lauer)
March 26, 2023, 9:07am
10
That‘s all good for those folks who want to use it in, say, 2025 or later, it doesn‘t help the developers who are actually struggling since years against swift-corelibs-foundation until this very point of time.
1 Like
Jakobeha
(Jakob Hain)
March 27, 2023, 12:48am
11
Does anyone know when will the new foundation be released to the public? And is there anywhere on the forum where this is discussed?
sspringer
(Stefan Springer)
March 27, 2023, 5:07am
12
See this forums topic by @Tony_Parker . I guess the community will be involved before it will be finished.
Update: No planned release date mentioned.