今回はコマンドラインでビルド、実行してみます。
- いままでplaygroundで試していましたが、コマンドラインプログラムを作ってみます。
開発環境の確認
- xcodeで使えていればそのまま使えるのかな?コンパイルはswiftcというコマンドです。
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 実行ファイル ソースファイル
で良さそうです。
コンパイル〜実行
- 簡単なプログラムで確認してみます。
sample.swift
print("HELLO WORLD");
- これだけ…コンパイルできるでしょうか?
結果
> swiftc -o sample.out sample.swift
> ./sample.out
HELLO WORLD
- 簡単ですね!
引数
- コマンドラインプログラム風に書いてみましょう。
- ARGVのコマンドライン引数を取るには素の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()
- 引数をつけてみます。
引数を付けて実行
> ./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言語のソース
#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言語のソース
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も使えるようになってるのかな?
今日はここまで
- 次こそはジェネリクスを調べるつもりです。