Я только что подумал об отличном решении, которое работает как с исходными файлами, так и с заголовочными файлами, очень эффективно и работает во время компиляции на всех платформах без специфичных для компилятора расширений. Это решение также сохраняет относительную структуру каталогов вашего проекта, чтобы вы знали, в какой папке находится файл, и только относительно корня вашего проекта.
Идея состоит в том, чтобы получить размер исходного каталога с помощью инструмента сборки и просто добавить его в __FILE__
макрос, полностью удалив каталог и показывая только имя файла, начиная с исходного каталога.
Следующий пример реализован с использованием CMake, но нет никаких причин, по которым он не будет работать с любыми другими инструментами сборки, потому что трюк очень прост.
В файле CMakeLists.txt определите макрос, имеющий длину пути к вашему проекту в 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}")
В исходном коде определите __FILENAME__
макрос, который просто добавляет размер исходного пути к __FILE__
макросу:
#define __FILENAME__ (__FILE__ + SOURCE_PATH_SIZE)
Тогда просто используйте этот новый макрос вместо __FILE__
макроса. Это работает, потому что __FILE__
путь всегда будет начинаться с пути к вашему исходному каталогу CMake. Удалив его из __FILE__
строки, препроцессор позаботится о том, чтобы указать правильное имя файла, и все это будет относиться к корню вашего проекта CMake.
Если вы заботитесь о производительности, это так же эффективно, как использование __FILE__
, потому что оба __FILE__
и SOURCE_PATH_SIZE
являются известными константами времени компиляции, поэтому он может быть оптимизирован компилятором.
Единственное место, где это может потерпеть неудачу, - это если вы используете это в сгенерированных файлах, а они находятся в папке для сборки вне исходного кода. Тогда вам, вероятно, придется создать другой макрос, используя CMAKE_BUILD_DIR
переменную вместо CMAKE_SOURCE_DIR
.