C++ 仅针对iOS模拟器构建复制符号
我在编译开源库时遇到了一个奇怪的问题。在为设备编译时,Xcode可以很好地编译并部署它。然而,当我为模拟器编译时,在链接阶段会出现重复的符号错误 我已经检查了其中的一些符号,看起来这些符号都是在.hh文件中实现的,而不是在.m文件中实现的。显然,这是糟糕的代码结构,错误是有意义的。然而,没有意义的是为什么设备构建没有错误 每个.hh文件的顶部都包含一个#pragma。我最初的想法是,这不是预期的工作,但删除后,我得到了设备和模拟器构建的编译时错误,说明我已经重新定义了这些符号。嗯,然后我试着用C++ 仅针对iOS模拟器构建复制符号,c++,ios,c,xcode,linker-errors,C++,Ios,C,Xcode,Linker Errors,我在编译开源库时遇到了一个奇怪的问题。在为设备编译时,Xcode可以很好地编译并部署它。然而,当我为模拟器编译时,在链接阶段会出现重复的符号错误 我已经检查了其中的一些符号,看起来这些符号都是在.hh文件中实现的,而不是在.m文件中实现的。显然,这是糟糕的代码结构,错误是有意义的。然而,没有意义的是为什么设备构建没有错误 每个.hh文件的顶部都包含一个#pragma。我最初的想法是,这不是预期的工作,但删除后,我得到了设备和模拟器构建的编译时错误,说明我已经重新定义了这些符号。嗯,然后我试着用
#ifndef EXAMPLE_DEFINE
#define EXAMPLE_DEFINE
// code
#end if
但这产生了与“pragma”相同的结果
由于需要进行大量的代码更改,我不可能手动检查并修复每个错误,特别是因为我希望能够轻松地更新代码库。那么,有没有任何理由可以证明这个设备没有失败,我如何才能让模拟器构建以同样的方式运行呢
编辑:我也使用#import而不是#include进行了测试,但它也产生了相同的结果
编辑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)
下面是一个有问题的文件(AlertView.hh):
#pragma一次
#包括
#包括
#包括
#包括
#包括
类AlertView:公共视图
{
公众:
constexpr AlertView(){}
Rect2实验室框架;
Gfx::文本;
BaseMenuView菜单;
rect2rect;
Rect2&viewRect(){return rect;}
void init(常量字符*标签,菜单项**菜单项,bool highlightFirst);
void deinit()覆盖;
无效位置()覆盖;
无效输入事件(常量输入::事件&e)覆盖;
无效绘制(Gfx::FrameTimeBase frameTime)覆盖;
};
类YesNoAlertView:公共AlertView
{
公众:
YesNoAlertView(){}
typedef DelegateFunc InputDelegate;
MenuItem*MenuItem[2]={nullptr};
//可选代表
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(选项1?选项1:“是”);菜单项[0]=&yes;
no.init(选项2?选项2:“否”);菜单项[1]=&no;
断言(!onYesD);
断言(!onNoD);
AlertView::init(标签、菜单项、highlightFirst);
}
void deinit()重写
{
logMsg(“脱硝警报”);
AlertView::deinit();
onYesD={};
onNoD={};
}
输入和输出;
输入代理onNoD;
私人:
text菜单项是
{
[this](TextMenuItem&,const Input::Event&e)
{
自动回调=onYesD;
removeModalView();
if(回调)回调(e);
}
};
文本菜单项编号
{
[this](TextMenuItem&,const Input::Event&e)
{
自动回调=onNoD;
removeModalView();
if(回调)回调(e);
}
};
};
这表明您已经尝试了头部防护装置,但我的建议是,一旦您检查以下内容
链接
更新显示符号的链接器错误,这是您正在使用的库的错误 请发布显示重复的生成日志。好的,我已经用生成日志和有问题的文件更新了问题。这里没有任何内容似乎有任何效果。检查您定义的类名是否存在于其他任何地方。
#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);
}
};
};