__FILE__ からディレクトリ名を削除する方法

c/c++のマクロ __FILE__ から、ディレクトリ名を取り除いて、ファイル名だけ(basenameだけ)にする方法です。

stackoverflow にいろんな方法が掲載されていたので、要点だけまとめます。
https://stackoverflow.com/questions/8487986/file-macro-shows-full-path

gccの場合

GCC 12からは __FILE_NAME__ という定数が使えます

clangの場合

最近のclangでも同様に __FILE_NAME__ という定数が使えます

MSVCの場合(visual studio)

コンパイラオプションで "/d1trimfile" を指定すると __FILE__ が加工できます。

$(SolutionDir)を削除したい場合は

 /d1trimfile:"$(SolutionDir)\":

を指定すればOK

Makefile側で何とかする

CMakeなら

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__FILENAME__='\"$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<))\"'")

CXX_FLAGS+=-D__FILENAME__='\"$(subst $(SOURCE_PREFIX)/,,$(abspath $<))\"'"

で __FILENAME__ が自動生成できるそうです

その他

マクロの中で文字列処理を行う
#include <libgen.h>
#define PRINTFILE() { char buf[] = __FILE__; printf("Filename:  %s\n", basename(buf)); }
#include <string.h>
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)

コンパイラが最適化してくれるなら実害は少ないでしょうが、最適化されない場合は毎回 文字列処理の関数がコールされます。この手の方法は却下でしょう。

GCCの-fmacro-prefix-map=old=new オプションを使う

GCCの場合はコンパイラオプションでマクロを置換できるようです。GCCに依存しすぎなのでこれも却下。

c++11の constexpr を使う
template <typename T, size_t S>
inline constexpr size_t get_file_name_offset(const T (& str)[S], size_t i = S - 1)
{
    return (str[i] == '/' || str[i] == '\\') ? i + 1 : (i > 0 ? get_file_name_offset(str, i - 1) : 0);
}

template <typename T>
inline constexpr size_t get_file_name_offset(T (& str)[1])
{
    return 0;
}

c++11の constexpr で、コンパイル時に文字列を加工する方法です。stackoverflow では「美しい」と称賛している人もいますが、__FILE__はデバッグ用のマクロなどで大量に使用される定数で、それを毎回 constexpr でコンパイルするのはビルド時間が長くなりそうなので個人的には却下です。