CMakeLists_find_package以及C++基本語法

辰令發表於2024-03-26

命令 catkin_make

等效於以下指令:
cd ~/catkin_ws
cd src
catkin_init_workspace
cd ..
mkdir build
cd build
cmake ../src  -DCMAKE_INSTALL_PREFIX=../install -DCATKIN_DEVEL_PREFIX=../devel

命令 cmake 與 make install

    -DCMAKE_BUILD_TYPE=:  release debug
    -DCMAKE_INSTALL_PREFIX=/usr/local/mysql       \    #安裝路徑
	
     # 下面形式是相同的
     cmake -DTEST_DEBUG=ON ..
     cmake -D TEST_DEBUG=ON ..
     CMAKE_INSTALL_PREFIX,用於指定cmake install時的相對地址字首
     CMAKE_INSTALL_PREFIX,用於指定cmake install時的相對地址字首
       透過修改 CMAKE_INSTALL_PREFIX 變數的值來指定這些檔案應該複製到哪個根目錄
    make install 和make install prefix=/usr/local/
     prefix預設是/usr/local 
1) 如果共享庫檔案安裝到了/lib或/usr/lib目錄下, 那麼需執行一下ldconfig命令
  ldconfig命令的用途, 主要是在預設搜尋目錄(/lib和/usr/lib)以及動態庫配置檔案/etc/ld.so.conf內所列的目錄下, 搜尋出可共享的動態連結庫(格式如lib*.so*), 進而建立出動態裝入程式(ld.so)所需的連線和快取檔案. 快取檔案預設為/etc/ld.so.cache, 此檔案儲存已排好序的動態連結庫名字列表. 

2) 如果共享庫檔案安裝到了/usr/local/lib(很多開源的共享庫都會安裝到該目錄下)或其它"非/lib或/usr/lib"目錄下, 那麼在執行ldconfig命令前, 還要把新共享庫目錄加入到共享庫配置檔案/etc/ld.so.conf中, 如下:
# cat /etc/ld.so.conf
include ld.so.conf.d/*.conf
# echo "/usr/local/lib" >> /etc/ld.so.conf
# ldconfig

) 如果共享庫檔案安裝到了其它"非/lib或/usr/lib" 目錄下,  但是又不想在/etc/ld.so.conf中加路徑(或者是沒有許可權加路徑). 那可以export一個全域性變數LD_LIBRARY_PATH, 然後執行程式的時候就會去這個目錄中找共享庫

檔案中CMakeLists.txt:

find_package 需要找到指定本版的庫標頭檔案包含路徑、連結庫路徑等,從而能夠滿足我們開發專案的編譯連結需要。
find_package命令便捷進行依賴包配置的前提是這個包的開發者也是用CMake配置好了這個包,
    並提供了<PackageName>Config.cmake或Find<PackageName>.cmake的配置檔案
 本質是透過一些特定的規則找到<package_name>Config.cmake包配置檔案,
    透過執行該配置檔案,從而定義了一系列的變數,透過這些變數就可以準確定位到庫的標頭檔案和庫檔案,完成編譯
 CMake提供了find_package()命令用來查詢
 CMake本身不提供任何搜尋庫的便捷方法,所有搜尋庫並給變數複製的操作必須由CMake程式碼完成,
  也就是目錄下的<PackageName>Config.cmake或Find<PackageName>.cmake的配置檔案。
   只不過庫的作者通常會提供這兩個檔案,以方便使用者呼叫。
REQUIRED:可選欄位。表示一定要找到包,找不到的話就立即停掉整個CMake。而如果不指定REQUIRED則CMake會繼續執行。

預設查詢路徑

 find_package查詢.cmake的預設查詢路徑有如下
 PATH
 CMAKE_PREFIX_PATH
 CMAKE_FRAMEWORK_PATH
 CMAKE_APPBUNDLE_PATH
 echo $PATH可查詢PATH包含哪些預設查詢路徑,以預設路徑為根目錄,find_package將查詢目錄下包含的.cmake檔案

設定查詢路徑

讓find_package在指定路徑找依賴包,有三種方式
# 1. 設定DIR
set(Torch_DIR /home/libtorch)
find_package(Torch REQUIRED)   
# 2. 設定PATHS
find_package(Protobuf REQUIRED
			 PATHS /home/libtorch
			 NO_DEFAULT_PATH)    
# 3. 指定
set(CMAKE_PREFIX_PATH /home/libtorch)

改變

 find_package(YourPackageName NO_DEFAULT_PATH)    ## 不要在預設的路徑中查詢
 find_package(YourPackageName NO_CMAKE_PATH)	  ## 不要在CMAKE_PREFIX_PATH變數中指定的路徑中查詢  

C++ 語法

過載
  operator 是C++的一個關鍵字,它和運算子(如=)一起使用,表示一個運算子過載函式
  使用operator過載運算子,是C++擴充套件運算子功能的方法
     將運算子過載實現為類的成員函式;運算子過載實現為非類的成員函式(即全域性函式
   1.類體中宣告(定義)需要過載的運算子
  
   2.operator()函式物件
     仿函式(functor)又稱為函式物件(function object)是一個能行使函式功能的類。
	  仿函式的語法幾乎和我們普通的函式呼叫一樣,不過作為仿函式的類,都必須過載operator()運算子,
	  
	在C++中,如果你想要定義一個結構體E並使其具有類似於Hasher的功能,
	   要確保E有一個名為operator()的過載方法, 這個方法允許你像呼叫函式一樣呼叫你的結構體例項  
資料容器
vector其中一個特點:記憶體空間只會增長,不會減小,
  援引C++ Primer:為了支援快速的隨機訪問,vector容器的元素以連續方式存放,每一個元素都緊挨著前一個元素儲存

  hash_map ,unordered_map ,map 
   標頭檔案#include <unordered_map>,名稱空間需要引入using std::unordered_map,我
    unordered_map 容器,直譯過來就是"無序 map 容器"的意思
     emplace 的使用和insert的使用方法類似,但是emplace無需使用value型別引數,而是直接將引數列表傳遞給元素型別的建構函式。
 class unordered_map
{
  typedef __umap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc>  _Hashtable;
  _Hashtable _M_h;

 }	
_Hashtable具體是什麼:
  template<bool _Cache>
    using __umap_traits = __detail::_Hashtable_traits<_Cache, false, true>;
   template<typename _Key,
       typename _Tp,
       typename _Hash = hash<_Key>,
       typename _Pred = std::equal_to<_Key>,
       typename _Alloc = std::allocator<std::pair<const _Key, _Tp> >,
       typename _Tr = __umap_traits<__cache_default<_Key, _Hash>::value>>
  
 enum  列舉(enumeration)和類相似,能夠定義一種新的資料型別,不同的是,列舉是將一組整形常量組織在一起
 struct 結構體
模板
  模板就是實現程式碼重用機制的一種工具,它可以實現型別引數化,即把型別定義為引數,從而實現了真正的程式碼可重用性	
    關鍵字using作為別名宣告的開始,其後緊跟別名和等號,其作用是把等號左側的名字規定成等號右側型別的別名
    template<typename T>
    using MMap = map<int, T>;  
   	  
  等價於
   template<typename T>
   struct MyMap
    {
   	 typedef map<int, T> mapType;
    };
 	
`eof` 是End Of File的縮寫,表示檔案結束 
   :this是指向自身物件的指標,*this是自身物件	
    c++中,return this 是返回當前物件的地址,
	      return *this 是返回當前物件或當前物件的複製。如果返回的是引用,那麼就是物件本身,否則是物件的複製
	1e3  :1乘以10的三次方。e為階碼標誌,大小寫通用,3為階碼 
    1e-3 :0.001 		
 std::ostream::seekp
    ifstream 類和 fstream 類有 seekg 成員函式,可以設定檔案讀指標的位置; ostream & seekp (int offset, int mode);
    ofstream 類和 fstream 類有 seekp 成員函式,可以設定檔案寫指標的位置。 istream & seekg (int offset, int mode);
	    ios::beg:讓檔案讀指標(或寫指標)指向從檔案開始向後的 offset 位元組處。
		         offset 等於 0 即代表檔案開頭。在此情況下,offset 只能是非負數。
        ios::cur:在此情況下,offset 為負數則表示將讀指標(或寫指標)從當前位置朝檔案開頭方向移動 offset 位元組,
		         為正數則表示將讀指標(或寫指標)從當前位置朝檔案尾部移動 offset位元組,為 0 則不移動。
        ios::end:讓檔案讀指標(或寫指標)指向從檔案結尾往前的 |offset|(offset 的絕對值)位元組處
    
    所謂“位置”,就是指距離檔案開頭有多少個位元組。檔案開頭的位置是 0
  seekg():輸入 檔案指標跳轉函式。表示將輸入檔案指標跳轉到指定位元組位置‘  "g" 表示 "get",
    本質在於檔案中有一個指標,在指標位置進行讀寫操 正的表示向後偏移,負的表示向前偏移
    01.  seekg(0L,ios::beg); 表示從檔案的開頭位置開始,移動 0 位元組,實際上就是指移動到檔案開頭
	    如果目前已經在檔案末尾,則在呼叫此函式之前,必須清除檔案末尾的標誌
		 dataIn.clear(); dataIn.seekg(0L, ios::beg);
   
  seekp():輸出 檔案指標跳轉函式。表示將輸出檔案指標跳轉到指定位置 p是put縮寫
檔案操作和檔案流  #include <fstream> 
 std::ofstream和std::ifstream都屬於fstream這個類。
 fstream是控制檔案讀寫操作的一個類,其中包括std::ofstream和std::ifstream  

java

    hashCode()方法的作用是確定物件在雜湊儲存結構例如HashMap、HashSet中的邏輯地址
      hashCode並不需要唯一性,但equals必須嚴格地判斷兩個物件是否相同-保證單一原則:equals相同的兩個物件的hashcode必須相同	 
    在無序集合中(如Set),使用hashcode來計算key應儲存在hash表的索引,
     如果重寫了equals而沒有重寫hashcode,會出現兩個完全相同的物件。
     因為hashcode不同,計算出的索引不同		  

參考

 https://www.zhihu.com/question/21866381/answer/2309063290
 C++11特性:使用using和typedef給模板定義別名  https://blog.csdn.net/qq_73185160/article/details/135049613
 C++ seekg()和seekp()用法詳解  https://c.biancheng.net/view/pbwx9nt.html	 
  https://blog.csdn.net/baidu_35692628/article/details/132724130
 “輕鬆搞定CMake”系列之find_package用法詳解 https://blog.csdn.net/zhanghm1995/article/details/105466372