Swift под Linux

Вопросы написания собственного программного кода (на любых языках)

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21336
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Swift под Linux

Непрочитанное сообщение Olej » 09 фев 2018, 16:56

Olej писал(а): 1-я интересующая меня задача:
Следующая интересующая меня задача:
- определение координат 2D точек, составных [X,Y] из 2-х Double значений
- ввод покоординатно таких чисел с терминала
- с контролем ошибок ввода: <2 или >2 чисел введено, не числовое значение, отработку конца ввода EOF=^D и т.д.
- с тем, чтобы обработку ошибок сделать через переопределённый протокол Error (собственных ошибок) и выбрасывание исключений try-catch, раз такое есть в языке

Код: Выделить всё

class point {   // класс 2D точки 
   var x, y : Double?
   init( x : Double, y : Double ) {
      self.x = x
      self.y = y
   }
}

enum InputError: Error {
    case noDigit( s : Substring )
    case emptyString
    case lessDigits
    case moreDigits
}

func input() throws -> point? {
   print( "координаты в формате X Y : ", terminator: "" )
   let line : String! = readLine()
   if nil == line { return nil } // EOF
   if 0 == line.count { throw InputError.emptyString }
   let компоненты : Array<Substring> = line.split( whereSeparator: { $0 == " " } )
   if компоненты.count < 2 { throw InputError.lessDigits }
   if компоненты.count > 2 { throw InputError.moreDigits } 
   let x : Double! = Double( компоненты[ 0 ] )
   if x == nil { throw InputError.noDigit( s:компоненты[ 0 ] ) }
   let y : Double! = Double( компоненты[ 1 ] )
   if y == nil { throw InputError.noDigit( s:компоненты[ 1 ] ) }
   return point( x:x, y:y )
} 

while true {
   do {
      if let p = try input() {       // p = не nil
         print( "точка X=\(p.x!) Y=\(p.y!)" )
      }
      else { break }                 // EOF
   } catch InputError.noDigit( let why ) {
      print( "не число: \(why)" ) 
   } catch InputError.emptyString {
      print( "пустая строка" ) 
   } catch InputError.lessDigits {
      print( "мало чисел" ) 
   } catch InputError.moreDigits {
      print( "много чисел" ) 
   } catch {
      print( "непонятная ошибка: \(error)" )
   }
}
print( "\nзавершение ввода" )

Код: Выделить всё

olej@nvidia ~/2018_WORK/own.BOOKs/ManyLang/swift $ make 2Din
swiftc -O 2Din.swift -o 2Din

Код: Выделить всё

olej@nvidia ~/2018_WORK/own.BOOKs/ManyLang/swift $ ./2Din
координаты в формате X Y : 23 45
точка X=23.0 Y=45.0
координаты в формате X Y : -22 +33
точка X=-22.0 Y=33.0
координаты в формате X Y : 1 2 3 4
много чисел
координаты в формате X Y : 7 6 5
много чисел
координаты в формате X Y : 666
мало чисел
координаты в формате X Y : 0
мало чисел
координаты в формате X Y : 0 0
точка X=0.0 Y=0.0
координаты в формате X Y : 0d 33
не число: 0d
координаты в формате X Y : 67 t5
не число: t5
координаты в формате X Y :
пустая строка
координаты в формате X Y :
завершение ввода
P.S. Как легко понять, для всех и любых *.swift я написал Makefile такого примерно содержания:

Код: Выделить всё

%: %.swift
        swiftc -O $< -o $@
Вложения
2Din.swift
(1.61 КБ) 83 скачивания

Аватара пользователя
Olej
Писатель
Сообщения: 21336
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Swift под Linux

Непрочитанное сообщение Olej » 09 фев 2018, 17:09

Olej писал(а):

Код: Выделить всё

olej@nvidia ~/2018_WORK/own.BOOKs/ManyLang/swift $ ./2Din
...
Характерно (и грустно!) что при переносе, копировании полученного исполнимого файла на другой хост, другой Linux (Fedora 25), на котором не развёрнута вся инфраструктура Swift:

Код: Выделить всё

[olej@dell swift]$ file 2Din
2Din: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, not stripped

[olej@dell swift]$ ./2Din 
./2Din: error while loading shared libraries: libswiftCore.so: cannot open shared object file: No such file or directory

[olej@dell swift]$ ldd 2Din
	linux-vdso.so.1 (0x00007ffd569e7000)
	libswiftCore.so => not found
	libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f99e71b1000)
	libm.so.6 => /lib64/libm.so.6 (0x00007f99e6ea8000)
	libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f99e6c91000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f99e68cb000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f99e7539000)

Аватара пользователя
Olej
Писатель
Сообщения: 21336
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Swift под Linux

Непрочитанное сообщение Olej » 09 фев 2018, 19:26

Olej писал(а): Характерно (и грустно!) что при переносе, копировании полученного исполнимого файла на другой хост, другой Linux (Fedora 25), на котором не развёрнута вся инфраструктура Swift:
Но, поскольку дело здесь, как видится, только в связывании с динамическими библиотеками - можно попробовать ... собрать библиотеки (если их нет) или ссылки на них (если они есть, но не находятся или не в тех версиях):

1. Копируем по сети Swift-библиотеку с хоста, где установлен Swift, в текущий каталог, где запускаем собранное приложение (чтобы не засорять систему - только для экспериментов):

Код: Выделить всё

[olej@dell swift]$ export LD_LIBRARY_PATH=./; ./2Din 
./2Din: error while loading shared libraries: libicuuc.so.55: cannot open shared object file: No such file or directory


2. Ещё одна библиотека libicuuc.so

Код: Выделить всё

[olej@dell swift]$ ldconfig -p | grep libicuu
    libicuuc.so.57 (libc6,x86-64) => /lib64/libicuuc.so.57
    libicuuc.so (libc6,x86-64) => /lib64/libicuuc.so
Создаём ссылку:

Код: Выделить всё

[olej@dell swift]$ ln -s /lib64/libicuuc.so.57  libicuuc.so.55 

[olej@dell swift]$ ls -l lib*
lrwxrwxrwx 1 olej olej      21 фев  9 18:12 libicuuc.so.55 -> /lib64/libicuuc.so.57
-rwxr-xr-x 1 olej olej 8336608 дек  6 02:38 libswiftCore.so
Пробуем:

Код: Выделить всё

[olej@dell swift]$ export LD_LIBRARY_PATH=./; ./2Din 
./2Din: error while loading shared libraries: libicui18n.so.55: cannot open shared object file: No such file or directory
3. Ещё одна библиотека libicui18n.so

Код: Выделить всё

[olej@dell swift]$ ldconfig -p | grep libicui18n
    libicui18n.so.57 (libc6,x86-64) => /lib64/libicui18n.so.57
    libicui18n.so (libc6,x86-64) => /lib64/libicui18n.so

[olej@dell swift]$ ln -s /lib64/libicui18n.so.57 libicui18n.so.55 

[olej@dell swift]$ ls -l lib*
lrwxrwxrwx 1 olej olej      23 фев  9 18:14 libicui18n.so.55 -> /lib64/libicui18n.so.57
lrwxrwxrwx 1 olej olej      21 фев  9 18:12 libicuuc.so.55 -> /lib64/libicuuc.so.57
-rwxr-xr-x 1 olej olej 8336608 дек  6 02:38 libswiftCore.so
Запускаем:

Код: Выделить всё

[olej@dell swift]$ export LD_LIBRARY_PATH=./; ./2Din 
координаты в формате X Y : 1 1
точка X=1.0 Y=1.0
координаты в формате X Y : 1 2 3
много чисел
координаты в формате X Y : 
пустая строка
координаты в формате X Y : 
завершение ввода
Вот вам исполнение Swift-приложения в системе, где Swift не устанавливался.
Т.е. проблема именно и только в разделяемых библиотеках!

Аватара пользователя
Olej
Писатель
Сообщения: 21336
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Swift под Linux

Непрочитанное сообщение Olej » 09 фев 2018, 20:02

Olej писал(а): Характерно (и грустно!) что при переносе, копировании полученного исполнимого файла на другой хост, другой Linux (Fedora 25), на котором не развёрнута вся инфраструктура Swift:
В принципе ... можно, конечно, собрать статически приложение с библиотеками ... или даже избирательно скомпоновать статически с некоторыми избирательно библиотеками, а остальные связывать динамически. Это основной и модный способ у Windows-ов...
Но у меня, с нескольких попыток, это не получилось:

Код: Выделить всё

olej@nvidia ~/2018_WORK/own.BOOKs/ManyLang/swift $ swiftc 2Din.swift -Xlinker "-Bstatic" -L /usr/local/lib/swift_static/linux -Xlinker "-Bdynamic" -lgcc_s -o 2Din
/usr/local/lib/swift/linux/x86_64/swift_begin.o:/home/buildnode/jenkins/workspace/oss-swift-4.0-package-linux-ubuntu-16_04/swift/stdlib/public/runtime/ImageInspectionInit.cpp:function sectionDataInit(): error: undefined reference to 'swift_addNewDSOImage'
/usr/local/lib/swift_static/linux/libswiftCore.a(Errors.cpp.o):/home/buildnode/jenkins/workspace/oss-swift-4.0-package-linux-ubuntu-16_04/swift/stdlib/public/runtime/Errors.cpp:function swift::dumpStackTraceEntry(unsigned int, void*, bool): error: undefined reference to 'swift::lookupSymbol(void const*, swift::SymbolInfo*)'
...
И так далее ... много неразрешённых имён (при том, что сообщений о не найденных библиотеках нет).
Дофигища:

Код: Выделить всё

olej@nvidia ~/2018_WORK/own.BOOKs/ManyLang/swift $ swiftc 2Din.swift -Xlinker "-Bstatic" -L /usr/local/lib/swift_static/linux -Xlinker "-Bdynamic" -lgcc_s -o 2Din 2>&1 | wc -l
58

Аватара пользователя
Olej
Писатель
Сообщения: 21336
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Swift под Linux

Непрочитанное сообщение Olej » 10 фев 2018, 10:43

Olej писал(а): Следующая интересующая меня задача:
И, наконец, вариант, к которому всё шло - задача, эквивалентная тем, которые излагались на 2-х десятках языков программирования: сравнение языков программирования - задача обсчёта периметра и площади выпуклого многоугольника:

Код: Выделить всё

import Glibc

enum InputError: Error {
    case noDigit( s : Substring )
    case emptyString
    case lessDigits
    case moreDigits
}

class point {   // класс 2D точки 
   var x, y : Double
   init( x : Double, y : Double ) {
      self.x = x
      self.y = y
   }
   func display() {
      print( "[\( x ),\( y )]", terminator: " " )
   }
   func minus( p : point ) -> point {
      return point( x:x - p.x, y:y - p.y )
   }
   func abs() -> Double {
      return sqrt( pow( x, 2 ) + pow( y, 2 ) ) 
   }
   func polar() -> ( Double, Double ) {
      let r = abs(), θ = atan2( y, x )
      return ( r, θ )
   }
}

func input() throws -> point? {
   let line : String! = readLine()
   if nil == line { return nil } // EOF
   if 0 == line.count { throw InputError.emptyString }
   let компоненты : Array<Substring> = line.split( whereSeparator: { $0 == " " } )
   if компоненты.count < 2 { throw InputError.lessDigits }
   if компоненты.count > 2 { throw InputError.moreDigits } 
   let x : Double! = Double( компоненты[ 0 ] )
   if x == nil { throw InputError.noDigit( s:компоненты[ 0 ] ) }
   let y : Double! = Double( компоненты[ 1 ] )
   if y == nil { throw InputError.noDigit( s:компоненты[ 1 ] ) }
   return point( x:x, y:y )
} 

class polygon {
   var count = 0
   var pts = [point]()
   func append( p : point ) {
      pts.append( p )
   }
   init() {
      print( "координаты вершин в формате: X Y (^D конец ввода)" )
      while true {
         print( "вершина № \( count + 1 ) : ", terminator: "" )
         do {
            if let p = try input() {       // p = не nil
               pts.append( p )
               count += 1
            }
            else { 
               print( "\r", terminator: "" )
               break                       // ^D - EOF
            }   
         }
         catch InputError.emptyString {
            break;                         // Enter - EOF
         }
         catch InputError.lessDigits {
            print( "мало чисел" ) 
         } 
         catch InputError.moreDigits {
            print( "много чисел" ) 
         }
         catch InputError.noDigit( let why ) {
            print( "не число: \(why)" ) 
         }
         catch {
            print( "непонятная ошибка: \(error)" )
         }
      }
      if 0 == count { return }            
      print( "вершин \(count) : ", terminator: "" )
      for p in pts {
         p.display()
      }
      print()
   }
   func perimeter() -> Double {
      var summa = 0.0
      for i in 1 ... count {
         summa += ( pts[ i % count ].minus( p:pts[ i - 1 ] ) ).abs()
      } 
      return summa
   }
   func square() -> Double {
      var summa = 0.0
      for i in 1 ... count - 2 {
         let ( r1, θ1 ) = ( pts[ i ].minus( p:pts[ 0 ] ) ).polar(),
             ( r2, θ2 ) = ( pts[ i + 1 ].minus( p:pts[ 0 ] ) ).polar()
         summa += r1 * r2 * fabs( sin( θ2 - θ1 ) ) / 2.0 
      }
      return summa
   }
}  

while true {
   let  plg = polygon()
   if( plg.count < 3 ) { break }
   print( "периметр = \( plg.perimeter() )" )
   print( "площадь = \( plg.square() )" )
}

Код: Выделить всё

olej@nvidia ~/2018_WORK/own.BOOKs/ManyLang/swift $ swiftc -O triangle.swift -o triangle
Выполнение:

Код: Выделить всё

olej@nvidia ~/2018_WORK/own.BOOKs/ManyLang/swift $ ./triangle
координаты вершин в формате: X Y (^D конец ввода)
вершина № 1 : 0 0
вершина № 2 : 0 1
вершина № 3 : 1 0
вершин 3 : [0.0,0.0] [0.0,1.0] [1.0,0.0]
периметр = 3.41421356237309
площадь = 0.5
координаты вершин в формате: X Y (^D конец ввода)
вершина № 1 : 0 0
вершина № 2 : 0 1
вершина № 3 : 1 1
вершина № 4 : 1 0
вершин 4 : [0.0,0.0] [0.0,1.0] [1.0,1.0] [1.0,0.0]
периметр = 4.0
площадь = 1.0
координаты вершин в формате: X Y (^D конец ввода)
Вложения
triangle.swift
(3.21 КБ) 71 скачивание

Аватара пользователя
Olej
Писатель
Сообщения: 21336
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Swift под Linux

Непрочитанное сообщение Olej » 10 фев 2018, 11:01

Olej писал(а): И, наконец, вариант, к которому всё шло - задача, эквивалентная тем, которые излагались на 2-х десятках языков программирования: сравнение языков программирования - задача обсчёта периметра и площади выпуклого многоугольника:
Здесь есть многое, для того чтобы составить представление о языке Swift:
- определение классов и объектов
- обработка ошибок возбуждением исключений
- возврат нескольких значений (кортежа) из функции
- импорт и использование математической библиотеки C

Аватара пользователя
Olej
Писатель
Сообщения: 21336
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Swift под Linux

Непрочитанное сообщение Olej » 10 фев 2018, 11:49

Olej писал(а): Выполнение:
Теперь та же задача в Linux системе, где Swift не устанавливался ... перенос в другую систему:

Код: Выделить всё

[olej@dell Загрузки]$ lsb_release -a
LSB Version:	:core-4.1-amd64:core-4.1-noarch
Distributor ID:	Fedora
Description:	Fedora release 25 (Twenty Five)
Release:	25
Codename:	TwentyFive

Код: Выделить всё

[olej@dell swift]$ export LD_LIBRARY_PATH=./; ./triangle
./triangle: error while loading shared libraries: libswiftGlibc.so: cannot open shared object file: No such file or directory
Хотя по ссылкам на библиотеки:

Код: Выделить всё

olej@nvidia ~/2018_WORK/own.BOOKs/ManyLang/swift $ ldd 2Din
    linux-vdso.so.1 =>  (0x00007ffc4b79c000)
    libswiftCore.so => /usr/local/lib/swift/linux/libswiftCore.so (0x00007f01b4be5000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f01b4863000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f01b455a000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f01b4344000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f01b3f7a000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f01b3d5d000)
    libatomic.so.1 => /usr/lib/x86_64-linux-gnu/libatomic.so.1 (0x00007f01b3b55000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f01b3951000)
    libicuuc.so.55 => /usr/lib/x86_64-linux-gnu/libicuuc.so.55 (0x00007f01b35bd000)
    libicui18n.so.55 => /usr/lib/x86_64-linux-gnu/libicui18n.so.55 (0x00007f01b315b000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f01b5181000)
    libicudata.so.55 => /usr/lib/x86_64-linux-gnu/libicudata.so.55 (0x00007f01b16a4000)
Здесь нет явного связывания (динамического) с библиотекой libswiftGlibc.so - математических функция языка C ... но, возможно, она подгружается по требованию в момент вызова?

Аватара пользователя
Olej
Писатель
Сообщения: 21336
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Swift под Linux

Непрочитанное сообщение Olej » 10 фев 2018, 11:56

Olej писал(а): Здесь нет явного связывания (динамического) с библиотекой libswiftGlibc.so - математических функция языка C ... но, возможно, она подгружается по требованию в момент вызова?
Копируем (по сети) библиотеку libswiftGlibc.so из /usr/local/lib/swift/linux, с хоста установки Swift, в любое место, которое доступно для поиска библиотек или которое мы можем явно указать с помощью переменной окружения LD_LIBRARY_PATH:

Код: Выделить всё

[olej@dell swift]$ ls -l lib*
lrwxrwxrwx 1 olej olej      23 фев  9 18:14 libicui18n.so.55 -> /lib64/libicui18n.so.57
lrwxrwxrwx 1 olej olej      21 фев  9 18:12 libicuuc.so.55 -> /lib64/libicuuc.so.57
-rwxr-xr-x 1 olej olej 8336608 дек  6 02:38 libswiftCore.so
-rwxr-xr-x 1 olej olej   32752 дек  6 02:38 libswiftGlibc.so

И теперь имеем:

Код: Выделить всё

[olej@dell swift]$ export LD_LIBRARY_PATH=./; ./triangle
координаты вершин в формате: X Y (^D конец ввода)
вершина № 1 : 0 0
вершина № 2 : 
вершин 1 : [0.0,0.0] 
[olej@dell swift]$ export LD_LIBRARY_PATH=./; ./triangle
координаты вершин в формате: X Y (^D конец ввода)
вершина № 1 : 0 0
вершина № 2 : 0 1
вершина № 3 : 1 0
вершин 3 : [0.0,0.0] [0.0,1.0] [1.0,0.0] 
периметр = 3.41421356237309
площадь = 0.5
координаты вершин в формате: X Y (^D конец ввода)

Аватара пользователя
Olej
Писатель
Сообщения: 21336
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Swift под Linux

Непрочитанное сообщение Olej » 16 апр 2018, 19:24

Swift vs. Kotlin. Отличия важны
9 марта в 13:42
Этот пост является вольным переводом статьи Swift vs. Kotlin — the differences that matter by Krzysztof Turek

Вы наверняка видели это сравнение Swift и Kotlin: http://nilhcem.com/swift-is-like-kotlin/. Довольно интересное, правда? Я согласен, что в этих языках много схожего, но в этой статье я обращу внимание на некоторые аспекты, которые их все-таки разнят.

Ответить

Вернуться в «Программирование»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 5 гостей