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 生成靜態庫檔案
A 在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檔案 生成可執行檔案】