2012-07-11 28 views
3

我有一個C++程序,用於爲我正在執行的夏季項目運行模擬。這是相當計算密集型的,但我已經獲得了使用集羣計算機的資源來運行它的權限,但我測試它並在我自己的筆記本電腦上開發它。這個程序生成文本文件作爲輸出,這是我遇到麻煩的地方。一個源需要在多臺機器上進行不同的編譯

我需要將文本文件保存在不同的路徑中,具體取決於我是在自己的計算機上還是在集羣計算機上運行程序。我現在的解決方案是在我的makefile中使用$(shell hostname)來檢查代碼正在被編譯到哪臺機器上,並根據該輸出使用條件編譯和在makefile中從該操作定義的宏。有一次,我使用了兩種不同版本的頭文件,這些頭文件在我的計算機上對羣集定義了不同的宏,但我使用git存儲庫來回傳輸更改,並且我排除了一個文件喜歡這個。

我只是想知道什麼是最好的做法來設置路徑編譯時在具有相同來源的不同計算機上。

+6

這聽起來不像我需要在不同的機器上進行不同的編譯。這聽起來像是需要在運行時從命令行或某種配置文件中獲取一些路徑。 – 2012-07-11 13:43:51

+0

哦,我從來沒有想過使用配置文件。我會看看我能找到什麼。你碰巧知道設置配置文件有多容易/難嗎?我想過一個命令行參數,但路徑很長,不共享任何子目錄,所以每次我都必須輸出整個路徑......(我知道,我太懶惰了,但是這不是什麼電腦?) – 2012-07-11 13:50:31

回答

3

這聽起來不像我需要在不同的機器上進行不同的編譯。這聽起來像是需要在運行時從命令行或某種配置文件中獲取一些路徑。

一個建議是使用boost program options library,它在一個簡單的設置中允許您從命令行或配置文件中讀取相同的參數。這是我在大集羣或我的筆記本電腦上運行類似工作時使用的工具,它運行良好。

下面是從自己的文件一個簡單的例子:

// Declare the supported options. 
po::options_description desc("Allowed options"); 
desc.add_options() 
    ("help", "produce help message") 
    ("compression", po::value<int>(), "set compression level") 
; 

po::variables_map vm; 
po::store(po::parse_command_line(ac, av, desc), vm); 
po::notify(vm);  

if (vm.count("help")) { 
    cout << desc << "\n"; 
    return 1; 
} 

if (vm.count("compression")) { 
    cout << "Compression level was set to " 
<< vm["compression"].as<int>() << ".\n"; 
} else { 
    cout << "Compression level was not set.\n"; 
} 
+0

感謝您的建議!我見過很多關於提升的內容,但從未嘗試過使用它。它看起來像以標準C++頭文件提供的簡單方式提供了許多重要的功能。 – 2012-07-11 14:05:11

+1

@MilesYucht Boost絕對值得學習。它消除了C++ 11標準庫所要求的恆定的車輪改造。一旦你熟悉它,你會發現自己的工作效率更高。 – 2012-07-11 14:09:47

+0

簡而言之,它似乎處理各種命令行選項,這很好,因爲我已經使用了多個命令行選項。 – 2012-07-11 14:11:13

1

我同意亞歷克斯,最簡單的解決方案不會在編譯時,但在運行時通過配置文件或命令行參數。所有其他的事情是平等的,你可能會更容易嘗試通過命令行參數使用argvargc傳遞它。

+0

我有一個關於配置文件的唯一問題是這樣的:我使用了一個有兩個分支的git倉庫。一個分支(master)包含可以在兩臺計算機之間共享的源/其他信息,另一個分支包含實際構建和運行程序(在本例中爲配置文件)的附加信息。我只把主人推到回購。但是,我希望能夠在這兩個分支之間進行合併,同時從主設備中排除此配置文件。我該如何解決它?這是我想要使用合併驅動程序的情況嗎? – 2012-07-11 13:55:41

0

如果你能忍受在QtCore(750K和4MB庫取決於編譯選項和平臺之間)的依賴,你可以使用QSettings方便存儲目錄路徑,而不必每次都設置目錄路徑。您可以在運行時在命令行上將它傳遞一次並讓程序將結果存儲到設置文件中,然後該設置將成爲未經命令行參數調用程序的新默認值。

其他無依賴替代方案將涉及編寫自己的配置文件解析例程或使用現有的配置文件,但我總是喜歡依賴經過良好測試的開源代碼。

祝你好運!

+0

我認爲如果將來我會寫更多使用Qt的東西,但是現在我想我可以像Justin和Alex建議的那樣去閱讀我自己的配置文件。雖然謝謝! – 2012-07-11 14:08:02

1

我對此並不是很有經驗,但我可以想到一個簡單的方法。

設置一個環境變量,指向每臺機器上的相應目錄, 並在makefile中使用該環境變量。

例如,

在機器1的〜/。在.bashrc

export MY_DIRECTORY = ~/Foo 

在機器2的〜/ .bashrc中

export MY_DIRECTORY = ~/Bar 

你的Makefile將使用它的機器上運行的環境變量。例如, $(MY_DIRECTORY) 並且(〜/ .bashrc不是您的存儲庫的一部分,因此兩臺機器上可能存在不同的副本)

+0

這是一個非常聰明的想法,它似乎應該工作。這不像我目前版本的代碼不起作用,但我想知道什麼是最佳實踐,而不是如何才能簡單地實現它。雖然謝謝! – 2012-07-11 14:24:19

0

您可以繼續使用單獨標題的路由。在你的Git存儲庫中包含這兩個文件,分別爲clusterHeader.hlaptopHeader.h,並使用你現有的Makefile腳本在每個系統上使用不同的頭文件來構建。爲了簡化鏈接問題,可能會在構建腳本時將腳本中的文件從clusterHeader.hpplaptopHeader.hpp臨時重命名或複製到普通的舊header.h,並在腳本末尾更改名稱。

如果你想保持你的頭文件在兩個版本之間保持一致,在你的操作系統無關頭文件中使用這個方法作爲另一個頭文件和#include這個頭文件。

source.cpp 
| 
-> header.hpp 
    | 
    -> clusterHeader.hpp OR laptopHeader.hpp 

另外,只要系統不完全一樣的操作系統(這我假設他們不是因爲一個是集羣),你很可能很容易得到它使用一些簡單的#ifdef語句。

最後,CMake或qmake總是選項。

相關問題