C++_項目開發與Cmake構建工具


一、語言:

 C語言
 C++ 標准庫可以分為兩部分:
  標准函數   庫: 這個庫是由通用的、獨立的、不屬於任何類的函數組成的。函數庫繼承自 C 語言。
               C++ 標准庫包含了所有的 C 標准庫,為了支持類型安全,做了一定的添加和修改
  面向對象 類庫: 這個庫是類及其相關函數的集合。

二、編譯器:

GCC:GNU Compiler Collection(GUN 編譯器集合),它可以編譯C、C++、JAV、Fortran。大寫的GCC	
gcc & g++現在是gnu中最主要和最流行的c & c++編譯器 。
g++是c++的命令,以.cpp為主,
gcc是c語言一般為.c。
其實編譯器是gcc還是g++ 是按照C標准還是C++標准編譯鏈接來確定。
根據代碼的后綴名來判斷調用 c編譯器還是c++編譯器 (g++)
對於.c文件gcc當做c語言處理,g++當做c++處理;
對於.cpp文件gcc和g++均當做c++處理
編譯器對程序代碼的編譯主要分為下面幾個過程:  
    a) 詞法分析 
    b) 語法分析 
    c) 語義分析 
    d) 中間代碼生成 
    e) 代碼優化 
    f) 代碼生成 
    g) 符號表管理 
    h) 將多個步驟組合成趟 
    i) 編譯器構造工具  	

三、過程:

1.編寫代碼

2.編譯和鏈接
  預處理階段--編譯階段--匯編階段--鏈接階段
 編譯就是把文本形式源代碼翻譯為機器語言形式的目標文件的過程。
 鏈接是把目標文件、操作系統的啟動代碼和用到的庫文件進行組織,形成最終生成可執行代碼的過程
 
 01.編譯過程又可以分成兩個階段:編譯和匯編
   gcc編譯器便是把以上的幾個過程進行捆綁,使用戶只使用一次命令就把編譯工作完成
   --> 預編譯處理(.c) 
   --> 編譯、優化程序(.s、.asm)
   --> 匯編程序(.obj、.o、.a、.ko) 
   --> 鏈接程序(.exe、.elf、.axf等)
 02.鏈接
    靜態鏈接 
	動態鏈接	
3.運行是執行可執行文件
調試--運行過程中調試,運行結果調試

四、具體情況

1.切換到相應的目錄
2.Linux環境下
	g++ 
	用g++ 加上文件名,注意要加上文件擴展名,這樣會生成一個Linux默認生成a.out的可執行文件(Windows默認生成a.exe,)
3.直接輸入  ./a.out 並回車, 即可執行由demo.cpp編譯鏈接生成的程序(Windows環境下,則改成a.exe 運行程序)
具體示例
    cd  /home/test/soft/test-master
    g++ -o helloworld  helloworld.cpp 
    ./helloworld.cpp 

01.頭文件-源文件-庫文件-目標文件

 source file
 head file
 C++中進行代碼分離  在h文件中聲明Declare,而在cpp文件中定義Define
   頭文件是文本文件,是可供閱讀的;庫文件是二進制文件,不可直接閱讀。
   頭文件在編譯中使用;庫文件在鏈接中使用。
   頭文件中是函數或定義的聲明,及少量內聯函數的使用,一般不包含非靜態函數實現;庫文件中包含函數的實現。
   頭文件是手動編寫的,庫文件是編譯生成的

02.頭文件Head file

01.頭文件(.h):
    寫類的聲明(包括類里面的成員和方法的聲明)、函數原型、#define常數等,但一般來說不寫出具體的實現。
    在寫頭文件時需要注意,在開頭和結尾處必須按照如下樣式加上預編譯語句:
    #ifndef CIRCLE_H
    #define CIRCLE_H
    
    //代碼寫在這里
    
    #endif
 
 eg:mydecoder.h
     #ifndef _MY_DECODER_H_
     #define _MY_DECODER_H_
     #include<opencv2/opencv.hpp>
     class myDecoder{
      private:
     		int width;
     		float * d_nrm;
      private:
     		nv_handle;
     		nv_state;
     
      public:
     		myDecoder();
     		~myDecoder();
      public:    
     		int init(int width,int height);
      };
     
     #endif

03.源文件

 02.源文件(.cpp):mydecoder.cpp
    源文件主要寫實現頭文件中已經聲明的那些函數的具體代碼。
       開頭必須#include一下實現的頭文件,以及要用到的頭文件
    #include "decoder.h"
   ##hpp  是Header Plus Plus的簡寫
    .hpp本質就是將.cpp的實現代碼混入.h頭文件當中,定義與實現都包含在同一文件,則該類的調用者只需要include該.hpp文件即可,無需再將cpp加入到project中進行編譯
   
 源代碼的編譯和鏈接
      .h頭文件是編譯時必須的,lib是鏈接時需要的,dll是運行時需要的
   
       添加頭文件目錄           INCLUDE_DIRECTORIES
       添加需要鏈接的庫文件目錄 LINK_DIRECTORIES
       工程生成目標文件        add_executable

code

 #include <time.h>  int clock_gettime(clockid_t clk_id, struct timespec* tp);
  struct timespec
  {
     time_t tv_sec; /* 秒*/
     long tv_nsec; /* 納秒*/
  };
  
  關於 unsigned long long 於 long long
   long long 最大只有19位 ;
   unsigned long long  最大有20位 ,原因犧牲了符合位來換取更大的記錄 
       可以根據需要,獲取不同要求的精確時間
    CLOCK_MONOTONIC   是 monotonic time ,
    而 CLOCK_REALTIME 是 wall time 

五、構建系統與構建工具

cmake與make
 編寫-編譯-鏈接-運行 源文件太多,一個一個編譯時就會特別麻煩--
 make工具,它是一個自動化編譯工具,你可以使用一條命令實現完全編譯。但是需要編寫一個規則文件,make依據它來批處理編譯,這個文件就是makefile
 cmake工具,它能夠輸出各種各樣的makefile或者project文件,從而幫助程序員減輕負擔。需要編寫cmakelist文件,它是cmake所依據的規則
01.GNU構建系統
  構建方式-GNU構建系統(GNU Build System)主要是指通過 autoconf automake和libtool這三個工具構建出來的軟件結構體系,又名 Autotools
     基於源碼安裝軟件:configure->make->make install 利用腳本和make程序在特定平台上構建軟件
	    configure腳本是由軟件開發者維護並發布給用戶使用的shell腳本。這個腳本的作用是檢測系統環境,
		        最終目的是生成Makefile和config.h。configure主要檢查當前目標平台的程序、庫、頭文件、函數等的兼容性
        make通過讀取Makefile文件,開始構建軟件。
	    make install可以將軟件安裝到需要安裝的位置 
	生成configure腳本和Makefile.in等文件,開發者需要創建並維護一個configure.ac文件,configure.ac用於生成configure腳本。autoconf工具用來完成這一步
  cmake
  xmake 是一個基於 Lua 的輕量級跨平台構建工具,使用 xmake.lua 維護項目構建,相比 makefile/CMakeLists.txt,配置語法更加簡潔直觀

02.IDE構建工具
    Visual Studio 

六、Cmake介紹

cmake --version
cmake  --help
    Usage
      cmake [options] <path-to-source>
      cmake [options] <path-to-existing-build>
	把支持的命令行參數分成了幾個類別
 /usr/bin/cmake: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux),
 dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, 
 BuildID[sha1]=, stripped
  說明: /lib64是內核級的,/usr/lib64是系統級的,/usr/local/lib64是用戶級

1.安裝cmake

CMake能用來編寫跨平台(cross-platform)的構建規則,
   通過這些規則來調用各個平台的編譯器、鏈接器,生成各個目標(靜態庫,靜態庫,或者可執行)  
  ,CMake 並不直接建構出最終的軟件,而是產生標准的建構文檔(如 Makefile 或 projects	)   
  編譯器 gcc
  函數庫
  安裝好CMake,它提供了一個可執行文件cmake或cmake.exe,
      有時候還提供一個GUI版本,比如ccmake或cmake-gui,調用的還是cmake命令
Ubuntu  安裝 sudo apt install cmake
development tools    
    use the GCC compiler, 
       GDB to debug, 
   and make to build the project	

2.步驟

 原始的方式  采用 gcc hello.cpp -o hello 命令來生成可執行文件
 新建 build 目錄,cd 到 build 目錄下,敲 cmake .. 命令,敲 make 命令生成 hello 可執行文件
  mkdir build && cd build && cmake .. && make -j16
 ls 一下會發現 CMake 幫我們生成了 Makefile 等等一些文件。
   CMakeCache.txt  
   CMakeFiles  
   cmake_install.cmake  
   compile_commands.json  
   Makefile 

3.示例項目

 01.先把opencv環境配置好  sudo apt-get install libopencv-dev 
    確定頭文件位置
       安裝的位置
        /usr/include/opencv2/opencv.hpp
    	/usr/include/opencv/
    	/usr/share/opencv/
	確定庫函數位置
	   /usr/lib/x86_64-linux-gnu/
02.修改Cmake
# 	 錯誤類型 .cpp:3:22: fatal error: opencv.hpp: 沒有那個文件或目錄
# 頭文件路徑
  INCLUDE_DIRECTORIES(
          ${PROJECT_SOURCE_DIR}/include
  )
  include_directories("/usr/include/opencv2")
  include_directories("/usr/include/opencv")
  include_directories("/usr/include")
  link_directories("/usr/lib/x86_64-linux-gnu/")
 03.修改main函數
    修改根目錄
   std::string root_dir = "./";
   std::string config_file = root_dir + "./conf/test.ini";
 04.執行過程
 mkdir build && cd build && cmake .. && make -j16
 
 #make -j16意思即make最多允許16個編譯器同時執行,提高編譯速度,充分利用本機計算資源項目在進行並行編譯
05.查看輸出:
   /home/test/soft/test-master/Log/IPM

七、CMakeLists.txt內容

# 最低指定的CMake版本
 cmake_minimum_required(VERSION 3.10)
 # 括號里面填你的工程名
 project(Test)
 
 # 指定語言要求,以下命令為c++ 11
 set(CMAKE_CXX_STANDARD 11)
 set( CMAKE_CXX_COMPILER "g++" )
 set( CMAKE_BUILD_TYPE "Release" )
 set( CMAKE_CXX_FLAGS "-std=c++11 -march=native -O3" )
 
 # 頭文件路徑
 INCLUDE_DIRECTORIES(
         ${PROJECT_SOURCE_DIR}/include
 )
 include_directories("/usr/include/opencv2")
 include_directories("/usr/include/opencv")
 include_directories("/usr/include")
 
 # 給編譯器添加庫目錄,指定要鏈接的庫文件的路徑
 link_directories("/usr/lib/x86_64-linux-gnu/")
 
 set(MY_OPENCV_LIBS opencv_calib3d opencv_core opencv_highgui
         opencv_imgcodecs opencv_imgproc opencv_videoio
         )
 link_libraries(
         ${MY_OPENCV_LIBS}
         )
 
 # 生成可執行文件 SurrouncViewPano add_executable命令也可以用來創建導入的(IMPORTED)可執行目標:add_executable(< name> IMPORTED)
 # :add_executable: 使用給定的源文件,為工程引入一個可執行文件
 add_executable(Test
                 main.cpp
         src/ini_parser.cpp
         src/string_util.cpp
         src/Test.cpp
         src/util.cpp)
 	  
#說明  
#  link_libraries 要在 add_executable 之前
# target_link_libraries 要在 add_executable 之后
	02命令行
  001.構建
  rm -rf build && mkdir build && cd build && cmake .. && make all -j8
  002.執行
  ./build/Frame /data/video_demo.mp4 /data/frame/

示例01

 # 自定義頭文件目錄- 告訴編譯器頭文件在哪個位置
 INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/include)
 
 ###方式一:直接生成目標文件-可執行文件
      #編譯可執行程序
      add_executable(${PROJECT_NAME}
      CVrame.cpp
      src/util.cpp
             )
 
 # # 方式二, -生成目標文件-生成靜態庫  --目標文件鏈接靜態庫-可執行文件
 # add_executable(${PROJECT_NAME} CVrame.cpp )
 # #生成動態鏈接庫
 # #庫文件的輸出目錄
 # SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
 # ADD_LIBRARY( util SHARED ${PROJECT_SOURCE_DIR}/src/util.cpp)
 # #目標文件鏈接到庫文件
 # target_link_libraries(${PROJECT_NAME}  util)

示例02

#尋找Opencv庫 ###方式opencv一
find_package(OpenCV REQUIRED)
message(STATUS " version: ${OpenCV_VERSION}")
message(STATUS " libraries: ${OpenCV_LIBS}")
message(STATUS " includ: ${OpenCV_INCLUDE_DIRS}")
include_directories( 
        ${OpenCV_INCLUDE_DIRS}
        ${OpenCV_INCLUDE_DIRS}/opencv2
        )
link_libraries( ${OpenCV_LIBS})

###方式opencv二
# include_directories("/usr/include/opencv2")
# include_directories("/usr/include/opencv")
# include_directories("/usr/include")
# set(MY_OPENCV_LIBS opencv_calib3d opencv_core opencv_highgui
#         opencv_imgcodecs opencv_imgproc opencv_videoio
#         )
# link_libraries(  ${MY_OPENCV_LIBS}  )

# 庫文件-添加非標准的共享庫搜索路徑
link_directories("/usr/lib/x86_64-linux-gnu/")	

八、#參考

 CMakeLists.txt
  Get started with CMake Tools on Linux https://code.visualstudio.com/docs/cpp/cmake-linux
   C++中頭文件(.h)和源文件(.cpp)都應該寫些什么 https://www.cnblogs.com/fenghuan/p/4794514.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM