2009-10-20 80 views
5

__FILE____LINE__宏內置到Ç預處理器,並經常用於打印調試輸出與文件名和行號。我需要類似的東西,但只需要路徑末尾的目錄名稱。例如,如果我的代碼位於: /home/davidc/some/path/to/some/code/foo/bar我需要一個只會給我「bar」的宏,如果代碼位於/ home/davidc/some/path/to/some/code/foo/bee然後我需要它給我「蜜蜂」。我怎樣寫一個CPP __DIR__宏,類似於__FILE__

有什麼想法? (順便說一句,這是一個C++應用程序)。

更新:要清楚,我在一個宏後,將在編譯時給我一個包含目錄名稱的字符串,我不想在運行時做任何字符串處理。

回答

6

如果您正在使用GNU make構建項目,那麼你也許能夠做這樣的事情:

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

那必須是對最神可怕我曾經想過在一段時間內在Makefile中做的事情。我認爲你不會在編譯器的範圍內找到一個快速或乾淨的方法來實現這一點,所以我會尋找聰明的方法將信息注入編譯過程。

祝你好運。

+0

「哦,你打了我一分鐘 - 我做的事情幾乎完全一樣。如果最後一個目錄中有空格,它就不起作用,否則它是一個完美的解決方案。相信我 - 我以前在Makefiles中看到過*更糟糕的怪物。 – 2009-10-20 01:40:41

+0

@Adam:我只需要做一些_fixups_來解決版本號從今晚的零開始。從07.64到08.01導致我們有很多不必要的悲傷。 – 2009-10-20 02:08:21

+0

我使用CMake,所以我應該能夠做到這一點。謝謝! – 2009-10-20 23:07:35

4

沒有內置的宏,但顯然你可以編寫自己的小解析例程,它需要一個文件併爲給定的完整PATH文件名撕掉目錄名。讓我們調用這個函數:

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

然後你就可以做出這樣的宏:

#define __DIR__ parseLastDir (__FILE__) 

將排序的行爲像你想要什麼(它給你的std :: string,而不是一個char的*以便更好地定義清理)與相關語義(其結果取決於所調用的文件,以便始終得到正確的目錄)。

+0

事情是,我想'parseLastDir'發生在編譯時(沒有理由不能,因爲__FILE__是預先確定的)。我在想,也許在boost :: mpl或其他一些hacky模板metaprogramming中的一些宏可能會讓我這樣做.. 這是一個相當性能苛刻的應用程序,我不想浪費時間做不必要的字符串在運行時處理。 – 2009-10-20 00:39:55

+0

woops,忘記降價 應該是\ __ FILE__,而不是__FILE__ – 2009-10-20 00:40:42

+1

問題是編譯時訪問字符串文字 - 這是不可能的。看起來我們將在C++ 1x中進行編譯時字符串處理。 – 2009-10-20 00:44:01

2

你想要的是類似於unix的東西

__BASE_FILE__ 

看看http://theory.uwinnipeg.ca/localfiles/infofiles/gcc/cpp_13.html吧。我希望這有幫助。

編輯:嘗試兩個

如何使用預處理的#line命令。您可以使用它來更改文件名變量,如下所示:http://www.cppreference.com/wiki/preprocessor/line

+1

關閉,但沒有雪茄。這使得文件名/路徑被傳遞到g ++中,因此它將路徑的一些早期部分截斷,但是不會給我僅僅最後一個dir(因爲我的代碼位於一堆子目錄中) ,所以現在我只是得到foo/bar而不是/ home/davidc/some/path/to/some/code/foo/bar,關閉但不幸仍然是同樣的問題。 – 2009-10-20 01:00:24

+0

該死的,那麼近。我要繼續尋找。 – 2009-10-20 01:02:46

2

根據您的編譯器/軟件的構建方式,您可以在編譯時聲明當前或任何路徑。

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

我從來沒有使用過MS編譯器,但我知道ICC也有類似的選項。

gcc manpage

+0

謝謝,但那不是我所追求的。我正在編譯一個包含數百個不同目錄的文件的大型項目,這個想法是,每個文件都可以包含這個宏,並且它將返回與它自己的源文件位置相對應的目錄名稱,我不想'代碼「特別是在任何地方的路徑。 – 2009-10-20 00:48:14

+0

哦,是的,我在Linux上使用g ++ – 2009-10-20 00:50:03

0

如何改變你的Makefile /編譯系統,以便爲.../bar/file.cc編譯線將包括-D__DIR__ bar。它應該是更容易...