Swiftはじめたい...その１１ コマンドラインで実行ファイルをつくる。


# 今回はコマンドラインでビルド、実行してみます。

+ いままでplaygroundで試していましたが、コマンドラインプログラムを作ってみます。

## 開発環境の確認

+ xcodeで使えていればそのまま使えるのかな？コンパイルはswiftcというコマンドです。

```shell:swiftc

>> which swiftc
/usr/bin/swiftc

>> swiftc -version
Apple Swift version 2.1.1 (swiftlang-700.1.101.15 clang-700.1.81)
Target: x86_64-apple-darwin15.2.0

>> swiftc -help
OVERVIEW: Swift compiler

USAGE: swiftc [options] <inputs>

MODES:
  -dump-ast        Parse and type-check input file(s) and dump AST(s)
  -dump-parse      Parse input file(s) and dump AST(s)
  -dump-type-refinement-contexts
                   Type-check input file(s) and dump type refinement contexts(s)
  -emit-assembly   Emit assembly file(s) (-S)
  -emit-bc         Emit LLVM BC file(s)
  -emit-executable Emit a linked executable
  -emit-ir         Emit LLVM IR file(s)
  -emit-library    Emit a linked library
  -emit-object     Emit object file(s) (-c)
  -emit-sibgen     Emit serialized AST + raw SIL file(s)
  -emit-sib        Emit serialized AST + canonical SIL file(s)
  -emit-silgen     Emit raw SIL file(s)
  -emit-sil        Emit canonical SIL file(s)
  -parse           Parse input file(s)
  -print-ast       Parse and type-check input file(s) and pretty print AST(s)

OPTIONS:
  -application-extension  Restrict code to those available for App Extensions
  -assert-config <value>  Specify the assert_configuration replacement. Possible values are Debug, Release, Replacement.
  -D <value>              Specifies one or more build configuration options
  -embed-bitcode-marker   Embed placeholder LLVM IR data as a marker
  -embed-bitcode          Embed LLVM IR bitcode as data
  -emit-dependencies      Emit basic Make-compatible dependencies files
  -emit-module-path <path>
                          Emit an importable module to <path>
  -emit-module            Emit an importable module
  -emit-objc-header-path <path>
                          Emit an Objective-C header file to <path>
  -emit-objc-header       Emit an Objective-C header file
  -fixit-all              Apply all fixits from diagnostics without any filtering
  -fixit-code             Get compiler fixits as code edits
  -framework <value>      Specifies a framework which should be linked against
  -F <value>              Add directory to framework search path
  -gline-tables-only      Emit minimal debug info for backtraces only
  -gnone                  Don't emit debug info
  -g                      Emit debug info
  -help                   Display available options
  -import-underlying-module
                          Implicitly imports the Objective-C half of a module
  -I <value>              Add directory to the import search path
  -j <n>                  Number of commands to execute in parallel
  -L <value>              Add directory to library link search path
  -l<value>               Specifies a library which should be linked against
  -module-cache-path <value>
                          Specifies the Clang module cache path
  -module-link-name <value>
                          Library to link against when using this module
  -module-name <value>    Name of the module to build
  -nostdimport            Don't search the standard library import path for modules
  -num-threads <n>        Enable multi-threading and specify number of threads
  -Onone                  Compile without any optimization
  -Ounchecked             Compile with optimizations and remove runtime safety checks
  -output-file-map <path> A file which specifies the location of outputs
  -O                      Compile with optimizations
  -o <file>               Write output to <file>
  -parse-as-library       Parse the input file(s) as libraries, not scripts
  -parse-sil              Parse the input file as SIL code, not Swift source
  -parseable-output       Emit textual output in a parseable format
  -profile-coverage-mapping
                          Generate coverage data for use with profiled execution counts
  -profile-generate       Generate instrumented code to collect execution counts
  -save-temps             Save intermediate compilation results
  -sdk <sdk>              Compile against <sdk>
  -serialize-diagnostics  Serialize diagnostics in a binary format
  -target-cpu <value>     Generate code for a particular CPU variant
  -target <value>         Generate code for the given target
  -version                Print version information and exit
  -v                      Show commands to run and use verbose output
  -whole-module-optimization
                          Optimize input files together instead of individually
  -Xcc <arg>              Pass <arg> to the C/C++/Objective-C compiler
  -Xlinker <value>        Specifies an option which should be passed to the linker
  
```

+ ccとかと同じように``swiftc -o 実行ファイル ソースファイル``で良さそうです。

## コンパイル〜実行

+ 簡単なプログラムで確認してみます。

```swift:sample.swift
print("HELLO WORLD");
```

+ これだけ…コンパイルできるでしょうか？

```shell:結果
> swiftc -o sample.out sample.swift
> ./sample.out
HELLO WORLD
```
+ 簡単ですね！

## 引数

+ コマンドラインプログラム風に書いてみましょう。
+ ARGVのコマンドライン引数を取るには素のswiftだけじゃだめっぽいです。

```swift:Foundationをimportします。
import Foundation

func main() -> Int {
	let argv = NSProcessInfo.processInfo().arguments
	let argc = argv.count
	for ( var i = 0 ; i < argc ; i++ ) {
	    print("argv[\(i)] = \(argv[i])")
	}
	return 0
}
main()
```

+ 引数をつけてみます。

```shell:引数を付けて実行
> ./sample.out a b c d -1 漢字
argv[0] = /フルパス/sample.out
argv[1] = a
argv[2] = b
argv[3] = c
argv[4] = d
argv[5] = -1
argv[6] = 漢字
```

+ ```int main(int argc,char *argv[])```関数っぽくつかえますね。
+ NSProcessInfo.processInfo()には他にもプロセス番号や環境変数も取得できます。中身はObjective-Cと一緒です。

## 実行速度をCと比べてみる。

+ せっかくコマンドラインで動く実行ファイルが作れるようになったのでCで作ったプログラムとくらべてみます。

```c:C言語のソース
#include <stdio.h>

int main(int argc,char *argv[])
{
	int i;
	long a = 0;
	for (i = 0; i < 1000000000; i++) {
		++a;
	}
	printf("%ld\n",a);
	return 0;
}
```

```swift:Swift言語のソース
func main() -> Int {
	var a : CLong = 0
	for ( var i = 0 ; i < 1000000000 ; i++ ) {
		++a;
	}
	print(a)
	return 0
}
main()
```
### Cの実行結果

|real|user|sys|
|--:|--:|--:|
|2.42|2.41|0.00|
|2.41|2.40|0.00|
|2.42|2.41|0.00|
|2.42|2.41|0.00|
|2.39|2.38|0.00|

### Swiftの実行結果

|real|user|sys|
|--:|--:|--:|
|4.37|4.35|0.01|
|4.34|4.32|0.01|
|4.37|4.35|0.01|
|4.34|4.32|0.01|
|4.45|4.41|0.01|

+ 倍近くかかりすね。ま、敵うわけないか...

## まとめ

+ FoundationをインポートしてNSProcessInfoを使わなければいけないようです。
+ Macでは関係ないですがswiftはオープンソースになったようですが、他のプラットフォームでもFoundationも使えるようになってるのかな？

# 今日はここまで

+ 次こそはジェネリクスを調べるつもりです。