Ho appena pensato a un'ottima soluzione che funziona sia con i file sorgente che con quelli di intestazione, è molto efficiente e funziona in fase di compilazione su tutte le piattaforme senza estensioni specifiche del compilatore. Questa soluzione conserva anche la relativa struttura di directory del progetto, in modo da sapere in quale cartella si trova il file e solo relativamente alla radice del progetto.
L'idea è di ottenere le dimensioni della directory di origine con lo strumento di compilazione e di aggiungerla alla __FILE__
macro, rimuovendo completamente la directory e mostrando solo il nome del file a partire dalla directory di origine.
L'esempio seguente è implementato usando CMake, ma non c'è motivo per cui non funzionerebbe con nessun altro strumento di compilazione, perché il trucco è molto semplice.
Nel file CMakeLists.txt, definire una macro che abbia la lunghezza del percorso del progetto su CMake:
# The additional / is important to remove the last character from the path.
# Note that it does not matter if the OS uses / or \, because we are only
# saving the path size.
string(LENGTH "${CMAKE_SOURCE_DIR}/" SOURCE_PATH_SIZE)
add_definitions("-DSOURCE_PATH_SIZE=${SOURCE_PATH_SIZE}")
Sul tuo codice sorgente, definisci una __FILENAME__
macro che aggiunge semplicemente la dimensione del percorso di origine alla __FILE__
macro:
#define __FILENAME__ (__FILE__ + SOURCE_PATH_SIZE)
Quindi usa questa nuova macro anziché la __FILE__
macro. Questo funziona perché il __FILE__
percorso inizierà sempre con il percorso della directory dei sorgenti di CMake. Rimuovendolo dalla __FILE__
stringa, il preprocessore si occuperà di specificare il nome file corretto e sarà tutto relativo alla radice del progetto CMake.
Se ti preoccupi delle prestazioni, questo è efficiente quanto l'utilizzo __FILE__
, perché entrambi __FILE__
e SOURCE_PATH_SIZE
sono noti costanti di tempo di compilazione, quindi può essere ottimizzato dal compilatore.
L'unico posto in cui ciò fallirebbe se lo si utilizza su file generati e si trovano in una cartella di build off-source. Quindi probabilmente dovrai creare un'altra macro usando la CMAKE_BUILD_DIR
variabile anziché CMAKE_SOURCE_DIR
.