Undefined symbols for architecture x86_64:
  "__TFC8Winenote4WineCfMS0_FT4nameSS_S0_", referenced from:
      __TFC13winenoteTests13WinenoteTests11testExamplefS0_FT_T_ in WinenoteTests.o

このようなエラーが出て大変ハマりました。まっさらから作った簡単なコードでは起きないのになぜだろうと・・・結論から言うとProduct Nameを小文字始まりにするとハマりますよということです。

どういう状況で起きたかというとWinenoteというプロジェクトのWineクラスのテストコードを書いてビルドした時です。

import XCTest
import Winenote

public class WineTests: XCTestCase {
    public func testWine() {
        // Wineオブジェクト生成
        var wine = Wine()
    }

よーくエラーメッセージを見てみたら明らかでした。この部分です。

__TFC8Winenote4WineCfMS0_FT4nameSS_S0_

これはWinenoteというパッケージ名のWineクラスを指しているんですが、パッケージ名は実はwinenoteだったのです。小文字始まり。

プロジェクトのパッケージ名は、Build SettingsのProduct Nameで決まります。ここをwinenoteにしていたため、パッケージ名も小文字始まりになっていました。そこで、以下のようにimportも小文字にしたら無事リンクできました。

import winenote

最初にプロジェクトを作るときにProduct Nameを入力しますが、それによりBundle Identifierも決まります。大文字始まりにすると、

net.stack3.Winenote

のようになって気持ちが悪いので、Product Nameを小文字にしがちです。結構ハマっている人多いんじゃないでしょうか。

そもそもの話、リンクではなくコンパイラレベルで、そんなパッケージはないよと出してくれれば、もっと早く気づいたかもしれません。Swiftのコンパイラのエラーメッセージは、まだまだ洗練されておらず的確にエラー原因を示してくれないことが多いです・・・今後のアップデートに期待。