Символы не найдены для архитектуры i386 — но работает для устройства iOS

Я сталкиваюсь со странной проблемой здесь, я пытаюсь интегрировать исходники проекта libkml C ++ в мой проект iOS. Проект компилируется независимо нормально, но когда дело доходит до линковки через эту строку кода:

kmldom::PointPtr appPoint = kmlconvenience::CreatePointLatLon(appLocation.coordinate.latitude, appLocation.coordinate.longitude);

Я получаю ошибки компоновщика Только когда я строю это для симулятора. Он прекрасно работает, когда я создаю его для устройства iOS, но для симулятора я получаю следующие 3 ошибки компоновщика:

(null): "kmldom::GxTimeSpan::GxTimeSpan()", referenced from:

(null): Kmldom::KmlFactory::CreateGxTimeSpan() const in libLibKML.a(kml_factory.o)

(null): "kmldom::GxTimeStamp::GxTimeStamp()", referenced from:

(null): Kmldom::KmlFactory::CreateGxTimeStamp() const in libLibKML.a(kml_factory.o)

(null): Symbol(s) not found for architecture i386

(null): Linker command failed with exit code 1 (use -v to see invocation)

Эти ошибки возникают только при попытке собрать для симулятора

Я мог бы хорошо с разработкой для одного устройства, но я пытаюсь решить эту проблему по 2 причинам:

  1. Было бы легко для команды использовать симулятор время от времени для целей разработки.
  2. Я действительно хочу докопаться до сути и понять, почему это происходит в первом случае. Почему он строит для устройства и терпит неудачу для симулятора хотя цель одна и та же, а исходные файлы, включенные в цель, будут одинаковыми для симулятора и устройства.?.

Определение классов GXTimeStamp и GXTimeSpan находится в заголовочном файле gx_timeprimitive.h, и это содержимое:

#ifndef KML_DOM_GX_TIMEPRIMITIVE_H__
#define KML_DOM_GX_TIMEPRIMITIVE_H__

#include <string>
#include "kml/base/xml_namespaces.h"#include "kml/dom/kml22.h"#include "kml/dom/object.h"#include "kml/dom/timeprimitive.h"
namespace kmldom {

class Serializer;
class Visitor;

// <gx:TimeSpan>
class GxTimeSpan : public TimeSpan {
public:
virtual ~GxTimeSpan();
static KmlDomType ElementType() {
return Type_GxTimeSpan;
}
virtual KmlDomType Type() const { return Type_GxTimeSpan; }
virtual bool IsA(KmlDomType type) const {
return type == Type_GxTimeSpan || TimeSpan::IsA(type);
}

// Visitor API methods, see visitor.h.
virtual void Accept(Visitor* visitor);

private:
friend class KmlFactory;
GxTimeSpan();
LIBKML_DISALLOW_EVIL_CONSTRUCTORS(GxTimeSpan);
};

// <gx:TimeStamp>
class GxTimeStamp : public TimeStamp {
public:
virtual ~GxTimeStamp();
static KmlDomType ElementType() {
return Type_GxTimeStamp;
}
virtual KmlDomType Type() const { return Type_GxTimeStamp; }
virtual bool IsA(KmlDomType type) const {
return type == Type_GxTimeStamp || TimeStamp::IsA(type);
}

// Visitor API methods, see visitor.h.
virtual void Accept(Visitor* visitor);

private:
friend class KmlFactory;
GxTimeStamp();
LIBKML_DISALLOW_EVIL_CONSTRUCTORS(GxTimeStamp);
};

}  // end namespace kmldom

#endif  // KML_DOM_GX_TIMEPRIMITIVE_H__

Я прочитал много сообщений, что ошибки компоновщика происходят, потому что исходные файлы не скомпилированы. Я тоже думал об этом, чтобы решить эту проблему, но я не могу включить этот заголовочный файл в исходники компиляции, потому что это файл .h.

Также я дважды проверил — файл kml_factory.cc включен в исходники компиляции внутреннего проекта:

Файл kml_factory.cc включен в фазу компиляции

Ждем предложений и помощи. Благодарю.

5

Решение

Я чувствую себя глупо, когда говорю это, но я не знаю, как отсутствовал файл gx_timeprimitive.cc. У меня сложилось впечатление, что файл gx_timeprimitive.h был завершен сам по себе, так как в нем есть виртуальные классы, и я попытался определить классы GXTimeSpan и GXTimeStamp, предоставив пустую реализацию конструкторов в частной области видимости, например:

class GxTimeSpan : public TimeSpan {
public:
virtual ~GxTimeSpan();
static KmlDomType ElementType() {
return Type_GxTimeSpan;
}
virtual KmlDomType Type() const { return Type_GxTimeSpan; }
virtual bool IsA(KmlDomType type) const {
return type == Type_GxTimeSpan || TimeSpan::IsA(type);
}

// Visitor API methods, see visitor.h.
virtual void Accept(Visitor* visitor);

private:
friend class KmlFactory;
GxTimeSpan()
{

}
LIBKML_DISALLOW_EVIL_CONSTRUCTORS(GxTimeSpan);
};

Но все же компилятор не будет создавать объектный файл из интерфейсных файлов (файлы .h исключаются из исходников компиляции, они просто содержат все объявления), поэтому компоновщик не может найти нужные конструкторы. Это заставило меня искать файл gx_timeprimitive.cc в интернете, и он действительно был доступен.

Мышление с хладнокровием сэкономило бы мне 100 баллов, но у меня есть урок!

Кроме того, чтобы ответить, почему он выдавал ошибку только в режиме симулятора:
На самом деле строка, которую я упомянул выше —
kmldom::PointPtr appPoint = kmlconvenience::CreatePointLatLon(appLocation.coordinate.latitude, appLocation.coordinate.longitude);
при сборке для ARMv7, я думаю, что если переменная appPoint используется в другом месте кода, который пропускает компоновщик, связывая его с источниками объектного файла libkml. Принимая во внимание, что i386 будет выполнять связывание независимо от того, используется ли переменная в коде или нет. Я предполагаю, что это какая-то оптимизация компилятора, из-за которой поведение в разных архитектурах отличается. Именно эта головоломка заставила меня упустить ключевой момент поиска пропавшего файла!

Извинения за тех, кто нашел время, чтобы решить эту мою глупую проблему, спасибо всем.

3

Другие решения

Это может быть что-то похожее на Символы iOS не найдены для архитектуры i386.

Вот наиболее важные моменты:

При создании библиотек, каркасов или приложений для iOS XCode будет компилировать объектный код только для архитектур, указанных в настройках сборки для целевого объекта. XCode также будет ссылаться только на двоичные файлы, в которые встроена указанная архитектура.

При запуске кода в симуляторе iOS вы запускаете код на рабочем столе, который является архитектурой i386.

Если вы получаете ошибку отсутствующей архитектуры i386 при запуске приложения iOS в симуляторе, вам необходимо убедиться, что ваше приложение и все его зависимые библиотеки созданы для архитектуры i386.

2