c/c++のマクロ __FILE__ から、ディレクトリ名を取り除いて、ファイル名だけ(basenameだけ)にする方法です。
stackoverflow にいろんな方法が掲載されていたので、要点だけまとめます。
https://stackoverflow.com/questions/8487986/file-macro-shows-full-path
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__)
コンパイラが最適化してくれるなら実害は少ないでしょうが、最適化されない場合は毎回 文字列処理の関数がコールされます。この手の方法は却下でしょう。
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 でコンパイルするのはビルド時間が長くなりそうなので個人的には却下です。