2013-05-19 10 views
5

Sto affrontando uno strano problema qui, sto cercando di integrare lo libkml C++ project sources nel mio progetto iOS. Il progetto compila autonomamente bene, ma quando si tratta di collegare attraverso questa riga di codice:Simboli non trovati per l'architettura i386 - Ma funziona per il dispositivo iOS

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

ricevo errori del linker Solo quando sto costruendo per simulatore. Funziona bene quando costruire per dispositivi iOS, ma per simulatore di I ottenere gli errori del linker seguenti 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) 

These errors occur only when I try to build for simulator

potevo andare bene con lo sviluppo per il dispositivo da soli, ma sto cercando di risolvere questo problema problema per 2 motivi:

  1. Sarebbe facile per il team utilizzare il simulatore a volte per scopi di sviluppo.
  2. Voglio davvero arrivare fino in fondo e capire perché questo sta accadendo nel primo caso. Perché costruisce per il dispositivo e fallisce per il simulatore sebbene il target sia lo stesso ei file di origine inclusi nella destinazione siano gli stessi per il simulatore e per il dispositivo ?.

La definizione delle classi e GXTimeStamp GXTimeSpan sono nel file di intestazione gx_timeprimitive.h e questo è il contenuto:

#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__ 

Ho letto molti post che si verificano errori del linker coz i file di origine non vengono compilati . Stavo pensando alle stesse linee per risolvere anche questo problema, ma non posso includere questo file di intestazione in fonti compilate perché è un file .h.

Inoltre, ho controllato due volte - il file kml_factory.cc è incluso nelle fonti di compilazione del progetto interno:

kml_factory.cc file included in compile phase

Guardando al futuro per suggerimenti e aiuto. Grazie.

+0

Quale versione di XCode stai usando? –

+0

Sto usando 4.6.2 –

risposta

3

Mi fa sentire stupido a dirlo, ma, non so come mancasse il file gx_timeprimitive.cc. Avevo l'impressione che gx_timeprimitive.file di h era completa di per sé in quanto ha le classi virtuali e ho cercato di definire le classi GXTimeSpan e GXTimeStamp fornendo l'implementazione vuota di costruttori in ambito privato, in questo modo:

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); 
}; 

Ma ancora, il compilatore non creerebbe file oggetto fuori dai file di interfaccia (i file .h sono esclusi dalle fonti compilate, contengono solo tutte le dichiarazioni), quindi il linker non riesce a trovare i costruttori necessari. Questo mi ha fatto cercare il file gx_timeprimitive.cc in internet ed era effettivamente disponibile.

Pensare con la testa fredda mi avrebbe risparmiato 100 punti di taglie, ma ho una lezione da portare!

Inoltre, per rispondere perché stava dando errore nel modo simulato da solo: In realtà la linea che ho citato sopra - kmldom::PointPtr appPoint = kmlconvenience::CreatePointLatLon(appLocation.coordinate.latitude, appLocation.coordinate.longitude); quando costruito per ARMv7, credo, che a meno che la variabile appPoint viene utilizzato in altre parti del codice di linker salta collegandolo con i sorgenti del file oggetto di libkml. Considerando che, i386 eseguirà il collegamento indipendentemente dal fatto che la variabile sia utilizzata nel codice o meno. Immagino che questa sia una sorta di ottimizzazione del compilatore a causa della quale il comportamento è diverso nelle rispettive architetture. E 'stato questo puzzle che mi ha fatto perdere l'indizio cruciale di guardare nel file mancante!

Mi scuso per coloro che hanno avuto il tempo di risolvere questo mio sciocco problema, grazie a tutti.

2

Questo può essere qualcosa di simile a iOS symbols not found for architecture i386.

Ecco i punti più importanti:

Quando si costruisce biblioteche, quadri o le applicazioni per iOS, XCode sarà solo compilare codice oggetto le architetture specificate nelle impostazioni di generazione per il target. XCode si collegherà anche solo ai binari che hanno l'architettura specificata.

Quando si esegue il codice nel simulatore iOS, si esegue il codice sul desktop che è l'architettura i386.

Se si verifica l'errore di architettura i386 mancante nell'esecuzione di un'applicazione iOS nel simulatore, è necessario assicurarsi che l'applicazione e tutte le sue librerie dipendenti siano state create per l'architettura i386.

+0

Ho il codice sorgente libkml incluso nel mio codice, il che significa che la libreria libkml sarà costruita per l'architettura che è stata selezionata prima di costruire il progetto principale. Inoltre, libkml dipende solo da una libreria esterna - la libreria Expat, che ho compilato esternamente e viene creata una grossa libreria che può essere collegata attraverso i386 e ARMv7. Inoltre, la libreria Expat non sta dando problemi qui, come indicato nella mia domanda, il problema è da qualche parte nel codice sorgente delle fonti libkml. Sto ancora cercando di capire cosa c'è che non va, grazie per i tuoi suggerimenti. –

Problemi correlati