Qt實現軟件從Windows到Linux跨平臺

        Qt,面向C++圖形界面的一種架構,對於GUI有很好的擴展,通過近一個月的學習和摸索,終於實現了Windows下的軟件代碼移植到Linux,實現了軟件的跨平臺。這其中走了不少彎路,遇到很多問題,主要是通過Internet找資料,上論壇求助,才使得最終成功,所以這也是我寫這篇博文的初衷,希望能通過自己的經驗總結,能夠讓更多像我一樣的菜鳥少走彎路,走的更遠。。。

         首先,介紹一下:爲什麼要用Qt?因爲我們自己開發了一個小軟件,在Windows下用C++寫的代碼,其中主要調用了MKL和Opengl兩個庫,我們的目的是想將我們的軟件推廣,讓更多的人來使用我們的軟件,那就希望除了在Windows下,在Linux(國外較多)環境下也能使用我們的軟件,這就是要實現軟件跨平臺,那跨平臺就必然涉及到了底層代碼層的東西,首先要選擇跨平臺的工具,通過網上搜集資料,最終確定使用Qt。

         其次,確定使用Qt後,光靠Qt行不行?Qt是面向對象的GUI,涉及到代碼層、MKL庫、Opengl庫等最根本的東西時候還需要其他的工具進行輔助,那我就將我們開發使用的工具做以介紹,從代碼最底層開始,在進行Qt開發時候,代碼層是以靜態庫的形式鏈接到Qt的工程文件中,因此大量的底層代碼都是以庫的形式存在,在Windows下是以.lib形式存在,在Linux下是以.a或者.so形式存在,那麼使用什麼工具進行代碼管理呢?我們選用的是Cmake進行代碼編譯生成庫,其中Cmake在Windows和Linux下都能使用,Cmake的使很強大,就我個人而言,它能將.cpp以及.h等大量的代碼及頭文件統一管理,代碼、庫、頭文件非常清晰明瞭,對於一個工程軟件的理解思路很清晰,Cmake的語法很好掌握,下載Cmake的使用手冊,然後按照手冊中的例程走一遍,很多語法都是固定的,比如最簡單的Hello Word!很多人都是從這開始學的吧,呵呵,我當時也是找了一個最簡單的Hello Word!將Cmake的使用從頭到尾熟悉了一遍,然後再在簡單的基礎上進行復雜擴展,其實只要最簡單的東西熟悉了,難的也就變得簡單了,因爲難的是在簡單的基礎上迭代、擴展,基礎的東西熟悉了可以少走彎路,對於Cmake我就簡單介紹,具體細節可參照網上其他Cmake具體資料,我這裏主要將我們跨平臺的宏觀大體思路進行介紹,涉及到細節的東西不做深入探討,如果你能使用Cmake生成代碼庫:.lib,.a,.so那麼你離成功就近了一步,那進行Windows向Linux跨平臺時候,主要生成Linux下的.a和.so即可,.a是靜態庫,.so是動態庫,下圖顯示成功生成了.a和.so庫文件,.a和.so生成是靠代碼控制。

         對於Cmake進行代碼生成庫時候,我的經驗是不用添加代碼所涉及到的MKL等數學庫,我理解的是Cmake只在代碼層面對對軟件代碼進行管理和編譯,它不涉及到函數功能是否實現,意思就是Cmake不管你這個函數是否能使現相應的函數功能,我只需在我Cmake 編譯的時候能找到代碼中出現的函數名即可,比如vslNewStream()函數,我不要求我在mkl數學庫中能實現你的函數功能,我只需要在Cmake編譯時,我在mkl的頭文件定義中能找到vslNewStream函數名稱即可,那Cmake核心要求就需要你要將代碼中涉及的代碼以及頭文件的路徑要全部加對,即Cmake語法中include_directories()是核心的東西,不能出錯,Cmake成功generate之後只是說明你的Cmake工程管理代碼的語法沒問題,要涉及底層.cpp代碼沒問題,還需要在Linux用make來檢驗代碼並生成最終的.a和.so庫,cd到由Cmake生成的Build文件下,一般生成了Makefile文件,make主要是針對Makefile進行操作編譯,下圖表示成功生成libmose.a靜態鏈接庫。

           下一步,將成功生成的libmose.a靜態鏈接庫加入到Qt工程文件中,注意,現在所加的.a靜態庫只是在Qt中加入了代碼管理庫,其相當於邏輯集成庫,因此當程序代碼真正要實現功能時,比如要進行函數調用時,那麼現在就要加入mkl等庫文件,mkl庫中有.a庫中代碼調用相應函數功能的函數,例如上述提到的vslNewStream()函數功能的實現定義在libmkl_intel_lp64.a中,因此只需要將代碼中涉及到所有函數以及變量全部統一加入到Qt工程文件中,那麼整個軟件工程才能統一正常運轉工作。在Linux下安裝Qt,我們安裝的Qt版本爲QT Library: 4.8.1 QT Creator:2.4.1 Ubuntu:12.04,具體安裝步驟不再詳述。

              然後很重要,也很麻煩的一步,在Qt中添加庫,由於開始對Qt不熟悉,所以在這一步卡了很長時間,主要問題還是出現在Windows代碼移植到Linux環境下容易出現問題,還有就是Qt對代碼要求很嚴格,不能出現任何細小的疏忽和錯誤,否則就會出現undefined referenced to' ... ',這幾乎是所有初學Qt的人都要經歷的過程,因爲Qt對代碼的苛刻,所以你代碼無論出現什麼問題,它都會出現上述錯誤,正因爲非常常見,不能具體到對應代碼錯誤,因此解決起來也很頭疼,網上也給了一些解答,我覺得每個人遇到的問題都不一樣,因此具體問題具體分析,通過自己深入理解代碼,分析和解決undefinded reference to 這一錯誤。Qt對代碼層面要求很苛刻,舉例說明,比如當代碼要調用MKL庫時,.a庫的調用順序不一樣都會出現錯誤,因此初學者一定要小心,否則你會陷入undefined referenced to 的泥潭無法自拔,比如:

             程序成功運行,而當我將LIBS += 順序變換一下時,編譯就會出錯。如下圖:

                在進行Qt工程文件添加.a庫時,INCLUDEPATH += 同樣重要,注意這裏的路徑一定要和libmose.a代碼頭文件路徑以及調用的MKL頭文件一致,否則會出錯,可能會有人問爲什只加入.h文件即可,原因是你Cmake,make編譯生成的libmose.a中包含了.cpp代碼文件,Qt中工程編譯時,加入相應代碼的.h頭文件來定義相應的.cpp中的函數、變量定義即可,前面說到Cmake是進行代碼管理打包生成代碼鏈接庫,那麼在Qt中就要真正的調用函數,進行實戰,我理解的是Qt是幹實事的,Cmake之是做做表面工作(可能理解的不準確),那我在驗證仿真程序時,是利用Qt中按鈕觸發事件信號槽機制來觸發進行仿真程序運行,如何設置按鈕觸發在Qt例程中,網上有現成代碼,直接copy過來就能用。


                   這是Qt信號槽按鈕觸發界面,也就是當點擊yes時,信號觸發連接到軟件仿真程序,程序就開始運行,下圖是點擊yes按鈕後仿真結果

          那麼以上調用MKl庫就完成,下面要調用Opengl庫進行顯示,前面說實現Windows到Linux跨平臺,其實最麻煩的是Opengl庫中涉及到Windows.h等Windows下的系統文件如何實現在Linux下的替換和移植,我開始還幻想着通過自己寫Windows.h在Linux下相應的API,結果發現工程量太大,結果放棄了,後來想直接調用Qt下的QtOpengl,因爲Qt本身是針對跨平臺的,因此QtOpengl就不會涉及到Windows到Linux的問題,後來通過簡單調用QtOpengl實現簡單顯示三維圓柱體。

                  那麼Qt實現跨平臺,調用MKL、Opengl庫的工作基本告一段落,下面主要是將上述仿真結果參數寫入QtOpengl中,那麼就實現了Linux下Qt對代碼仿真、顯示一體化的功能,再進行後期的代碼、算法優化,即實現將Windows下的軟件移植到Linux下,實現軟件跨平臺。

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