Tôi vừa nghĩ ra một giải pháp tuyệt vời cho việc này hoạt động với cả tệp nguồn và tệp tiêu đề, rất hiệu quả và hoạt động trên thời gian biên dịch trong tất cả các nền tảng mà không cần các tiện ích mở rộng dành riêng cho trình biên dịch. Giải pháp này cũng bảo tồn cấu trúc thư mục tương đối của dự án của bạn, vì vậy bạn biết tệp nằm trong thư mục nào và chỉ liên quan đến thư mục gốc của dự án.
Ý tưởng là lấy kích thước của thư mục nguồn bằng công cụ xây dựng của bạn và chỉ cần thêm nó vào __FILE__
macro, loại bỏ hoàn toàn thư mục và chỉ hiển thị tên tệp bắt đầu từ thư mục nguồn của bạn.
Ví dụ sau được triển khai bằng CMake, nhưng không có lý do gì nó không hoạt động với bất kỳ công cụ xây dựng nào khác, vì thủ thuật này rất đơn giản.
Trên tệp CMakeLists.txt, xác định một macro có độ dài đường dẫn đến dự án của bạn trên 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}")
Trên mã nguồn của bạn, xác định một __FILENAME__
macro chỉ thêm kích thước đường dẫn nguồn vào __FILE__
macro:
#define __FILENAME__ (__FILE__ + SOURCE_PATH_SIZE)
Sau đó, chỉ cần sử dụng macro mới này thay vì __FILE__
macro. Điều này hoạt động vì __FILE__
đường dẫn sẽ luôn bắt đầu với đường dẫn đến thư mục nguồn CMake của bạn. Bằng cách loại bỏ nó khỏi __FILE__
chuỗi, bộ xử lý trước sẽ đảm nhiệm việc chỉ định tên tệp chính xác và tất cả sẽ liên quan đến thư mục gốc của dự án CMake của bạn.
Nếu bạn quan tâm đến hiệu suất, điều này cũng hiệu quả như việc sử dụng __FILE__
, bởi vì cả hai __FILE__
và SOURCE_PATH_SIZE
được biết là hằng số thời gian biên dịch, do đó nó có thể được tối ưu hóa bởi trình biên dịch.
Nơi duy nhất thất bại là nếu bạn đang sử dụng tệp này trên các tệp được tạo và chúng nằm trong thư mục xây dựng ngoài nguồn. Sau đó, có lẽ bạn sẽ phải tạo một macro khác bằng cách sử dụng CMAKE_BUILD_DIR
biến thay vì CMAKE_SOURCE_DIR
.