2010-04-07 18 views
14

Il mio progetto Xcode si basa su varianti dello stesso prodotto utilizzando due target. La differenza tra i due è solo su quale versione di una libreria inclusa viene utilizzata. Per i file sorgente .c è facile assegnare la versione corretta alla destinazione corretta usando la casella di controllo target. Tuttavia, incluso il file di intestazione include sempre lo stesso. Questo è corretto per un bersaglio, ma sbagliato per l'altro.controllando quale file di intestazione del progetto Xcode includerà

C'è un modo per controllare quale file di intestazione è incluso da ciascun target?

Qui è la mia gerarchia del file di progetto (che viene replicata in Xcode):

MyProject 
    TheirOldLib 
    theirLib.h 
    theirLib.cpp 
    TheirNewLib 
    theirLib.h 
    theirLib.cpp 
myCode.cpp 

e myCode.cpp fa una cosa come:

#include "theirLib.h" 
… 
somecode() 
{ 
#if OLDVERSION 
    theirOldLibCall(…); 
#else 
    theirNewLibCall(…); 
#endif 
} 

E, naturalmente, mi definisco OLDVERSION per una obiettivo e non per l'altro.

Nota il #include deve essere come mostrato. Entrambi il seguente errore fallire con un file non trovato:

#include "TheirOldLib/theirLib.h" 
#include "TheirNewLib/theirLib.h" 

Quindi non v'è un modo per dire che Xcode theirLib.h da includere per ogni target?

Vincoli:
- i due file di intestazione hanno lo stesso nome. Come ultima risorsa, potrei rinominare uno di loro, ma preferirei evitarlo perché questo porterebbe a un aumento di capelli sulle altre piattaforme.
- dover aggiungere un riferimento alla cartella che racchiude è anche qualcosa che preferisco evitare, perché dovrei farlo due volte con una direttiva di compilazione condizionale.
- Sono libero di modificare il mio progetto come altrimenti ritengo opportuno

Grazie per qualsiasi aiuto.

risposta

21

La parte fondamentale della risposta è utilizzare USE_HEADERMAP = NO come suggerito da Chris in un commento. Ecco i dettagli.

ricetta breve (il check-in Xcode 3.2.2):

  1. aggiungere un'impostazione di generazione personalizzata di USE_HEADERMAP = NO per ogni target interessato. Ecco come:
    1.1. Apri il pannello delle informazioni sulla destinazione nel riquadro "Crea".
    1.2. Apri il menu a comparsa delle azioni in basso a sinistra nella finestra, seleziona "Aggiungi impostazioni definite dall'utente".
    1.3. Nella riga appena aggiunta, impostare la prima colonna ("Impostazione") su USE_HEADERMAP e la seconda colonna ("Valore") su NO.

  2. aggiungere il percorso di inclusione corretto a ciascun target (impostazioni di generazione di destinazione "Percorsi di ricerca intestazione"). Nel mio esempio sarebbe:
    2.1. aggiungi TheirOldLib per target "vecchio"
    2.2.aggiungi TheirNewLib per "nuovo" target

Fase 1 disabilita la funzione di intestazione mappa automatica di Xcode, attraverso il quale qualsiasi file di intestazione incluso nel progetto è direttamente accessibile attraverso il suo nome, qualunque sia il suo percorso effettivo. Quando due intestazioni hanno lo stesso nome, questa caratteristica porta a un'ambiguità irrisolvibile.

Passaggio 2 consente al #include "theirLib.h" di funzionare senza qualificare il nome del percorso effettivo del file di intestazione.

Queste due passi insieme soddisfano i miei due vincoli.

Infine, USE_HEADERMAP è non documentato da Apple, per quanto posso dire. Riempirò una segnalazione di bug per questo, poiché questa impostazione è cruciale in un certo numero di casi, come rivela googling per esso. Segnalato come rdar: // 7840694. Anche sul radar aperta come http://openradar.appspot.com/radar?id=253401

+0

Funziona perfettamente. Grazie. Il poster dovrebbe averlo contrassegnato come Risposta. – SmallChess

+2

Shouldnt nel passaggio 2. essere "Utente Header Percorsi di ricerca" invece di "intestazione Percorsi di ricerca"? come si usa # include "" e non #include <> – Olof

+0

Credo che lei ha ragione. 'Percorsi di ricerca intestazione' funzionano, ma' Percorsi di ricerca intestazione utente 'dovrebbero essere migliori. –

0

Perché non è possibile utilizzare solo percorsi di inclusione diversi in ciascun target?

+2

Se si hanno due intestazioni con lo stesso nome ma percorsi diversi, è necessario impostare USE_HEADERMAP = NO in un'impostazione di compilazione personalizzata in entrambe le destinazioni. – cdespinosa

+0

Neat. Immagino di non aver mai provato. È bello vedere che Mike Ferris sta ancora combattendo contro l'usabilità. –

+0

utilizzando diversi percorsi di inclusione in ogni bersaglio non funziona: includere i file * IN * progetto sono sempre resi accessibili da Xcode senza percorso a tutti. Questo è il motivo per cui il problema si pone in primo luogo: senza alcun percorso per disambiguare, non sembra esserci alcun modo per dire a Xcode quale è il file giusto da includere. Il suggerimento di Chris è di disabilitare quella caratteristica, per invertire uno schema di percorso di inclusione più convenzionale. Scriverò la risposta in dettaglio. –

Problemi correlati