2011-03-04 61 views
5

我有一個在多個平臺上編譯的項目... Windows,Unix,Linux,SCO,命名你的風格。在C++編譯時檢索輸出目標名稱字符串

我想將輸出目標的名稱填充到項目源代碼(輸出程序的名稱,DLL,SO庫或其他)中的變量中,以便我可以在消息中將它用作通用方法來引用組件名稱是它在Windows上的一個EXE,一個DLL,在Unix上的一個SO庫等。

我在想的是一個像功能 _預處理器鍵,但拉東西的EXE/DLL在Visual C++中的Windows上,然後是GCC中的SO輸出庫。當然,這些可能會是兩種不同的機制,但我想將兩者合併爲一個選項,我可以在我的多平臺代碼中使用這些選項。

因此,一個宏觀的東西或者我可以調用的東西,至少在編譯過程中選擇Windows輸出文件名(Visual C++),所以我可以將它推入代碼中的一個常量字符串中,並且可能是一種方法在GCC中也是這樣,所以這兩個平臺可以被包裝成一個抽象。最好不要在運行時拾取,但在編譯期間捕獲並保留。

如果輸出是一個庫,那麼它的lib文件名。如果它是一個組件,那麼輸出組件文件名。

我希望Boost或Poco必須有這樣的東西,可能已經有一些不受支持的端點,這很好。

回答

8

如果在一個項目下一切都在一起,則可以使用預處理器宏。要在Visual Studio中執行此操作,請打開項目屬性並轉到配置屬性> C/C++>預處理器,並將類似PROGRAM_NAME="\"$(ProjectName)\""的內容添加到預處理器定義字段(對應於​​編譯器選項)。

對於GCC,請使用類似的-Dfoo=bar命令行選項。例如,你的Makefile可能是這個樣子:

PROGRAM_NAME = myapplication 
CFLAGS += '-DEXECUTABLE_NAME="$(PROGRAM_NAME)"' 

# Rule to make the executable from the object files 
$(PROGRAM_NAME): $(OBJS) 
    $(LD) $(OBJS) -o [email protected] $(LDFLAGS) 

# Rule to make object files from C source files 
%.o: %.c 
    $(CC) $(CFLAGS) -c $< -o [email protected] 

這允許你的源文件使用宏PROGRAM_NAME,這將擴大到在這種情況下,常量字符串"myapplication"。然而,如果你有被鏈接到多個程序的目標文件(例如你有很多共享庫代碼可以由主程序驅動程序或各種測試套件運行),那麼目標文件可以'不知道他們提前鏈接到哪個可執行文件,所以他們必須在運行時確定它。

在這種情況下,請使用常量全局變量來存儲程序名稱,並使用上述技術在每個可執行文件的主源文件中定義並初始化該變量。

+0

謝謝,我忘記了語法! – psycho 2012-03-08 10:44:00

1

編譯器無法知道這一點。這是分配名稱的鏈接器。我會說你最好的選擇是定義或運行時確定模塊名稱(這不適用於靜態庫)

1

另一個解決方案,有點hacky,將是你的代碼中的const字符串設置爲一個獨特的,容易定位和足夠大的值,並且鏈接完成後找到&用文件的實際名稱覆蓋唯一值你正在操作...