0

オープン ソース ライブラリをコンパイルするときに奇妙な問題が発生します。デバイス用にコンパイルすると、Xcode は問題なくコンパイルし、問題なく展開します。ただし、シミュレーター用にコンパイルすると、リンク フェーズで重複シンボル エラーが発生します。

これらのいくつかをチェックしましたが、これらのシンボルはすべて .m ファイルではなく .hh ファイルに実装されているようです。明らかにこれは悪いコード構造であり、エラーは理にかなっています。ただし、デバイス ビルドでエラーが発生しない理由は理解できません。

これらの各 .hh ファイルには、ファイルの先頭に #pragma once が含まれています。私の最初の考えでは、これは期待どおりに機能していませんでしたが、削除すると、これらのシンボルを再定義したことを示す、デバイス ビルドとシミュレータ ビルドの両方でコンパイル時エラーが発生しました。うーん、それで #pragma once を置き換えてみました

#ifndef EXAMPLE_DEFINE
#define EXAMPLE_DEFINE

// code

#end if

しかし、これは #pragma once と同じ結果になります。

膨大な数のコード変更が必要になるため、コードベースを簡単に更新できるようにしたいので、すべてのエラーを手動で修正することは現実的ではありません。デバイスでこれが失敗しない理由はありますか?また、シミュレーターのビルドを同じように実行するにはどうすればよいですか?

編集: #include の代わりに #import を使用してテストしましたが、同じ結果が得られます

編集 2: さらにテストした結果、ターゲットのビルド設定でプリプロセッサ マクロを定義すると、#ifndef 内のコードが期待どおりに呼び出されないことがわかりました。なんらかの理由で、.hh ファイルでの新しい定義の定義が、ファイルの次のコンパイルに引き継がれていないようです。

また、リクエストに応じて、ビルドログからの抜粋を次に示します

duplicate symbol __ZZN12DelegateFuncIFvR16DualTextMenuItemRKN5Input5EventEEEC1IZN25MultiChoiceSelectMenuItem4initEPPKciiibSB_P12ResourceFaceEUlS1_S5_E_EERKT_PNSt3__19enable_ifIXntsr3std11is_functionISG_EE5valueEvE4typeEENKS8_ISF_EUlRKNS7_7StorageES1_S5_E_cvPFvSR_S1_S5_EEv in:
    /Users/riley.testut/Library/Developer/Xcode/DerivedData/GBA4iOS-dqkflotukruucqbxjyslhtfuekse/Build/Intermediates/GBA4iOS.build/Debug-iphonesimulator/GBA4iOS.build/Objects-normal/i386/Main-FB93852047D42061.o
    /Users/riley.testut/Library/Developer/Xcode/DerivedData/GBA4iOS-dqkflotukruucqbxjyslhtfuekse/Build/Intermediates/GBA4iOS.build/Debug-iphonesimulator/GBA4iOS.build/Objects-normal/i386/OptionView.o
duplicate symbol __ZZN12DelegateFuncIFbiRKN5Input5EventEEEC1IZN15MultiChoiceView4initER19MultiChoiceMenuItemb9_2DOriginEUliS3_E_EERKT_PNSt3__19enable_ifIXntsr3std11is_functionISC_EE5valueEvE4typeEENKS6_ISB_EUlRKNS5_7StorageEiS3_E_cvPFbSN_iS3_EEv in:
    /Users/riley.testut/Library/Developer/Xcode/DerivedData/GBA4iOS-dqkflotukruucqbxjyslhtfuekse/Build/Intermediates/GBA4iOS.build/Debug-iphonesimulator/GBA4iOS.build/Objects-normal/i386/Main-FB93852047D42061.o
    /Users/riley.testut/Library/Developer/Xcode/DerivedData/GBA4iOS-dqkflotukruucqbxjyslhtfuekse/Build/Intermediates/GBA4iOS.build/Debug-iphonesimulator/GBA4iOS.build/Objects-normal/i386/OptionView.o
duplicate symbol __ZZN12DelegateFuncIFvR12TextMenuItemRKN5Input5EventEEEC1IN14YesNoAlertView2noMUlS1_S5_E_EEERKT_PNSt3__19enable_ifIXntsr3std11is_functionISB_EE5valueEvE4typeEENKS8_ISA_EUlRKNS7_7StorageES1_S5_E_cvPFvSM_S1_S5_EEv in:
    /Users/riley.testut/Library/Developer/Xcode/DerivedData/GBA4iOS-dqkflotukruucqbxjyslhtfuekse/Build/Intermediates/GBA4iOS.build/Debug-iphonesimulator/GBA4iOS.build/Objects-normal/i386/ButtonConfigView.o
    /Users/riley.testut/Library/Developer/Xcode/DerivedData/GBA4iOS-dqkflotukruucqbxjyslhtfuekse/Build/Intermediates/GBA4iOS.build/Debug-iphonesimulator/GBA4iOS.build/Objects-normal/i386/MenuView.o
ld: 16 duplicate symbols for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

問題のあるファイルの 1 つ (AlertView.hh) は次のとおりです。

#pragma once

#include <gui/View.hh>
#include <gui/MenuItem/MenuItem.hh>
#include <util/gui/BaseMenuView.hh>
#include <util/rectangle2.h>
#include <util/DelegateFunc.hh>

class AlertView : public View
{
public:
    constexpr AlertView() { }
    Rect2<GC> labelFrame;
    Gfx::Text text;
    BaseMenuView menu;
    Rect2<int> rect;

    Rect2<int> &viewRect() { return rect; }

    void init(const char *label, MenuItem **menuItem, bool highlightFirst);
    void deinit() override;
    void place() override;
    void inputEvent(const Input::Event &e) override;
    void draw(Gfx::FrameTimeBase frameTime) override;
};

class YesNoAlertView : public AlertView
{
public:
    YesNoAlertView() { }
    typedef DelegateFunc<void (const Input::Event &e)> InputDelegate;

    MenuItem *menuItem[2] = {nullptr};

    // Optional delegates
    InputDelegate &onYes() { return onYesD; }
    InputDelegate &onNo() { return onNoD; }

    void init(const char *label, bool highlightFirst, const char *choice1 = nullptr, const char *choice2 = nullptr)
    {
        yes.init(choice1 ? choice1 : "Yes"); menuItem[0] = &yes;
        no.init(choice2 ? choice2 : "No"); menuItem[1] = &no;
        assert(!onYesD);
        assert(!onNoD);
        AlertView::init(label, menuItem, highlightFirst);
    }

    void deinit() override
    {
        logMsg("deinit alert");
        AlertView::deinit();
        onYesD = {};
        onNoD = {};
    }

    InputDelegate onYesD;
    InputDelegate onNoD;
private:
    TextMenuItem yes
    {
        [this](TextMenuItem &, const Input::Event &e)
        {
            auto callback = onYesD;
            removeModalView();
            if(callback) callback(e);
        }
    };
    TextMenuItem no
    {
        [this](TextMenuItem &, const Input::Event &e)
        {
            auto callback = onNoD;
            removeModalView();
            if(callback) callback(e);
        }
    };
};
4

1 に答える 1

0

ヘッダーガードを試したことを示していますが、私の提案は、次のリンクを確認することです。

http://en.wikipedia.org/wiki/Include_guard

http://c2.com/cgi/wiki?RedundantIncludeGuards

更新プログラムは、シンボルのリンカー エラーであり、これは使用しているライブラリのエラーであることを示しています。

于 2013-07-25T08:11:54.503 に答える