SSブログ

SwiftをUbuntuでやる。 [プログラミング]

以下は
Ubuntu 16.04
Swift version 3.1.1
でお送りします。んがくく(古い)

インストールの大体はダウンロードサイトのページの事を大体やってある。
https://swift.org/download/#using-downloads

SwiftがOSSになって、Ubuntu上の開発環境が提供されたわけだが、Linux上での開発が良く分からない。というか、基本GUIアプリを作るためのSwiftをLinuxのコマンドラインアプリを作るための使い方とかはあんまり見ない。まぁMacがあるのにわざわざUbuntu上でやることもないのだが、なんとなく天邪鬼な自分としてはせっかくのOSSだからOSSらしく使いたい。

そもそもOSS版で使えるのは標準ライブラリとかなんだろうけど、その範囲がいまいち良く分からなかった。MacのSwiftはGUIを主眼において開発されているから、全体としてそこをどうするかの話になってきてしまう。でも、OSSなSwiftの使うところはそこじゃない。というか、そこの部分は作られてないはず。

http://quesera2.hatenablog.jp/entry/2015/12/05/163855

一年以上前の記事だけど興味深いことが書かれている。実際に実現しているところもあるのかなぁ。細かくは分からん。

Swiftの通常版とオープンソース版の違いについて、という直球な題の記事もあった。

http://qiita.com/glayash/items/a4b1b1ffef97e649395b

一言で言うなら

Foundation
libdispatch
XCTest

ということなんだろうけど、そもそもFoundationというのがどこまでなのかが分かっていない。一つ前のリンクにあるように標準ライブラリを含んだ形でFoundationがあるようだ。

実際のAppleのリファレンス的にはどこのURLに当たるのかだけれども

https://developer.apple.com/reference/swift

ここはどうにも機能的にまとまっているわけでもなく、ただのんべんだらりとアルファベット順に書かれているだけですね。

https://developer.apple.com/reference/foundation

とここにクラス群がまとまっていますが、print文はどこに属すの~という感じで、クラスのメソッドじゃない標準のものに関しては、別途挙げていかないといけないのかなと思いつつ、SwiftはGUI部分以外はほとんど何も分かっていないなと言うことが判明。いや、そんなんでOSSなSwift扱えるんか、と。

それとやたらとNSという接頭辞がObject-Cの時代を思い出させる。Swift3.0からはそれを取ろうとしているみたいだけど、正直中途半端間は否めない。

としりごんでいても仕方ないので、実際にコンパイルして動くものを作ってみようと思う。ただ単にURLを与えると、ダウンロードしてくるプログラムを作ってみる。

まず引数からURLを取ってくるところから。GUI用の言語をCUIで使うにはまずそこからだよね。

import Foundation

//print(C_ARGV)
//print(Process.arguments)
//print(Process.argv[1])
print(CommandLine.arguments)


やっと出てきた。何だよこの情報のぶれ方はw。というか、Swiftのライブラリの命名方法がやたら変わりすぎていて、いつのバージョンで効く情報なのかさえも非常に分かりづらい。

実はimport Foundationしなくても動いた。これが暗黙にFoundationをインポートするのか、なくても標準ライブラリとして装備されているのかは分からない。そもそもFoundationと標準ライブラリの境が分からんし。

NSURLはimport Foundationしないと知らないと言われた。普通に使うには基本的にFoundationをインポートしないといけないらしい。まぁ細かいパッケージをちまちまインポートするよりかずっとマシだけれども。いまだにNS何とかと書かないといけないのは新しくSwift3に移った余波としては言語に型名を近づけるのは、主要な場所以外は限定的なのかなぁ。

ダウンロードはNSURLConnectionがDeprecatedになって、NSURLSessionになったとiOS関係の記事には書いてあるのだけれども、どっちもGUIアプリ用のイベントを前提にしたものだから、普通にコマンドラインで単純に実行するには不必要と言うか、要らない機能も含まれている気がする。ソケットを生で使う程度の低レベルのものがないのかなぁと。

ともあれ非同期的な書き方をしなければいいわけで、Deprecatedになっていようが動けばとりあえず良しとする。というか、どこまで動いてくれるのかがわかっていない状態なので、別にHTTPを特に試したいわけじゃない。

NSURLConnectionがDeprecatedになったと書いてあったが、正確には多くの関数がDeprecatedになって、同期通信は出来なくなっていた。

https://developer.apple.com/reference/foundation/nsurlconnection

デリゲートとかやらないといけないのかな。面倒くさいな。URL取ってくるだけなんだけど。もっとシンプルなクラスとかないのかな。


色々なものを参考にしたんだけど、Linuxで直で動くソースが見つからないので切り張りして何とかコンパイルできるぐらいには持っていってみる。

import Foundation

print(CommandLine.arguments)
let myUrl = URL(string: CommandLine.arguments[1])!
let req = URLRequest.init(url: myUrl)
let config = URLSessionConfiguration.default

let session = URLSession(configuration: config)
let task = URLSession.shared.dataTask(with: myUrl) { data, response, error in
  do{
    try data!.write(to: URL(string: "./text.txt")!, options: NSData.WritingOptions.atomic)
  }catch{
  }
}
task.resume()


上手く動くかどうかは知らんが、コンパイルは通ったのでその点では問題ないだろう。NSのプリフィックスは軒並みコンパイラに怒られた。まぁ使わなくていいならそれでいい。

まずLLVMか何かのエラーが出るので、実行環境の./usr/libを$LD_LIBRARY_PATHに入れる。/etc/ld.conf.dの中のファイルをいじってもいいと思う。

コンパイル後動作させると、色々共有ライブラリがないといわれているみたいで、参照先がないよと言われる。

find .|grep \\.so |xargs -i% cp % .

./usr/libにパスは通っているものの、それ以下のディレクトリには通っていないので、あるもの全部を無理やりコピーしてくる。スタティックリンク用のファイルはいらないはず。

共有ライブラリを移動させた後も、libcurl.so.4がないというので入っているパッケージを入れる。

sudo apt install libcurl3

やっと動いたと思ったら、こんなメッセージが

fatal error: shared is not yet implemented: file Foundation/NSURLSession/NSURLSession.swift, line 200
Illegal instruction (core dumped)

sharedっての、インプリされてないってよw。というか、ソケット使いたいだけなので、低レベルな関数を提供してください。それかXcodeレベルに上げてください…。色々やり方はあるみたいなんだけど、簡単にしようとして逆に八方ふさがりになっている気がする。

もう少しまともになっていると思っていたんだけど、Ubuntuの開発具合はこんなもんなんだな。というか、テキストソースに互換性がないって事なのかな。あ~Macの方はObjective-Cのライブラリをはさんでいるから、直接のインプリはObj-Cって事なのかもね。なもんで、Linux版のインプリはSwiftで全部なされてないと。

Ubuntu版の中身の進捗はあまりよろしくないと言えるでしょう。時間と共に解消はされるけれども、正直何かを作るに足る状態にはなっていないのは間違いないです。だって普通にネットワークのメソッドも使えない状態なんですよ。FoundationはSwiftで書かれているって言うことは、それに近いことを自分でも出来そうな気がしますよね。Core FoundationはC言語で書かれていて、それをSwiftで呼んでいるっぽいのを読んだ気がするので、そこまでしないとまともに使えないのかもしれない。

でも、そこまでしてまで使いたい言語なのかと言うと微妙だ。楽ができるから使うとか、iOSも開発できるから使うとか、そういうカジュアルめいたものだと思っていたんだけど、どうやらそうではない感じである。やはり商業ベースのものをOSSにするというのは、それなりにハードルが高いんだなと思わざるを得ない。

あ~やっぱり本格的に手を入れようとするとCoreFoundationを使わないといけないらしい。

https://developer.apple.com/documentation/corefoundation

でも、Swiftで直接関数を提供しているみたいなので、そこいらはC言語との兼ね合いを考えなくてもいいので楽できるのかもしれない。とはいえ、そこいらへんの情報はAppleからしか出ていなくて、サンプルソースとかあんまり出ていなさそうな気がする。コピペ厨房な自分としては、全部自力でインプリするのはめんどいなぁと思うわけで。

ただ、自分でライブラリを書こうとするとCFなんちゃらの関数は使っていかないとダメだろうなという事はなんとなく分かる。ただFoundationを無視するのは結構汎用性も落ちるし、車輪の再発明になりかねない状態だったりはする。


それにソケットのところを見ると

https://developer.apple.com/documentation/corefoundation/cfsocket-rg7

#include <sys/socket.h>
とかしていて、かなりSwift使っている感が薄くなる。

ちょっとどうしようか迷っている。Swiftで書く意味があるのか、というのが一番の問題点ではある。そもそも先ほどのコンパイルだけ通したものが、Xcodeで動くのかなというのを確かめたほうがいい気がしてきた。

そして、そもそもSwiftがiOSやMacOSのGUIアプリを念頭に置いた言語であり、Foundationもそれに沿ったものであることを心に留めておかないといけない。

タグ:Swift3
コメント(0) 
共通テーマ:パソコン・インターネット

コメント 0