プロが教える店舗&オフィスのセキュリティ対策術

iPhone向けのメーラーを作ってみようと思い、LibEtPan というライブラリをGitHubから
ダウンロードして、以下のURLにある pop-sample.c のサンプルコードを使ってみたところ
エラーが出ました。
結論からいうとエラーメッセージをそのままネットで調べて、とりあえずコンパイルエラーは
発生しなくなり、無事、ライブラリを使う事はできたのですが、なぜ動くようになったのか、
今のコンパイルエラーが出ていない状態がはたして正しいのかがわかっておりません。

以下、エラー発生までのプロセスです。

1、新規でiPhone向けプロジェクトを作成
2、libEtPanをサブプロジェクトとして追加
3、libetpan-ios.a をLinkに追加
4、Other Linker Flagsに -lsasl2 を設定
5、pop-sample.cのサンプルコードをコピー
(サンプルコード内にあるファイル書き込みの処理はコンソールにメール内容を表示する処理に置き換えた)

手順3と4は以下GitHubのREADMEに書いてある手順です。
https://github.com/dinhviethoa/libetpan

この状態でビルドすると、以下のようなエラーが発生しました。

Undefined symbols for architecture i386:
"_SecCertificateCopyData", referenced from:
_mailstream_low_cfstream_get_certificate_chain in libetpan-ios.a(mailstream_cfstream.o)
"_deflate", referenced from:
_mailstream_low_compress_write in libetpan-ios.a(mailstream_compress.o)
"_deflateEnd", referenced from:
_mailstream_low_compress_open in libetpan-ios.a(mailstream_compress.o)
_mailstream_low_compress_free in libetpan-ios.a(mailstream_compress.o)
"_deflateInit2_", referenced from:
_mailstream_low_compress_open in libetpan-ios.a(mailstream_compress.o)
"_inflate", referenced from:
_mailstream_low_compress_read in libetpan-ios.a(mailstream_compress.o)
"_inflateEnd", referenced from:
_mailstream_low_compress_open in libetpan-ios.a(mailstream_compress.o)
_mailstream_low_compress_free in libetpan-ios.a(mailstream_compress.o)
"_inflateInit2_", referenced from:
_mailstream_low_compress_open in libetpan-ios.a(mailstream_compress.o)
"_kCFStreamPropertySSLPeerCertificates", referenced from:
_mailstream_cfstream_set_ssl_enabled in libetpan-ios.a(mailstream_cfstream.o)
_mailstream_low_cfstream_get_certificate_chain in libetpan-ios.a(mailstream_cfstream.o)
"_kCFStreamPropertySSLSettings", referenced from:
_mailstream_cfstream_set_ssl_enabled in libetpan-ios.a(mailstream_cfstream.o)
"_kCFStreamSSLAllowsAnyRoot", referenced from:
_mailstream_cfstream_set_ssl_enabled in libetpan-ios.a(mailstream_cfstream.o)
"_kCFStreamSSLAllowsExpiredCertificates", referenced from:
_mailstream_cfstream_set_ssl_enabled in libetpan-ios.a(mailstream_cfstream.o)
"_kCFStreamSSLAllowsExpiredRoots", referenced from:
_mailstream_cfstream_set_ssl_enabled in libetpan-ios.a(mailstream_cfstream.o)
"_kCFStreamSSLLevel", referenced from:
_mailstream_cfstream_set_ssl_enabled in libetpan-ios.a(mailstream_cfstream.o)
"_kCFStreamSSLValidatesCertificateChain", referenced from:
_mailstream_cfstream_set_ssl_enabled in libetpan-ios.a(mailstream_cfstream.o)
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

そこで、上記のエラーメッセージをネットで検索し、結果的には以下のことをすることで、コンパイルエラーが
解消しました。

・CFNetwork.framework と Security.framework のLink追加
・Other Linker Flags に -lz の追加

そこで、質問ですが、熟練したプログラマは、上記のようなエラーが出たとき、
そのエラーメッセージからどういう情報を読み取り、どのようなプロセスで問題を
解決するのでしょうか?
私は、上記のエラーメッセージを見ても「Undefined symbols」というメッセージから
何かライブラリが足りないのかな?程度しか情報を読み取る事ができませんでした。

以上、よろしくお願いします。

A 回答 (1件)

> 私は、上記のエラーメッセージを見ても「Undefined symbols」というメッセージから


> 何かライブラリが足りないのかな?程度しか情報を読み取る事ができませんでした。

このメッセージから読み取れることだったら、熟練者でも大体同じだと思います。

あとは
○ これが発生しているのは、リンク工程
Undefined Symbolsというエラーからも判断できるし
> ld: symbol(s) not found for architecture i386
> clang: error: linker command failed with exit code 1 (use -v to see invocation)
とリンカでエラーになっていることが明記されている
→ ソースコードからオブジェクトファイルへコンパイルするのは成功しているようである

○ "_SecCertificateCopyData" 等が具体的な「未定義シンボル」
→ソースコードには、 先頭の _ を除いた「SecCertificateCopyData」等が使われている
→必要なライブラリ/フレームワークを探すためのヒント

くらいでしょうか。

この回答への補足

回答ありがとうございました!

>→ ソースコードからオブジェクトファイルへコンパイルするのは成功しているようである

なるほど。
コンパイルとリンクの違いもよくわかってなかったんですが、
コンパイルは成功しているが、リンクで失敗しているということがわかると、
コードの文法的な誤りはないけど、ライブラリなどのリソースが足らない
ということがわかるのですね。

>→ソースコードには、 先頭の _ を除いた「SecCertificateCopyData」等が使われている
>→必要なライブラリ/フレームワークを探すためのヒント

SecCertificateCopyDataがどのライブラリ/フレームワークに含まれているかは、
やはり、Webで検索するなどして調べるしかないものなんですね。
もしくは、製品のマニュアルなどに記載されるべきものということでしょう。


大変参考になりました。
ありがとうございました。

補足日時:2013/09/10 21:12
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!