LoginSignup
6

More than 5 years have passed since last update.

posted at

updated at

[swift] swiftcコマンド まとめ

環境

  • OS: MacOS Sierra
  • swiftc --version
  Apple Swift version 4.0 (swiftlang-900.0.65 clang-900.0.37)
  Target: x86_64-apple-macosx10.9

書いたこと

  • モジュールとライブラリについて
  • モジュールファイルの作成
  • 静的ライブラリーの作成
  • 動的ライブラリーの作成
  • 実行ファイルの作成

Swiftのモジュールとライブラリについて

Swiftソースファイルをモジュール化するには、swiftmoduleファイルを作成する必要がある。
このswiftmoduleファイルは、C言語のヘッダーファイルに相当する。

従って、Pythonなどのようなスクリプト言語におけるモジュールとは異なり、実行ファイル生成時もしくは、swiftコマンドで直接ソースファイルを実行時に、別途ライブラリやソースファイルを指定する必要がある。

swiftコンパイラは、モジュールとライブラリーを単独でそれぞれ出力する事ができる。
またライブラリは静的ライブラリと動的ライブラリどちらも作ることができるが、
実行ファイルの作成時においてライブラリをリンクする際、動的ライブラリと静的ライブラリで違いはない。

前提とするディレクトリ階層

Main/-*-main.swift
      |
      *-Foo/-*-Foo.swift

以下、Fooを外部モジュールとみたてて、Main.swiftファイルの実行ファイルを作成する方法を説明する。

モジュールファイルの作成

$ swiftc -emit-module -module-name Foo Foo.swift

Foo.swiftmoduleファイルが生成される。

NOTE: 指定しているオプションについて

option description
-emit-module モジュールを出力するように指定
-module-name 出力するモジュール名を指定

main.swiftファイル内で、Fooモジュールがimportされている場合は以下のようにしてmain.swiftファイルのコンパイルが可能になる。

$ swiftc -I ../Foo ../Foo/Foo.swift main.swift -o a.out
$ ./a.out # 実行

NOTE: 指定しているオプションについて

option description
-I モジュール検索パス

静的ライブラリーの作成

1. オブジェクトファイルを作る
$ swiftc -emit-object -parse-as-library Foo.swift

Foo.oファイルが生成される。

NOTE: 指定しているオプションについて

option description
-emit-object オブジェクトファイルを出力するように指定
-parse-as-library 指定されたソースファイルをライブラリとして解析するように指定。この指定がないと実行ファイル生成時に、_mainシンボルが重複しているエラーが出力される
2. 静的ライブラリーの作成  
$ ar r libFoo.a Foo.o ...

...には、他にもオブジェクトファイルがある場合は指定する


MEMO:
オブジェクトファイル作成時に、-parse-as-library を指定しないと、実行ファイル生成時に_mainシンボルが重複しているエラーが表示される。

$ swiftc -I ./Foo -L ./Foo -lFoo main.swift 
ld: warning: ignoring file .//libFoo.a, file was built for archive which is not the architecture being linked (x86_64): .//libFoo.a
Undefined symbols for architecture x86_64:
  "__T03FooAAVABSS4name_tcfC", referenced from:
      _main in main-c86a13.o
ld: symbol(s) not found for architecture x86_64

静的ライブラリの機能(関数など)はswiftコマンドで読み込むことはできない。
一旦swiftcコマンドで実行ファイルを生成する必要がある。

動的ライブラリの作成

動的ライブラリは直接swiftcコマンドで作成出来る。

$ swiftc -emit-library Foo.swift

libFoo.dylibが生成される。

NOTE: 指定しているオプションについて

option description
-emit-object オブジェクトファイルを出力するように指定

また以下のように直接モジュールとライブラリーを作ることも可能
ex: 動的ライブラリの場合

$ swiftc -emit-library -emit-module -module-name Foo Foo.swift

MEMO:
動的ライブラリは、-parse-as-library を指定する必要はない。
また動的ライブラリはswiftコマンドで直接ライブラリ内の機能をロード出来る。

実行ファイルの作成

Main実行ファイルを作成する

 $ swiftc -I ./Foo -L ./Foo -lFoo main.swift

NOTE: 指定しているオプションについて

option description
-I モジュール検索パス
-L ライブラリ検索パス
-lXXX libXXXライブラリをリンクするように指定

main実行ファイルの実行

$ ./Main

swiftソースファイルを直接実行

Fooモジュールが、動的ライブラリの場合はswiftコマンドでmain.swiftをそのまま実行できる。
しかしながら、静的ライブラリは実行エラーになる。

$ swift -I ./Foo -L ./Foo -lFoo main.swift

関連

  • clangモジュールについて
    https://qiita.com/ysn551/items/6f783af2b65c2c4d4631]
    こちらはObjective-Cで開発時に私がまとめたものです。
    このモジュール機能を調べていなければ、Swiftのモジュールは理解できなかっただろうと思いました。

  • [C言語] 共有ライブラリと静的ライブラリを整理する
    https://qiita.com/edo_m18/items/b9765ff3313d5a13f82f
    ライブラリの作成方法で参照にさせていただきました。
    オブジェクトファイルから静的ライブラリを作る方法がC言語とまったく同じってところがswiftの凄さですよね。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
6