• C++_分离编译与Cmake


    C++工程结构

    目录结构

    小型项目, 可以简单地将 .h 与 .c 这两类源文件分别归纳在两个独立的目录 include 与 src 中
    稍微大一些的项目  能够以模块为单位,以库的形式进行抽象的实现,可以统一放在名为 libs 的目录下进行管理
    

    项目的编译流程

    01.GCC命令行编译  文件 src/main.c 为程序入口 main 函数的所在文件
    02.使用 Makefile 进行结构化编译
    03.使用 CMake 进行跨平台的自动化构建  CMake(Cross-platform Make)
     
    静态库 --动态库  共享链接库
      Linux下的共享链接库主要放在/lib目录下,以lib*.so.*为典型的文件
    

    文件目录

    build
    config
      -- config_test.yaml
    include
      -- read_from_yaml.h
    src
      -- main.cpp
      -- read_from_yaml.cpp
    CMakeLists.txt
    0_build.sh
    1_run.sh
    

    各自内容

     内容详解
    

    config_test.yaml

    %YAML:1.0
    name: 'test'
    grade: 12
    score: 9.1
    input_path: '../data/test.txt'	
    

    read_from_yaml.h

    // include guard 
    #ifndef IMG_DATA_READ_H
    #define IMG_DATA_READ_H
    
    #include <iostream>
    #include <vector>
    #include <string>
    #include <cstring>
    #include <opencv2/opencv.hpp>
    #include <opencv2/core.hpp>
    using namespace std;
    
    typedef struct Params_in{
    std::string name;
    int grade;
    float score;
    std::string input_path;
    } Params;
    bool read_param_from_yaml(std::string yaml_f_nm, Params &in_params);
    void show_param(Params &in_params);
    #endif		 
    

    read_from_yaml.cpp

    #include "read_from_yaml.h"
    bool read_param_from_yaml(std::string yaml_f_nm, Params &in_params)
    {
        cv::FileStorage file_conf(yaml_f_nm,cv::FileStorage::READ);
        if(! file_conf.isOpened() ){
            std::cout << "Failed open " << yaml_f_nm  <<  endl;
            return false;
        }
        else stf:cout << "Success open " << yaml_f_nm  << endl;
        file_conf["name"] >> in_params.name ;
        file_conf["grade"] >> in_params.grade ;
        file_conf["score"] >> in_params.score ;
        file_conf["input_path"] >> in_params.input_path ;
        //file_conf.release()
        return true;
    }
    void show_param(Params &in_params)
    {
     std::cout << "name " << in_params.name <<  endl;
     std::cout << "grade " << in_params.grade <<  endl;
     std::cout << "score " << in_params.score <<  endl;
     std::cout << "input_path " << in_params.input_path <<  endl;
    }
    

    main.cpp

    #include <iostream>
    #include <vector>
    #include <string>
    #include <cstring>
    #include <opencv2/opencv.hpp>
    #include <opencv2/core.hpp>
    #include "read_from_yaml.h"
    using namespace std;
    
    int main(int argc, char** argv)
    {
        std:string cfg_path = "./config/config_test.yaml";
        Params in_params;
        if(! read_param_from_yaml(cfg_path, in_params)){
            return false;
        }
        show_param(in_params);
        return 0;
    }
    

    CMakeLists.txt

    cmake_minimum_required(VERSION 3.0.2)
    set(PROJECT_NAME config_read)
    set(CMAKE_CXX_STANDARD 11)
    set(OpenCV2_DIR /usr/share/OpenCV)
    project(${PROJECT_NAME})
    
    find_package(OpenCV REQUIRED)
    message(STATUS " version: ${OpenCV_VERSION}")
    message(STATUS " libraries: ${OpenCV_LIBS}")
    message(STATUS " includ: ${OpenCV_INCLUDE_DIRS}")
    
    include_directories( 
            ./include
            ${OpenCV_INCLUDE_DIRS}
            ${OpenCV_INCLUDE_DIRS}/opencv2
            )
    link_libraries( ${OpenCV_LIBS})
    ###########
    ## Build ##
    ###########
    
    ## Specify additional locations of header files
    ## Your package locations should be listed before other locations
    include_directories(
      ./include
      ${OpenCV_INCLUDE_DIRS}
    )
    ## Declare a C++ executable
    
    add_executable(${PROJECT_NAME}  src/main.cpp src/read_from_yaml.cpp  )
    ## Specify libraries to link a library or executable target against
    target_link_libraries(${PROJECT_NAME}
      ${OpenCV_LIBRARIES}
    )		 
    

    0_build.sh

    cd build && rm -rf ./* && cmake .. && make all -j16
    

    1_run.sh

    ./build/config_read
    

    执行步骤

    sh  0_build.sh
    sh   1_run.sh
     执行说明
         mkdir build && cd build 创建并进入用于存放编译结果文件的临时目录
     cmake .. 生成本地化构建项目
    

    说明

    静态库与动态库构建
    find_library               ## 该命令用于搜索指定动态文件路径
    add_library                ##  add_library(Hello hello.cxx)  #将hello.cxx编译成静态库如libHello.a
    include_directories        ##  include_directories:指定头文件的搜索路径,相当于指定gcc的-I参数
    link_directories           ## link_directories:动态链接库或静态链接库的搜索路径,相当于gcc的-L参数   link_directories仅对其后面的targets起作用
    add_executable             ## add_executable:编译可执行程序,指定编译--设置二进制目标文件的依赖
    target_include_directories ## 指定目标包含的头文件路径
    target_link_libraries      ## target_link_libraries:添加链接库,相同于指定-l参数
    同一目录,多个源文件
       # 指定生成目标
       add_executable(Demo main.cpp myMath.cpp)
    多个目录,多个源文件
        先将 math 目录里的文件编译成静态库再由 main 函数调用
    	# 添加 math 子目录
           add_subdirectory(math)
    	# 添加链接库
         target_link_libraries(demo MathFunctions)
    	 
    	 子目录 CMakeLists.txt
    	 # 生成链接库  add_library 将 DIR_LIB_SRCS 目录中的源文件编译为静态链接库
        add_library (MathFunctions ${DIR_LIB_SRCS})
    

    参考

     https://docs.opencv.org/3.2.0/d4/da4/group__core__xml.html
  • 相关阅读:
    AJAX和DHTML
    解析xml的4种方法详解
    javascript -window与document 待整理
    JavaScript中的shift()、unshift()和pop()函数
    JS中如何定义全局变量
    j中的substr(start,length)和substring(start,stop)
    JS中的唯一容器:数组
    typeof()和instanceof的用法区别
    JS和DOM的关系
    jQuery对象与DOM对象之间的转换方法
  • 原文地址:https://www.cnblogs.com/ytwang/p/16243115.html
Copyright © 2020-2023  润新知