一、語言:
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