2009-10-20 23 views
5

Các macro __FILE____LINE__ được tích hợp vào Bộ xử lý trước C và thường được sử dụng để in đầu ra gỡ lỗi với tên tệp và số dòng. Tôi cần một cái gì đó tương tự, nhưng chỉ với tên của thư mục ở cuối con đường. Ví dụ: nếu mã của tôi là: /home/davidc/some/path/to/some/code/foo/bar Tôi cần macro sẽ chỉ cung cấp cho tôi "thanh", nếu mã nằm trong/home/davidc/một số/con đường/đến/một số/code/foo/ong sau đó tôi cần nó để cho tôi "ong".Làm cách nào để viết macro cpp __DIR__, tương tự như __FILE__

Mọi suy nghĩ? (btw, đây là một ứng dụng C++).

Cập nhật: để rõ ràng, tôi sau một macro sẽ cho tôi một chuỗi có chứa tên thư mục tại thời gian biên dịch, tôi không muốn thực hiện bất kỳ xử lý chuỗi nào khi chạy.

Trả lời

6

Nếu bạn đang sử dụng GNU make để xây dựng dự án của bạn, sau đó bạn có thể có thể làm điều gì đó như thế này:

%.o: %.cpp 
    $(CC) $(CFLAGS) -D__DIR__="$(strip $(lastword $(subst /, , $(dir $(abspath $<)))))" -c $< -o [email protected] 

Đó có phải về nhất Thiên Chúa khủng khiếp điều mà tôi đã nghĩ về việc làm trong một Makefile trong một thời gian dài. Tôi không nghĩ rằng bạn sẽ tìm thấy một cách nhanh chóng hoặc sạch sẽ để làm điều này trong giới hạn của trình biên dịch vì vậy tôi sẽ tìm cách thông minh để tiêm các thông tin vào quá trình biên dịch.

Chúc may mắn.

+0

D'oh, bạn đã đánh bại tôi một phút - tôi đã làm khá nhiều điều tương tự. Nó không hoàn toàn hoạt động nếu thư mục cuối cùng có không gian trong đó, nhưng nếu không thì đó là một giải pháp hoàn hảo. Và hãy tin tôi - Tôi đã thấy * xa hơn * những quái dị tồi tệ hơn trong Makefiles trước đây. –

+0

@Adam: Tôi chỉ phải thực hiện một số _fixups_ để nhận được số phiên bản bắt đầu bằng số 0 tối nay. Đi từ 07.64 đến 08.01 đã khiến chúng tôi rất đau buồn. –

+0

Tôi đang sử dụng CMake, vì vậy tôi có thể làm điều này. Cảm ơn! –

4

Không có macro dựng sẵn cho điều đó, nhưng rõ ràng bạn có thể viết thói quen phân tích cú pháp nhỏ của riêng bạn để lấy tệp và tách tên thư mục cho một tên tệp đầy đủ nhất định. Cho phép gọi hàm này:

extern std::string parseLastDir (const char *path); 

Sau đó, bạn có thể làm cho một macro như thế này:

#define __DIR__ parseLastDir (__FILE__) 

mà sẽ loại cư xử như những gì bạn muốn (nó mang lại cho bạn một std :: string thay vì một char * để làm sạch được xác định tốt hơn) với ngữ nghĩa có liên quan (kết quả của nó phụ thuộc vào tập tin trong đó nó được gọi, để nó luôn luôn được đúng thư mục.)

+0

vấn đề là tôi muốn 'parseLastDir' diễn ra vào thời gian biên dịch (Không có lý do gì không thể, vì __FILE__ được xác định trước). Tôi đã suy nghĩ có lẽ một cái gì đó trong tăng :: mpl hoặc một số khác mẫu siêu lập trình meta trong một vĩ mô có thể cho tôi làm điều đó .. Nó cho một ứng dụng khá hiệu suất quan trọng, và tôi không muốn lãng phí thời gian làm chuỗi không cần thiết xử lý trong thời gian chạy. –

+0

woops, quên về markdown mà phải là \ __ FILE__, không __FILE__ –

+1

Vấn đề là với thời gian biên dịch truy cập vào chuỗi chữ - đó là không thể bây giờ. Có vẻ như chúng tôi sẽ có quá trình xử lý chuỗi thời gian biên dịch bằng C++ 1x. –

2

Những gì bạn muốn là một cái gì đó tương tự như unix

__BASE_FILE__ 

Hãy xem xung quanh http://theory.uwinnipeg.ca/localfiles/infofiles/gcc/cpp_13.html để biết. Tôi hi vọng cái này giúp được.

EDIT: Cố gắng Hai

Làm thế nào về cách sử dụng lệnh #line tiền xử lý. Bạn có thể sử dụng nó để thay đổi tên tập tin quá như bạn có thể thấy ở đây: http://www.cppreference.com/wiki/preprocessor/line

+1

Đóng, nhưng không có xì gà. Điều đó cung cấp cho tên tệp/đường dẫn được chuyển vào g ++, vì vậy nó sẽ tắt một số phần trước của đường dẫn, nhưng không cung cấp cho tôi thư mục cuối cùng như tôi muốn (vì mã của tôi nằm trong một thư mục con) , vì vậy bây giờ tôi chỉ nhận được foo/bar thay vì/home/davidc/some/path/thành/some/code/foo/bar, đóng nhưng tiếc là vẫn còn cùng một vấn đề. –

+0

Chết tiệt, rất gần. Tôi sẽ tiếp tục tìm kiếm. –

2

Tùy thuộc vào trình biên dịch của bạn/cách phần mềm của bạn được xây dựng, bạn có thể khai báo macro là đường dẫn hiện tại hoặc bất kỳ khi nào bạn biên dịch.

gcc -D__DIR__=/usr/src/test/ test.c 

Tôi chưa từng sử dụng trình biên dịch MS nhưng tôi biết có tùy chọn tương tự cho ICC.

gcc manpage

+0

Cảm ơn, nhưng đó không phải là những gì tôi theo sau. Tôi đang biên soạn một dự án lớn với hàng trăm tệp trong các thư mục khác nhau, ý tưởng là mỗi tệp có thể #include macro này và nó sẽ trả về tên thư mục tương ứng với vị trí tệp nguồn riêng của nó, tôi không muốn 'khó mã 'đường dẫn đến bất kỳ nơi nào cụ thể. –

+0

oh và vâng tôi đang sử dụng g + + trên Linux –

0

Làm thế nào về việc thay đổi makefile của bạn/xây dựng hệ thống để cho .../bar/file.cc dòng biên soạn sẽ bao gồm -D__DIR__ bar. Nó sẽ được dễ dàng hơn ...

Các vấn đề liên quan