Swift on Linux: Make Very First Step Work

Swift on Linux: Make very first step work

I had the exact same problem. It turns out that I had added the ppa:ubuntu-toolchain-r/test repo in order to install g++-4.9 on my Mint distro (17.2). Once I purged the repository and restored various libraries to their original versions, swift finally worked for me.

Specifically, I had to run

sudo apt-get install ppa-purge
sudo ppa-purge -d trusty ppa:ubuntu-toolchain-r/test

While cleaning up, ppa-purge was complaining that in order to resolve conflicts, it would have to remove quite a few packages it could not find in the Ubuntu Trusty repo (including really core ones like build-essential, xorg, gcc, x11-xserver-utils...), so I made a note and reinstalled these right away after the purge. Just be very careful.

I think some of the libraries overridden when installing g++ 4.9 were creating a conflict. I've verified all this on a fresh Mint install too.

Use a C library in Swift on Linux

Use a System Module to import the OpenGL header file:
https://github.com/apple/swift-package-manager/blob/master/Documentation/SystemModules.md

Assuming you have a directory layout like:

COpenGL/
Package.swift
module.modulemap
.git/

YourApp/
Package.swift
main.swift
.git/

the COpenGL/module.modulemap file will look something like:

module COpenGL [system] {
header "/usr/include/gl/gl.h"
link "gl"
export *
}

This has to be created in a separate git repo, with a version tag:

touch Package.swift
git init
git add .
git commit -m "Initial Commit"
git tag 1.0.0

Then declare it as a dependency in YourApp/Package.swift file

import PackageDescription

let package = Package(
dependencies: [
.Package(url: "../COpenGL", majorVersion: 1)
]
)

Then in your main.swift file you can import it:

import COpenGL
// use opengl calls here...

Non-persistent' S4TF installation

This might be due to issue SR-8690, which impacts Swift in general on Ubuntu. Removing libc6-dbg (sudo apt remove libc6-dbg) clears the error.

Does Swift compile to native code?

Yes, it compiles to machine language by way of LLVM Bitcode and, as @connor said, runs on top of the Objective-C runtime.

Swift Casting doesn't work as Expected

it is not Swift (language) specific, it is Apple specific ...
Sample Image
Sample Image

even worst if you change data to

let d = ["first":"john", "last":"doe", "test int": 0, "test null": NSNull()] as [String:Any]

linux version works as expected,

["test null": <NSNull: 0x0000000000825560>, "last": "doe", "first": "john", "test int": 0]
["test null": <NSNull: 0x0000000000825560>, "last": "doe", "first": "john", "test int": 0]
["test int": 0, "last": "doe", "first": "john", "test null": <NSNull: 0x0000000000825560>]

but apple prints

[:]
[:]
{
first = john;
last = doe;
"test int" = 0;
"test null" = "<null>";
}

it looks very strange. next code snippet explain why

import Foundation

public protocol P {}

extension String:P {}
extension Int:P {}
extension NSNull:P {}

let d = ["first":"john", "last":"doe", "test null": NSNull(), "test int": 10] as [String:Any]
print("A)",d, type(of: d))

let d1 = d as? [String:P] ?? [:]
print("B)",d1, type(of: d1))
print()

if let data = try? JSONSerialization.data(withJSONObject: d, options: []) {

if let jobject = try? JSONSerialization.jsonObject(with: data, options: []) {

let o = jobject as? [String:Any] ?? [:]
print("1)",o, type(of: o))

var o2 = o as? [String:P] ?? [:]
print("2)",o2, type(of: o2), "is it empty?: \(o2.isEmpty)")
print()

if o2.isEmpty {
o.forEach({ (t) in
let v = t.value as? P
print("-",t.value, type(of: t.value),"as? P", v as Any)
o2[t.key] = t.value as? P ?? 0
})
}
print()
print("3)",o2)
}
}

on apple it prints

A) ["test null": <null>, "test int": 10, "first": "john", "last": "doe"] Dictionary<String, Any>
B) ["test null": <null>, "test int": 10, "first": "john", "last": "doe"] Dictionary<String, P>

1) ["test null": <null>, "test int": 10, "first": john, "last": doe] Dictionary<String, Any>
2) [:] Dictionary<String, P> is it empty?: true

- <null> NSNull as? P Optional(<null>)
- 10 __NSCFNumber as? P nil
- john NSTaggedPointerString as? P nil
- doe NSTaggedPointerString as? P nil

3) ["test null": <null>, "test int": 0, "first": 0, "last": 0]

while on linux it prints

A) ["test int": 10, "last": "doe", "first": "john", "test null": <NSNull: 0x00000000019d8c40>] Dictionary<String, Any>
B) ["test int": 10, "last": "doe", "first": "john", "test null": <NSNull: 0x00000000019d8c40>] Dictionary<String, P>

1) ["test int": 10, "last": "doe", "first": "john", "test null": <NSNull: 0x00000000019ec550>] Dictionary<String, Any>
2) ["test int": 10, "last": "doe", "first": "john", "test null": <NSNull: 0x00000000019ec550>] Dictionary<String, P> is it empty?: false

3) ["test int": 10, "last": "doe", "first": "john", "test null": <NSNull: 0x00000000019ec550>]

finally, I used the slightly modified source code of JSONSerialization from open source distribution (to avoid conflict with apple Foundation I rename the class to _JSONSerialization :-) and change the code such a way it works in my Playground without any warnings and errors and ...
it prints the expected results :)
Sample Image

Why it works now? The key is

/* A class for converting JSON to Foundation/Swift objects and converting Foundation/Swift objects to JSON.    An object that may be converted to JSON must have the following properties:
- Top level object is a `Swift.Array` or `Swift.Dictionary`
- All objects are `Swift.String`, `Foundation.NSNumber`, `Swift.Array`, `Swift.Dictionary`, or `Foundation.NSNull`
- All dictionary keys are `Swift.String`s
- `NSNumber`s are not NaN or infinity */

Now the conditional downcasting of all possible values to P works as expected

to be honest, try this snippet on linux :-) and on apple.

let d3 = [1.0, 1.0E+20]
if let data = try? JSONSerialization.data(withJSONObject: d3, options: []) {
if let jobject = try? JSONSerialization.jsonObject(with: data, options: []) as? [Double] ?? [] {
print(jobject)
}
}

apple prints

[1.0, 1e+20]

while linux

[]

and with really big value will crash. this bug goes from (in the open sourced JSONSerialization)

if doubleResult == doubleResult.rounded() {
return (Int(doubleResult), doubleDistance)
}

replace it with

if doubleResult == doubleResult.rounded() {
if doubleResult < Double(Int.max) && doubleResult > Double(Int.min) {
return (Int(doubleResult), doubleDistance)
}
}

and 'deserialization' works as expected (serialization has other bugs ...)

error Failed to build iOS project. We ran xcodebuild command but it exited with error code 65

If you don't have cocoa pods installed you need to sudo gem install cocoapods

  1. run cd ios
  2. run pod install
  3. cd ..
  4. delete build folder
  5. run react-native run-ios

if the error persists,

  1. delete build folder again
  2. open the /ios folder in x-code
  3. navigate File -> Project Settings -> Build System -> change (Shared workspace settings and Per-User workspace settings): Build System -> Legacy Build System`

You should be good to go.

Swift how to iterate float

This is the (exact) equivalent of your C-loop using stride

Swift 2

for index in 0.0.stride(to: 99.5, by: 0.5) {
print(index)
}

Swift 3+

for index in stride(from:0.0, through: 99.5, by: 0.5) {
print(index)
}


Related Topics



Leave a reply



Submit