1. 程式人生 > >slam學習之旅——hello slam

slam學習之旅——hello slam

1 新建工作資料夾

       使用mkdir命令新建資料夾 slambook和ch1資料夾,並利用cd命令進入ch1檔案下,截圖如

      


2 編寫helloslam小程式

     使用vim命令建立helloslam.cpp檔案,並填寫如下程式碼

     

     

   按esc鍵,輸入:wq退出


3 編譯helloslam程式

3.1 使用g++命令編譯

編譯命令使用如下圖

此時利用ls命令可以看到ch1資料夾下多了一個a.out的可執行檔案,其中a.out是該命令預設生成的可執行檔名字

若想生成其他名字的可執行檔案,在呼叫g++命令時在其後新增-o,如下,可看到生成了hell的可執行檔案

補充:關於g++命令的補充說明

g++ –c Hello.cc  編譯檔案,生成目標檔案 Hello.o

g++ Hello.o –o abc  連線 並重命名為可執行檔案 abc

g++ Hello.cc    編譯連線一起,生成a.out

g++ Hello.cc –o hello 生成a.out並命名為hello

3.2 使用cmake編譯

       理論上說,任意一個C++ 程式都可以用g++ 來編譯。但當程式規模越來越大時,一個工程可能有許多個資料夾和裡邊的原始檔,這時輸入的編譯命令將越來越長。通常一個小型c++ 專案含有十幾個類,各類間還存在著複雜的依賴關係。其中一部分要編譯成可執行檔案,另一部分編譯成庫檔案。如果僅靠g++ 命令,我們需要輸入大量的編譯指令,整個編譯過程會變得異常繁瑣。因此,對於C++ 專案,使用一些工程管理工具會更加高效。在歷史上工程師們曾使用makefile 進行自動編譯,但下面要談的cmake 比它更加方便

       在一個cmake 工程中,我們會用cmake 命令生成一個makefile 檔案,然後,用make命令,根據這個makefile 檔案的內容,編譯整個工程

      首先利用rm命令將之前生成的可執行檔案刪除,此時ch1資料夾下只包含一個helloslam.cpp檔案

3.2.1  製作一個工程

       在ch1資料夾下,利用vim命令新建一個CMakeLists.txt檔案,在該檔案中新增如下部分

      

      每個CMakeLists.txt 檔案,告訴cmake 我們要對這個目錄下的檔案做什麼事情。CMakeLists.txt 檔案內容需要遵守cmake 的語法。這個示例中,我們演示了最基本的工程:指定一個工程名和一個可執行程式

     注意:cmake根據CMakeLists.txt檔案生成包含一系列檔案的工程,其中生成的最重要的檔案時makefile檔案,make命令會根據此檔案所制定的規則生成一些列檔案(檔案可能是庫檔案,也可能是可執行程式)

       此時ch1資料夾下只有2個檔案,如下

      

3.2.2 呼叫cmke命令新建工程

        命令使用如下,注意cmake命令後面有一個點(.),此點表示在當前資料夾,故此條命令的意思是在當前資料夾下建立工程。以下是正確建立後輸出資訊

      

     執行cmake命令前該資料夾ch1種只有2個檔案,執行cmake命令後再次呼叫ls命令可以看到該資料夾下多了很多資料夾和檔案,如下

     

3.2.3 編譯helloslam.cpp

         呼叫命令make生成可執行檔案,如下,圖中可以看到生成了綠色的helloslam檔案(可執行檔案)

      

3.3 上述2種編譯方式的區別

       cmake 過程處理了工程檔案之間的關係,而make 過程實際呼叫了g++ 來編譯程式。雖然這個過程中多了呼叫cmake 和make 的步驟,但我們對專案的編譯管理工作,從輸入一串g++ 命令,變成了維護若干個比較直觀的CMakeLists.txt 檔案,這將明顯降低維護整個工程的難度。比如,當我想新增一個可執行檔案時,只需在CMakeLists.txt 中新增一行“add_executable”命令即可,而後續的步驟都是不變的。cmake 會幫我們解決程式碼的依賴關係,無需我們輸入一大串g++ 命令。

3.4 使用庫檔案來實現hello

         此部分為另外一種生成hello程式功能的方法,故需要將之前的檔案全部清空,即工作目錄ch1下為空。

         在一個C++ 工程中,並不是所有程式碼都會編譯成可執行檔案。只有帶有main 函式的檔案才會生成可執行程式。而另一些程式碼,我們只想把它們打包成一個東西,供其他程式呼叫。這個東西叫做庫。一個庫往往是許多演算法、程式的集合。

        在Linux 中,庫檔案分成靜態庫和共享庫兩種¬。靜態庫以.a 作為字尾名,共享庫以.so結尾。所有庫都是一些函式打包後的集合,差別在於靜態庫每次被呼叫都會生成一個副本,而共享庫則只有一個副本,更省空間

3.4.1 生成靜態庫檔案

        在ch1目錄下利用vim闖將檔案libhelloslam.cpp,並新增程式碼如下:   

                                                                                             

    B 使用vim建立檔案CMakeLists.txt,並新增如下程式碼

     

C 使用mkdir命令建立build目錄,用於存放產生的一系列檔案,如下

    

D 進入build資料夾,並呼叫cmake命令建立工程,如下

   

E 在ch1目錄下呼叫make,生成庫檔案,如下,可以看到多出了一個檔案   libhello.a

    

3.4.2 生成共享庫檔案

       方法步驟與靜態庫檔案基本相同,唯一不同的是在CMakeLists.txt檔案中宣告不一樣,如下是共享庫檔案宣告方法

                            

        注意到:我們並沒有註釋掉靜態庫的宣告,因為:2種庫檔案的生成互不影響,只要2種類型庫檔案的名字不一樣即可,本例中靜態庫檔名字為hello,而共享庫檔名字為hello1.

       其他步驟與靜態庫檔案一樣,成功生成後如下:

     

     

      

  3.4.3 使用庫檔案          

        庫檔案是一個壓縮包,裡頭帶有編譯好的二進位制函式。不過,僅有.a 或.so 庫檔案的話,我們並不知道它裡頭的函式到底是什麼,呼叫的形式又是什麼樣的。為了讓別人(或者自己)使用這個庫,我們需要提供一個頭檔案,說明這些庫裡都有些什麼。因此,對於庫的使用者,只要拿到了標頭檔案和庫檔案,就可以呼叫這個庫了

  A   利用vim在工作目錄ch1下建立libhelloslam.h,並新增如下程式碼

   

   

B.利用vim在ch1目錄下生成usehello.cpp,如下:

  

 C.在CMakeLists.txt檔案中新增可執行程式的生成命令,同時新增庫檔案的連結宣告

 

D.在build資料夾中呼叫cmake和make,生成可執行程式usehello

  

3.5 使用IDE

        整合開發環境(Integrated Development Environment,IDE)

        IDE 為開發者提供了跳轉、補全、斷點除錯等很多方便的功能

        Linux 下的IDE 有很多種。雖然與Windows 下的Visual Studio 還有一些差距,不過支援C++ 開發的也有好幾種,例如Eclipse、Qt Creator、Code::Blocks、Clion 等等

        Kdevelop的優點列舉如下:
                                                1. 支援cmake 工程。
                                                2. 對c++ 支援較好(包括11 標準)。有高亮、跳轉、補全等功能。能自動排版程式碼。
                                                3. 能方便地看到各個檔案和目錄樹。
                                                4. 有一鍵編譯、斷點除錯等功能。
                                                5. 無須付費。

3.5.1 安裝

        Kdevelop。它是一個免費軟體,在Ubuntu 的源中提供,這意味著你可以用apt-get 來安裝它

        輸入sudo apt-get install kdevelop進行安裝

3.5.2開啟kdevelop

         輸入kdevelop開啟,開啟後介面如下

   

3.5.3 新建工程

      a  點選上方的工程,選擇從模版新建

         

     b.在建立新工程介面新增相應資訊

        

        c 點選上圖中的next按鈕,進行下一步

            

        d 點選finish按鈕,完成工程的建立

          

          圖中:第一欄是cmake命令的可執行程式目錄;第二欄是本程式的編譯執行目錄,點選ok完成建立

          生成成功後結果圖如下

     

3.5.4 新增相應程式碼

        本工程使用庫檔案來輸出helloworld

   a.首先新增庫檔案的原始檔,即libhello.cpp

       右鍵工程名helloslam,點選建立檔案

      

    在彈出的視窗中新增原始檔的名字,即libhello.cpp,如下,點選ok按鈕

     

    在新建立的cpp檔案中新增如下程式碼

   

  b.新增庫檔案的標頭檔案,即libhello.h,並新增如下程式碼

      與建立庫檔案libhello.cpp的方式相同,新增後如下圖

    

  c.在CMakeLists.txt檔案中新增生成lib的相應資訊

  

 d.對main檔案新增相應程式碼

   

e.在CMakeLists.txt檔案中為此工程的可執行檔案helloslam新增lib庫的連結

  

3.5.5 編譯程式

 點選介面上的構建按鈕,或者直接按F8,相當於輸入了cmake和make命令   

3.5.6 執行程式

a.執行程式前需要確保2步,其一就是已經點選過構建按鈕(即已經正確編譯連結,即cmake和make命令都執行成功,記住:只要make clean過工程,就需要重新構建);其二在點選execute按鈕時需要指定啟動器,即新增可執行程式的路徑,如下

點選execute按鈕,如果是第一次執行(或者使用過make clean,或清理過該工程)都會彈出配置啟動器的對話方塊,如下

上圖中選中工程名字helloslam, 然後點選新建,會自動彈出我們可執行程式的路徑,如下,點選ok完成

再次點選介面上的execute按鈕,成功執行

 


4 錯誤集錦

4.1 在步驟3.2.2時報錯

    錯誤資訊如下所示時,請仔細檢查自己的CMakeLists.txt檔案

 

筆者報上述錯誤原因如下,即工程名中間多了一個空格,去掉空格後即正常建立工程

4.2 在步驟3.4.3的D步驟時

   出現錯誤如圖,此錯誤為找不到usehello.cpp中包含的標頭檔案。

  解決方法:確保此標頭檔案【libhelloslam.h】在ch1目錄情況下,檢視usehello.cpp中include語句,正確的include語句如下:  

筆者錯誤的include語句如下:注意引號和尖括號的區別

補充:引號和尖括號的include語句區別如下:

include有兩種形式:

1,#include "  *.h":表示先在當前工程目錄下查詢標頭檔案,如果沒有再按標準方式查詢;這種方式常用於使用者自定義標頭檔案的查詢。

2,#include<*.h>:表示按標準方式查詢標頭檔案,即直接到系統指定的某些目錄中去找某些標頭檔案。

4.3  在步驟3.4.3的D步

         出現以下錯誤,則表示在CMakeLists.txt檔案中忘記了將庫檔案連結到可執行程式上,即忘記寫target_link_libraries(可執行程式名字  庫檔名字)

4.4  在步驟3.4.3的D步

   出現以下錯誤,表示忘記在usehello.cpp中新增include,即沒有包含庫檔案的標頭檔案(libhelloslam.h)

 

注意:若庫檔案的標頭檔案(libhelloslam.h)和target_link_libraries(可執行程式名字  庫檔名字)均忘記新增,則會先出現4.4的錯誤,解決掉之後會出現4.3的錯誤。原因是在CMakeLists.txt檔案中首先是生成可執行檔案,然後才連結可執行檔案到庫檔案上。

參考:
https://blog.csdn.net/u013378306/article/details/52424826   【gcc/g++編譯 cpp/c檔案 生成可執行檔案】