把項目從VS2005升級到VS2013

小斯同學花了幾周的時間,終於把我們的服務端和客戶端從vs2005升級到vs2013了。真是不得不給個贊。

升級的過程中遇到了各種問題,小斯同學跋山涉水、越過艱難險阻終於成功讓我們用上了高大上的宇宙第一IDE——vs2013。所以這裏我順帶把他升級中遇到的問題記錄一下,也許對一些朋友是種參考。

首先,需要說明一下,之前在csdn上看到有人提了一個問題:爲什麼好多遊戲都用VS2005開發呢?原帖子在這裏:http://bbs.csdn.net/topics/390645505

下面的回覆也是五花八門。這裏作爲從業人員,我談一下感受,首先用vs2005還是用vs2012甚至vs2013只是一個選擇問題,換句話說,只要願意,我們可以拿什麼亂七八糟的玩意開發都沒問題。

再來說下實際的,爲什麼大多數遊戲公司都用vs2005開發呢?我其實不知道那個樓主說魔獸世界和憤怒的小鳥是用vs2005開發的,但我們的遊戲確實是拿vs2005開發的,而且我知道的一些遊戲公司也確實拿vs2005開發,那麼爲什麼呢?因爲項目就是在那個時候創建的,而那個時候正好手頭上熟悉的開發工具就是vs2005,憤怒的小鳥2009年發行的第一個版本,其開發公司Rovio公司成立於2003年,他們公司之前當然不會打醬油了,所以目測之前我們用的不是vs2005,因爲那個時候還沒有vs2005呢,估計有了vs2005之後,他們公司升級到vs2005作爲開發工具了,而vs2008要等到07年底纔出來,如果他們的程序們不想升級,自然是沒人會去升的,而魔獸世界我們都知道是04年就出了,所以那個時候你總不能說他們的開發工具是vs2005吧。所以魔獸如果真的在用vs2005,那也是之後升級到vs2005的。至於爲什麼不繼續升級到vs2008或者是vs2010、12、13等,我的看法是,沒有需求。公司的目的是盈利,而如果從vs2005升級到vs2013無法提高收益,那麼爲什麼要升級,既然公司不會爲你升級而發獎金或者是工資,自然沒人閒的蛋疼去升級,還要處理一堆的升級之後的問題。

還有一點原因,因爲用戶看到的那個程序並非是由程序員來“控制”用什麼編譯的,當然這裏的控制是打引號的,聽我慢慢解釋,在公司升級開發工具並非跟自己玩玩一樣簡單,首先,一般公司編譯代碼都是配有編譯機的,就是說程序員在自己本地用開發工具來編寫調試代碼之後通過各種版本控制工具,比如svn或者git之類的提交到代碼庫裏,然後由編譯機來編譯出真正的供使用的版本,所以,如果你想升級開發工具就要同時升級自己的開發工具和編譯機的編譯配置,一般而言,公司的編譯機都有專門的人來管理的,也就是所謂的配置管理員之類的職位,他們負責管理編譯機,程序員當然可以在本地用各種開發工具進行開發,只要你能夠保證代碼編譯沒有問題,誰管你是用vs2013開發還是用記事本在寫代碼?但是程序員如果想要控制輸出到外網的版本是用什麼編譯工具來編譯的話,就要說服配置管理員來升級編譯機上的配置,而一般公司而言,這都是不可能的,因爲程序員壓根管不到配置管理員,如果不是項目經理點頭首肯,配置管理員爲什麼要聽你程序員的,而程序員如果要說服項目經理,那麼就要擺出各種厲害關係,比如vs2013如何碉堡(誰管你碉不碉堡)、如何能提高開發效率(尼瑪不升級你效率就低下嗎?)、vs2013能夠給用戶帶來飛一般的體驗(即使你信口開河,項目經理也不一定信)。即使你口才非凡的說服了項目經理,他同意讓公司花一筆錢把新的IDE買下來供大家使用,你還需要說服其他的程序員,因爲你一旦修改了項目的編譯工具,必然要影響到其他程序員的開發,當然我們必須能夠說服其他程序員,讓他們改變開發習慣。總結一下:

1、你需要說服項目經理,讓他申請花費一筆錢購買新的vs
2、你要說服配置管理員,讓他更改編譯機的配置,很有可能你需要幫助他解決新配置下的各種問題,而也許你並不擅長
3、你需要說服別的程序員,讓他們改變開發習慣,適應新的開發工具
4、最後你需要解決你們項目工程由vs2005升級到vs2013的各種詭異bug,保證升級之後你們的用戶不會在使用上有問題。

當然,這是從程序員推動去升級開發工具,如果從項目經理推動的話,就容易的多了,一句話“你們都給我用vs2013開發”,其他的事情自然有人去完成了,程序員要做的不過是安裝一下vs2013罷了。但是有多少項目經理是真正關心程序員拿什麼開發,又或者程序最後拿什麼編譯的呢?呵呵!其實只有程序員關心這些。我相信所有跟我一樣的程序員都是喜歡嘗試新鮮事物的,所以很多情況下,你雖然看到的程序是用vs2005編譯的,實際上我很有可能是用着vs2013在做開發,只不過編譯給你的是vs2005編譯的罷了:)

回到正題,我們項目升級過程中遇到了哪些問題呢?這裏我分別挑幾個顯著的問題說一下:

工程自動轉換
首先vs2013對vs2005的工程是兼容的,也就是說你可以直接用vs2013打開vs2005的工程,當然,vs2013會對vs2005的工程文件做一番轉換。找到vs2005的sln文件,用vs2013打開完成轉換後又日誌報告,一般來說不會有什麼問題,如果你想仔細看也可以,點進去看就是的:

wKiom1NH1f6QnWxKAACfzqMPv2Y091.jpg

wKioL1NH1dbylzfRAAFoM1x5Z7k478.jpg


這裏要注意一點,在轉換sln的時候,我們的vs2013掛掉了,最後我們發現是有一個工程的vcproj文件裏有引號字符的html代碼,這個在vs2005下是可以識別的,但是用vs2013去轉換它的時候卻把vs2013給弄死掉了,去掉就可以了

wKiom1NH1f_yDGtrAAAoYMAxzNY916.jpg


工程設置上的不同
還有一點就是在vs2005和vs2013工程配置裏有好多默認設置居然是不同的,比如輸出目錄,vs2013的路徑最後會添加一個 ‘\’,而vs2005下卻沒有。這個最初看上去沒什麼影響,但是我們的工程自己定義了路徑宏的時候添加了末尾的符號‘\’,導致在vs2013下路徑就多了一個‘\’。

wKioL1NH1gnhbAxUAAGIcNDxhoo681.jpg

wKiom1NH1jPB00qYAAE6IUOhh5U484.jpg


解決方案打開後一般來說各個工程的組織結構不會變動,這個時候不要緊着對整個解決方案進行編譯,建議一個工程一個工程的編譯,這樣解決問題起來比較清晰。

vs2013和vs2005另一個比較大的變化就是VC++的目錄設置,在vs2005裏面這個目錄設置是針對所有工程的總設置,在Tools->Options->Projects and Solutions->VC++ Directories下,而在vs2013裏,這個設置放到了每個工程設置下,在Project->Properties->VC++ Directories下,位置變化到是次要的,問題是vs2013把很多頭文件放到了系統的一個目錄,而且文件內容還發生了變化。

wKiom1NH1krja7BgAAMSh0R7lnU463.jpg

wKioL1NH1iPwnW8sAAHHvIhWoyA605.jpg



系統宏的不同
比如我們用到了一個系統的宏:OutputDebugStr,它在vs2005的頭文件裏定義在vs安裝目錄下的平臺sdk目錄下的mmsysytem.h,而到vs2013下這個文件被放到了系統目錄的sdk下,而且這個宏的定義還消失了。

wKiom1NH1mPzSPq3AAHO6Hd9y1U685.jpg

wKioL1NH1jrgARRCAACdcWQmWhE333.jpg

wKiom1NH1mOi3bOxAAB93pLQYVs869.jpg


解決辦法也比較簡單,在工程的預編譯文件裏添加一下這個宏的定義,注意兼容vs2005和vs2013版本就行:

#ifndef OutputDebugStr
#define OutputDebugStr OutputDebugString
#endif


其他未定義宏的解決方案也類似。只有有一類屬於宏的定義值本身就不同,比如,我們遇到這麼一個問題:
wKioL1NH1nCwnSIWAAA6bUgWfYs105.jpg

這個變量是定義在wingdi.h文件中的,但是在vs2013新的sdk下和vs2005的windows的sdk下這兩個定義是不一致的,vs2005下是這麼定義的:
wKioL1NH1omTyBhqAAA3IT-BVQA312.jpg

vs2013下是這麼定義的:

wKiom1NH1saQRAo9AABZ3cVGzEQ175.jpg

wKioL1NH1p6BEhlJAADLX6zcNXo140.jpg


目前我們的解決方案只是重新定義一下這個宏:

#if (_WIN32_WINNT >= _WIN32_WINNT_WINXP)
#define CLEARTYPE_QUALITY 5
#endif


事實上,vs2013下windows的SDK版本和vs2005自帶的SDK版本是有區別的,vs2013的SDK版本是0x0603,而vs2005的版本是0x0500。所以會有一批這種問題出現,其實你可以直接把這個版本號進行修改,這樣就可以使用vs2005下的版本內容了。雖然我不知道sdk是否向後兼容,不過應該是兼容的,可以試下。

命名空間的檢查更加嚴格
我們的程序引用了一個以前用C寫的庫,裏面用到了一個結構體名字叫:is_base_of,結果沒想到vs2013用的std命名空間裏有一個一樣的名字,所以我們的解決方案是給我們自己寫的結構體加上了一個命名空間。

namespace test {
    struct is_base_of {
        ...
    };
};


dx頭文件的不同
我們都知道vs2013已經集成了dx的sdk,而不像之前一樣單獨發佈dx的sdk,同時,vs2013把dx的頭文件放到了系統的sdk目錄裏。在上面我們提到過vs2013和vs2005的VC++目錄設置不同,vs2013包含了系統的sdk目錄,這導致了一個問題。舉個例子就明白了,因爲我們的客戶端程序用到了dx9,而爲了保證版本的一致性,我們把dx9的頭文件放到了工程目錄當中,在vs2005下,我們不需要特別指明dx的頭文件目錄,因爲系統的默認目錄裏是沒有dx的頭文件的,無論我們是用<>還是""的方式來先查找系統目錄還是先查找工程目錄最後都只能找到我們工程的dx頭文件,但是在vs2013下我們必須要把我們自己的dx目錄放進工程的VC++目錄裏,這樣才能保證我們引用的是自己的頭文件而不是系統的。順帶說一下,VC++目錄和在C/C++選項卡下的附加包含目錄有什麼區別:
wKiom1NH1u-RIY6KAAGhJg4IOz8700.jpg

配置在VC++目錄裏的路徑,在用 <> 包含的時候會優先查找,而配置在C/C++ 選項卡下的附加包含目錄在用 "" 包含的時候會優先查找。

VS自帶庫的實現不同
這個就比較糾結了,因爲兩個VS的版本存在差異,難免會出現庫的實現不同的情況,比如我們遇到的一個問題:
wKiom1NH1wPSuVBRAACEjZinlyM648.jpg

我們打開兩個VS的安裝目錄下 VC\include   queue文件,對比之後發現,這兩個queue的實現還真是差別大,我們的問題在於原本是一個public的成員變量,現在變成了protected了:
wKioL1NH1uuR509-AACW2_X43bY021.jpg

不過好在變爲protected之後,它提供了一個成員函數來獲取它,這沒辦法了,我們只能修改我們自己的代碼,把原來直接獲取改爲用成員函數來獲取。

wKioL1NH1xDywfXkAABIJcg5h08585.jpg

wKiom1NH1yWBO5QfAABM7Onpkak784.jpg


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章