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
   https://github.com/dev-cafe/cmake-cookbook
 https://www.mianshigee.com/tutorial/CMake-Cookbook/
posted @ 2022-05-07 18:01  辰令  阅读(187)  评论(0编辑  收藏  举报