zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    数据库中的Convert
    xml Data Type Methods in sql server
    WITH common_table_expression (Transact-SQL)
    NuGet配置代理
    SQL Source Control
    3线-8线译码器
    git commit template
    PowerShell中和服务相关的命令
    how to backup and restore database of SQL Server
    上升时间最长的序列
  • 原文地址:https://www.cnblogs.com/ytwang/p/14890288.html
Copyright © 2011-2022 走看看