Swiftはじめたい...その２０ モジュール


# その１８で作ったServer-side SwiftでCGI部分をモジュール化してみます。

+ CGI.pmなイメージですね。

## ソースを分割してみます。

+ class CGIを分離します。
+ １行目におまじないを書いておきます。

```swift:printenv.swift
import CGI

let q = CGI()

print("Content-type: text/html; charset=utf-8\n")
print("<!DOCTYPE html>")
print("<html lang=\"ja\">")
print("<head>")
print("<meta charset=\"UTF-8\">")
print("<meta name=\"viewport\" content=\"width=device-width\">")
print("<title>Hello Swift</title>")
print("</head>")
print("<body>")

print("<h4>Request Parameter</h4>")
print("<p>name : \(q.param("name"))</p>")
print("<p>age  : \(q.param("age"))</p>")

print("</body>")
print("</html>")
```

+ CGI.swiftだけを書いておきます。

```swift:CGI.swift
import Foundation

public class CGI {
		var p = [String:String]()

		public init() {
			// プロセスの環境変数を取得
			let ENV = NSProcessInfo.processInfo().environment
			// 環境変数からQUERY_STRINGを取得
			if let params = ENV["QUERY_STRING"] {
				if ( params != "" ) {
					if let tupple:[String] = params.componentsSeparatedByString("&") {
						tupple.forEach {
							let kv = $0.componentsSeparatedByString("=")
							p[kv[0]] = kv[1]
						}
					}
				}
			}
		}

		public func param(key:String) -> String {
				if let ret = p[key] {
						return ret
				} else {
						return ""
				}
		}
}
```


## 実行できるのかな？

#### ソースコードだけでimportしたのは動くでしょうか？

```shell:ソースだけでimportできるの？
% ./swift -I . -L . -lCGI printenv.swift
./printenv.swift:1:8: error: no such module 'CGI'
import CGI
```
+ ま、そりゃだめですよね...

#### モジュールを作成

+ 一行一発でできました！

```shell:module
% xcrun -sdk macosx swiftc -O -emit-library -emit-module CGI.swift -module-name CGI
% swift -I . -L . -lCGI printenv.swift
Content-type: text/html; charset=utf-8

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>Hello Swift</title>
</head>
<body>
<h4>Request Parameter</h4>
<p>name : </p>
<p>age  : </p>
</body>
</html>
```
<!-- // 一行でできたので削除

#### モジュールを作成

```shell:-emit-module
% xcrun -sdk macosx swiftc -emit-module -module-name CGI  CGI.swift
% ./swift -I . -L . -lCGI printenv.swift 
LLVM ERROR: Program used external function '__TMaC3CGI3CGI' which could not be resolved!
```

+ CGI.swiftdocとCGI.swiftmoduleというファイルができましたがダメでした。

#### オブジェクトファイルを作成

```shell:-emit-object 
% xcrun -sdk macosx swiftc -emit-object  -o CGI.o CGI.swift
% ./swift -I . -L . -lCGI printenv.swift
LLVM ERROR: Program used external function '__TMaC3CGI3CGI' which could not be resolved!
```

+ CGI.oというファイルができましたがダメでした。

#### ライブラリを作成

```shell:libtool 
% libtool -L/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/ -macosx_version_min 10.11 -dynamic -lc -o libCGI.dylib CGI.o
% ./swift -I . -L . -lCGI printenv.swift
Content-type: text/html; charset=utf-8

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>Hello Swift</title>
</head>
<body>
<h4>Request Parameter</h4>
<p>name : </p>
<p>age  : </p>
</body>
</html>
```
 
+ やっとできました！libCGI.dylibというファイルができました。
+ 実際には、libCGI.dylibとCGI.swiftmoduleがあれば動きました。

#### コンパイル＆実行

+ リンクオプションを指定してコンパイルしてください。

```shell
% xcrun -sdk macosx swiftc -I . -L . -lCGI -o printenv.cgi printenv.swift
% ./printenv.cgi 
Content-type: text/html; charset=utf-8

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>Hello Swift</title>
</head>
<body>
<h4>Request Parameter</h4>
<p>name : </p>
<p>age  : </p>
</body>
</html>
```

+ コンパイルしてしまえば、libCGI.dylibだけあれば動きました。

-->

## まとめ

+ コマンドラインだとちょっと面倒くさいですね。