8

Qui è la mia struttura di cartelle:VS2008: Posso creare un progetto con 2 file CPP con lo stesso nome in diverse cartelle?

/ 
| 
-- program.cpp 
-- utility.h 
-- utility.cpp 
| 
-- module/ 
    | 
    -- utility.h 
    -- utility.cpp 

// Note that I have two files named utility.h and two named utility.cpp 

sulla costruzione del progetto, ottengo un errore di collegamento (LNK2028: Token irrisolto e così via ...), dicendo che alcuni simboli non sono definiti. Ho confermato che tutti i simboli sono definiti e che tutte le funzioni dichiarate hanno una definizione corrispondente.

Ho la sensazione che nella compilazione del mio progetto, i file utility.cpp da entrambe le cartelle siano compilati nello stesso utility.obj nella cartella di output. Di conseguenza, uno sovrascrive l'altro.

  1. È questo comportamento previsto?
  2. Come faccio a creare un binario C++ che ha due file con lo stesso nome (anche se in diverse cartelle)?
+0

quello che stai cercando sono spazi dei nomi –

+4

@fuzzy: questo non ha nulla a che fare con i namespace. Solo uno dei 2 file .obj viene inserito nella fase di collegamento. –

+1

@fuzzy: Diciamo che il primo 'utility.cpp' da compilare definisce tutto sotto namespace' foo_ns' e il secondo 'utilty.cpp' da compilare compila tutto sotto namespace' bar_ns', il compilatore sovrascrive 'utility.obj' quando compilando il secondo 'utility.cpp' ... nel momento in cui il linker si attiva, solo' bar_ns' è disponibile nel file obj. –

risposta

12

Fare clic con il pulsante destro del mouse su entrambi i file .cpp>properties>C/C++>Output Files>Object File Name> impostare un nome personalizzato. per esempio. se entrambi i file sono denominati MyFile.cpp nella cartella A e un altro nella cartella B, è possibile impostare l'uscita di essere AMyFile e BMyFile.

In alternativa, è anche possibile utilizzare una macro per aggiungere come prefisso i nomi degli oggetti al nome della cartella principale (ad esempio utilizzando $(IntDir)\$(SafeParentName)$(SafeInputName)). Se questo non è sufficiente (per esempio avete A/B/MyFile.cpp e C/B/MyFile.cpp) e non vi occupate di avere alcuni file oggetto che ingombrano il vostro albero dei sorgenti, si possono anche utilizzare $(InputDir)\ che metterà i file oggetto nella stessa cartella del file di origine.

i file cpp verranno quindi compilati in due diversi file oggetto.

buon divertimento!

Aggiornamento per VS2010: Esiste una soluzione migliore in VS2010, verificarlo here. Grazie a n1ck's comment

btw, se i contenuti hanno lo stesso nome, li si separano utilizzando spazi dei nomi diversi?

namespace A { // in folder A 
    class CMyFile {}; 
}; 

namespace B{ // in folder B 
    class CMyFile {}; 
}; 

// client.cpp 
#include "A/MyFile.h" 
#include "B/MyFile.h" 
int main() { 
    A::CMyFile aMyFile; 
    B::CMyFile bMyFile; 
    return 0; 
} 

Non so se è importante ma è sicuramente più chiaro umana: D

+0

Questa è la soluzione, ma attenzione, per qualche motivo i nomi diversi per il file .cpp e il file obj rallentano notevolmente il ciclo di compilazione/collegamento. Non ho idea del perché. –

+0

Questo * dovrebbe * funzionare e * dovrebbe * essere la soluzione, ma non ha funzionato per me. VS creerebbe entrambi i file .obj ma proverebbe a collegarsi solo in uno di essi. –

+0

Lo riprendo: ricaricare la soluzione sembrava far funzionare questa tecnica (come dovrebbe). +1. VS è irritante per me stamattina per qualche motivo. –

2

Si potrebbe provare ad aggiungere un altro progetto alla soluzione, che compila un file statico mudule.lib da .cpp.h, quindi collegare il progetto principale del modulo con quella lib. Dovrebbe fare in modo che VS emetta i file .obj in una directory separata e dovresti essere in grado di collegarti senza problemi.

0

Forse le librerie (statiche o dinamiche) potrebbero aiutare nel tuo caso. Ma avrai ancora problemi se ci sono simboli pubblici con lo stesso nome come nell'eseguibile o in un'altra libreria.

0

Non conosco la catena di compilazione VS.

Tuttavia, ogni cpp viene prima compilato in un file obj. I passaggi di collegamento li uniscono insieme.

è molto comune, per mettere tutti i file obj in una stessa directory. Quindi, come hai intuito, quando compila il secondo, cancella il primo. Quindi alcuni simboli mancano durante la compilazione.

probabilmente C'è un'opzione (ancora una volta, io non lavoro con VS) per uscire dalla .obj nella stessa directory del file cpp. Lo svantaggio è un po 'di spazzatura nell'albero del codice sorgente.

Il mio parere personale sarebbe quello di refactoring.

1

Vuoi davvero due file diversi ma con lo stesso nome nello stesso progetto?

+4

Sicuro. 'Utility.h' e' utility.cpp' nella sottocartella aggiungono funzionalità specifiche per la funzione implementata in quella cartella. –

+4

Spesso non si ha scelta se si includono altre utilità nella build. –

1

La cosa più semplice che funziona bene è mettere il .objs contrastanti in diverse sottocartelle (ho usato questa tecnica con 2003 e 2008) in base alle directory di origine.

Ad esempio: "\ Debug \ gui /"

Per src \ GUI \ utils.cpp set "Nome oggetto File" per e per src \ database \ utils.cpp impostato su" \. Debug \ database /".

Mentre lo faccio manualmente ogni volta che vedo un conflitto, posso immaginare che scrivere uno script che aggiorni il progetto per ogni file .cpp (o solo per quelli in conflitto) sarebbe un compito piuttosto banale.

Problemi correlati