Je viens de penser à une excellente solution à cela qui fonctionne à la fois avec les fichiers source et en-tête, est très efficace et fonctionne au moment de la compilation sur toutes les plates-formes sans extensions spécifiques au compilateur. Cette solution préserve également la structure de répertoires relative de votre projet, afin que vous sachiez dans quel dossier se trouve le fichier, et uniquement par rapport à la racine de votre projet.
L'idée est d'obtenir la taille du répertoire source avec votre outil de construction et de l'ajouter simplement à la __FILE__
macro, en supprimant entièrement le répertoire et en affichant uniquement le nom du fichier commençant à votre répertoire source.
L'exemple suivant est implémenté à l'aide de CMake, mais il n'y a aucune raison qu'il ne fonctionne avec aucun autre outil de construction, car l'astuce est très simple.
Dans le fichier CMakeLists.txt, définissez une macro qui a la longueur du chemin vers votre projet sur 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}")
Sur votre code source, définissez une __FILENAME__
macro qui ajoute simplement la taille du chemin source à la __FILE__
macro:
#define __FILENAME__ (__FILE__ + SOURCE_PATH_SIZE)
Ensuite, utilisez simplement cette nouvelle macro au lieu de la __FILE__
macro. Cela fonctionne car le __FILE__
chemin commencera toujours par le chemin de votre répertoire source CMake. En le supprimant de la __FILE__
chaîne, le préprocesseur se chargera de spécifier le nom de fichier correct et tout sera relatif à la racine de votre projet CMake.
Si vous vous souciez des performances, c'est aussi efficace que d'utiliser __FILE__
, car les deux __FILE__
et SOURCE_PATH_SIZE
sont des constantes de temps de compilation connues, de sorte qu'elles peuvent être optimisées par le compilateur.
Le seul endroit où cela échouerait est si vous l'utilisez sur des fichiers générés et qu'ils se trouvent dans un dossier de construction hors source. Ensuite, vous devrez probablement créer une autre macro en utilisant la CMAKE_BUILD_DIR
variable au lieu de CMAKE_SOURCE_DIR
.