Właśnie wymyśliłem świetne rozwiązanie, które działa zarówno z plikami źródłowymi, jak i nagłówkowymi, jest bardzo wydajne i działa w czasie kompilacji na wszystkich platformach bez rozszerzeń specyficznych dla kompilatora. To rozwiązanie zachowuje również względną strukturę katalogów projektu, dzięki czemu wiesz, w którym folderze znajduje się plik, i tylko w odniesieniu do katalogu głównego projektu.
Chodzi o to, aby uzyskać rozmiar katalogu źródłowego za pomocą narzędzia do budowania i po prostu dodać go do __FILE__
makra, całkowicie usuwając katalog i wyświetlając tylko nazwę pliku, zaczynając od katalogu źródłowego.
Poniższy przykład jest zaimplementowany przy użyciu CMake, ale nie ma powodu, dla którego nie działałby z innymi narzędziami do kompilacji, ponieważ sztuczka jest bardzo prosta.
W pliku CMakeLists.txt zdefiniuj makro, które ma długość ścieżki do twojego projektu na 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}")
W kodzie źródłowym zdefiniuj __FILENAME__
makro, które po prostu dodaje rozmiar ścieżki źródłowej do __FILE__
makra:
#define __FILENAME__ (__FILE__ + SOURCE_PATH_SIZE)
Następnie użyj tego nowego makra zamiast __FILE__
makra. To działa, ponieważ __FILE__
ścieżka zawsze zaczyna się od ścieżki do katalogu źródłowego CMake. Usuwając go z __FILE__
łańcucha, preprocesor zajmie się określeniem poprawnej nazwy pliku i wszystko będzie zależne od katalogu głównego projektu CMake.
Jeśli zależy Ci na wydajności, jest to tak samo wydajne, jak użycie __FILE__
, ponieważ obie __FILE__
i SOURCE_PATH_SIZE
są znanymi stałymi czasu kompilacji, więc kompilator może je zoptymalizować.
Jedynym miejscem, w którym to się nie powiedzie, jest sytuacja, w której używasz tego na wygenerowanych plikach i znajdują się one w folderze kompilacji poza źródłem. Wtedy prawdopodobnie będziesz musiał utworzyć inne makro, używając CMAKE_BUILD_DIR
zmiennej zamiast CMAKE_SOURCE_DIR
.