【模板】Linux中cmake使用编译c++程序

Logger中需要的依赖文件如下:https://download.csdn.net/download/Word_And_Me_/89556265

目录

项目目录结构

CMake配置

主目录 CMakeLists.txt

 src 目录下的 CMakeLists.txt

案例代码整理

main.cpp

Logger.h

Logger.cpp

构建和运行

1、编译项目

2、运行项目

外部包配置

opencv配置


项目目录结构

ProjectRoot/
│── bin/                  # 存放编译后的可执行文件
│── build/                # 编译过程中生成的中间文件
│── includes/             # 存放头文件(.h)
│── libs/                 # 存放依赖库文件
│── logs/                 # 存放日志文件
│── src/                  # 存放源代码(.cpp 和 .h)
│   ├── main.cpp
│   ├── Logger.cpp
│   ├── Logger.h
│── CMakeLists.txt        # 主CMake配置文件
│── README.md             # 项目说明文档

CMake配置

主目录 CMakeLists.txt

cmake_minimum_required(VERSION 3.10)  # 指定项目需要的最低 CMake 版本

project(test_modbus LANGUAGES CXX)  # 指定项目名称和支持的语言

# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 11)  # 设置c++标准版本 11
set(CMAKE_CXX_STANDARD_REQUIRED True)  # 要求项目必须使用C++11标准
set(CMAKE_CXX_EXTENSIONS False)  # 禁用GNU扩展,仅使用严格的C++11标准


# 设置可执行文件输出路径,程序主目录下的bin文件夹
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) 

# 添加外部包含目录
include_directories(${CMAKE_SOURCE_DIR}/includes ${CMAKE_SOURCE_DIR}/src)

# 添加库目录
link_directories(${CMAKE_SOURCE_DIR}/libs)

# 添加子目录
add_subdirectory (src)

 src 目录下的 CMakeLists.txt

aux_source_directory (. SRC_LIST) # 将当前目录下的所有源文件添加到SRC_LIST变量中
# 可更换为显式管理文件:set(SRC_LIST main.cpp module1.cpp module2.cpp)

add_executable(test_modbus ${SRC_LIST}) # 创建可执行文件test_modbus


# 以下配置的include和lib均使用target_ 针对某个生成文件指定链接库

# link threads库
target_link_libraries(test_modbus PRIVATE pthread)


# 查找libmodbus库
find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBMODBUS REQUIRED libmodbus)

# 链接libmodbus库
target_link_libraries(test_modbus PRIVATE ${LIBMODBUS_LIBRARIES})

# 查找opencv
find_package(OpenCV REQUIRED)
target_include_directories(test_modbus PRIVATE ${OpenCV_INCLUDE_DIRS})
target_link_libraries(test_modbus PRIVATE ${OpenCV_LIBS})

# 可用于展示一些需要的信息
# message(STATUS "OpenCV version: ${OpenCV_VERSION}")
# message(STATUS "OpenCV include directories: ${OpenCV_INCLUDE_DIRS}")
# message(STATUS "OpenCV libraries: ${OpenCV_LIBS}")
# message(STATUS "OpenCV library directories: ${OpenCV_LIBRARY_DIRS}")

案例代码整理

main.cpp

#include <iostream>
#include <modbus/modbus.h>
#include <thread>
#include <opencv2/opencv.hpp>
#include <cstring>
#include "Logger.h"

using namespace std;

int main() {
    std::cout << "OpenCV Version: " << CV_VERSION << std::endl;
    initLogger();
    modbus_t* ctx;
    int rc, i;
    logger->info("Modbus test start");
    ctx = modbus_new_tcp("192.168.0.150", 502);
    if (ctx == NULL) {
        logger->error("Unable to allocate libmodbus context");
        return -1;
    }
    cout<<"ctx:"<<ctx<<endl;
    logger->info("Modbus context created");
    //modbus_set_debug(ctx, TRUE); // 开启调试模式
    if (modbus_set_slave(ctx, 1) == -1) {
        logger->error("Failed to set slave ID: {}", modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }
    logger->info("Slave ID set");
    if (modbus_connect(ctx) == -1) {
        logger->error("Connection failed: {}", modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }
    logger->info("Modbus connected");
    // 读取 M1~M10(线圈寄存器,地址 0x0000 起)
    //uint8_t M1_10[15];
    //rc = modbus_read_bits(ctx, 0x0000, 15, M1_10); // 读取 10 个线圈
    //if (rc == -1) {
    //    logger->error("Failed to read M1~M10: {}", modbus_strerror(errno));
    //    modbus_close(ctx);
    //    modbus_free(ctx);
    //    return -1;
    //}

    //std::cout << "M1~M10 values: ";
    //for (int i = 0; i < 15; ++i) {
    //    std::cout << (int)M1_10[i] << " ";
    //}
    //std::cout << std::endl;

    // 读取 Y000~Y004(线圈寄存器,地址 0x3300 起)
    uint8_t Y0_4[5];
    rc = modbus_read_bits(ctx, 0x3300, 5, Y0_4); // 读取 10 个线圈
    if (rc == -1) {
        fprintf(stderr, "Failed to read M1~M10:%s\n", modbus_strerror(errno));
        modbus_close(ctx);
        modbus_free(ctx);
        return -1;
    }

    std::cout << "Y000~Y004 values: ";
    for (int i = 0; i < 5; ++i) {
        std::cout << (int)Y0_4[i] << " ";
    }
    cout << endl;

     修改M1~M10
    //uint8_t writer[15] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
    //uint8_t temp[2];
    //rc = modbus_write_bit(ctx, 0x000b, false);
    //if (rc == -1) {
    //    fprintf(stderr, "Failed to write M11:%s\n", modbus_strerror(errno));
    //    modbus_close(ctx);
    //    modbus_free(ctx);
    //    return -1;
    //}

   logger->info("Modbus test end");
    return 0;
}

Logger.h

// #pragma once
#ifndef LOGGER_H
#define LOGGER_H

#include <iostream>
#include <vector>
#include <memory>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/sinks/rotating_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>

extern std::shared_ptr<spdlog::logger> logger;

void initLogger();

#endif // !LOGGER_H

Logger.cpp

#include "Logger.h"

std::shared_ptr<spdlog::logger> logger;

void initLogger() {
    try {
        std::shared_ptr<spdlog::sinks::rotating_file_sink_mt> file_sink;
        std::shared_ptr<spdlog::sinks::stdout_color_sink_mt> console_sink;
        // 创建彩色控制台 sink
        console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
        console_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%n] [%^%l%$] %v"); // [%^%l%$] 中的 %^ 和 %$ 是颜色标记,%l 是日志级别,这样可以在日志级别部分应用颜色。
        console_sink->set_level(spdlog::level::debug);

        // 创建一个旋转文件日志记录器,每个文件最大10MB,保留10个文件
        // logger_file = spdlog::rotating_logger_mt("running-process", "logs/basic-log.txt", 1024 * 1024 * 10, 10);
        // 创建文件 rotating sink
        file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>("logs/basic-log.txt", 1024 * 1024 * 10, 10);
        // 设置日志记录器的级别
        file_sink->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%n] [%l] %v");
        file_sink->set_level(spdlog::level::debug);

        std::vector<spdlog::sink_ptr> sinks{ console_sink, file_sink };
        logger = std::make_shared<spdlog::logger>("multi_sink", sinks.begin(), sinks.end());
        logger->set_pattern("%^[%Y-%m-%d %H:%M:%S.%e] [%n] [%l] %v%$");
        logger->set_level(spdlog::level::debug);

        spdlog::flush_every(std::chrono::seconds(5));
        spdlog::set_default_logger(logger);
    }
    catch (const spdlog::spdlog_ex& ex) {
        std::cout << "日志初始化失败: " << ex.what() << std::endl;
    }
}

构建和运行

1、编译项目

mkdir build
cd build
cmake ..
make

2、运行项目

./bin/test_modbus

外部包配置

opencv配置

sudo apt-get update
sudo apt-get install libopencv-dev
或
sudo apt update
sudo apt install libopencv-dev

一般会将opencv的include和lib下载至/usr/include 和 /usr/lib中,若找不到对应的依赖包,可以使用find命令查找:find /usr/ -name opencv

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/975444.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

买股票的最佳时机 - 2

买卖股票的最佳时机 III 题目描述&#xff1a; 提示&#xff1a; 1 < prices.length < 1050 < prices[i] < 105 分析过程&#xff1a; 写动态规划&#xff0c;我们需要考虑一下问题&#xff1a; 定义状态状态转移方程初始条件 遍历顺序 4种状态&#xff1a; …

数据分析与算法设计-作业2-拉普拉斯算子空间滤波和增强

作业2 题目 对Flower.dat图像&#xff08;10241024&#xff0c;np.uint8&#xff09;用如下拉普拉斯算子进行空间滤波和增强&#xff1a;np.array([[0, -1, 0], [-1, 4, -1], [0, -1, 0]])&#xff0c;图像边缘采用复制填充方式&#xff0c;不使用其他第三方库&#xff0c;使…

SpringBoot+Vue+微信小程序的猫咖小程序平台(程序+论文+讲解+安装+调试+售后)

感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;我会一一回复&#xff0c;希望帮助更多的人。 系统介绍 在当下这个高速发展的时代&#xff0c;网络科技正以令人惊叹的速度不断迭代更新。从 5G …

基于SpringBoot的二手交易系统

系统展示 用户前台界面 管理员后台界面 系统背景 在当今社会&#xff0c;随着电子商务的蓬勃发展和人们消费观念的转变&#xff0c;二手物品交易逐渐成为了一种新的生活方式。人们越来越倾向于将不再需要的物品进行二次交易&#xff0c;以实现资源的有效利用和环保理念的实践。…

vscode无法预览Markdown在线图片链接

问题&#xff1a;在VSCode中&#xff0c;打开MarkDown文件&#xff0c;存在在线图片链接&#xff0c; 但是在预览时却无法显示。 原因&#xff1a;因为Visual Studio Code中的MarkDown默认配置中只允许载入安全内容 解决方法&#xff1a; 1、输入快捷键 Ctrl Shift P 打开…

Power Query M函数

文章目录 三、PQ高阶技能&#xff1a;M函数3.1 M函数基本概念3.1.1 表达式和值3.1.2 计算3.1.3 运算符3.1.4 函数3.1.5 元数据3.1.6 Let 表达式3.1.6 If 表达式3.1.7 Error 3.2 自定义M函数3.2.1 语法3.2.2 调用定义好的自定义函数3.2.3 直接调用自定义函数3.2.4 自定义函数&am…

election靶机渗透测试

发现靶机ip地址 使用nmap进行扫描端口发现详细信息nmap -T4 -sV -sC -p- 192.168.52.142 用dirsearch扫一下网站的目录 看到一个phpinfo 一个phpmyadmin的登录页面 robots.txt文件 看一下这个election目录下并没有发现什么 继续进行目录扫描&#xff0c;这时候看到一个admin的l…

为AI聊天工具添加一个知识系统 之119 详细设计之60 圣灵三角形和Checker 之2

本文要点 要点回顾 我们回顾一下本题目的讨论内容。 我的想法是&#xff0c; 将Substance 作为 面向服务的架构的起点并基于差异来自下而上地分类 实体--目的是实体职责单一化&#xff0c;将Object作为面向对象的语义差异的系统原点 并沿着差异继承的路径来至上而下地划分对…

安全生产月安全知识竞赛主持稿串词

女:尊敬的各位领导、各位来宾 男:各位参赛选手、观众朋友们 合:大家好&#xff5e; 女:安全是天&#xff0c;有了这一份天&#xff0c;我们的员工就会多一份幸福&#xff0c; 我们的企业就会多一丝光彩。 男:安全是地&#xff0c;有了这一片地&#xff0c;我们的员工就多了一…

五、Three.js顶点UV坐标、纹理贴图

一部分来自1. 创建纹理贴图 | Three.js中文网 &#xff0c;一部分是自己的总结。 一、创建纹理贴图 注意&#xff1a;把一张图片贴在模型上就是纹理贴图 1、纹理加载器TextureLoader 注意&#xff1a;将图片加载到加载器中 通过纹理贴图加载器TextureLoader的load()方法加…

Deepin(Linux)安装MySQL指南

1.下载 地址&#xff1a;https://downloads.mysql.com/archives/community/ 2.将文件解压到 /usr/local 目录下 先cd到安装文件所在目录再解压&#xff0c;本机是cd /home/lu01/Downloads sudo tar -xvJf mysql-9.2.0-linux-glibc2.28-x86_64.tar.xz -C /usr/local3.创建软链…

[MDM 2024]Spatial-Temporal Large Language Model for Traffic Prediction

论文网址&#xff1a;[2401.10134] Spatial-Temporal Large Language Model for Traffic Prediction 论文代码&#xff1a;GitHub - ChenxiLiu-HNU/ST-LLM: Official implementation of the paper "Spatial-Temporal Large Language Model for Traffic Prediction" …

Aseprite绘画流程案例(1)——画相机图标

原图&#xff1a; 步骤一&#xff1a;打开需要参照的图标 步骤二&#xff1a;将参照的图片拖放到右边&#xff0c;作为参考 步骤三&#xff1a;新建24x24的画布&#xff0c;背景为白色的画布 步骤四&#xff1a;点击菜单栏——视图——显示——像素网格&#xff08;如果画布已经…

计算机毕业设计SpringBoot+Vue.js母婴商城(源码+LW文档+PPT+讲解+开题报告)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

Springboot + Ollama + IDEA + DeepSeek 搭建本地deepseek简单调用示例

1. 版本说明 springboot 版本 3.3.8 Java 版本 17 spring-ai 版本 1.0.0-M5 deepseek 模型 deepseek-r1:7b 需要注意一下Ollama的使用版本&#xff1a; 2. springboot项目搭建 可以集成在自己的项目里&#xff0c;也可以到 spring.io 生成一个项目 生成的话&#xff0c;如下…

Android输入事件传递流程系统源码级解析

1. 硬件层到Linux内核 设备节点&#xff1a;触摸事件由内核驱动捕获&#xff0c;写入/dev/input/eventX。关键结构体&#xff1a;input_event&#xff08;包含时间戳、类型、代码、值&#xff09;。 2. Native层处理&#xff08;system_server进程&#xff09; 2.1 EventHub …

贪心算法

int a[1000], b5, c8; swap(b, c); // 交换操作 memset(a, 0, sizeof(a)); // 初始化为0或-1 引导问题 为一个小老鼠准备了M磅的猫粮&#xff0c;准备去和看守仓库的猫做交易&#xff0c;因为仓库里有小老鼠喜欢吃的五香豆&#xff0c;第i个房间有J[i] 磅的五香豆&#xf…

HDFS Java 客户端 API

一、基本调用 Configuration 配置对象类&#xff0c;用于加载或设置参数属性 FileSystem 文件系统对象基类。针对不同文件系统有不同具体实现。该类封装了文件系统的相关操作方法。 1. maven依赖pom.xml文件 <dependency><groupId>org.apache.hadoop</groupId&g…

Scrum方法论指导下的Deepseek R1医疗AI部署开发

一、引言 1.1 研究背景与意义 在当今数智化时代&#xff0c;软件开发方法论对于项目的成功实施起着举足轻重的作用。Scrum 作为一种广泛应用的敏捷开发方法论&#xff0c;以其迭代式开发、快速反馈和高效协作的特点&#xff0c;在软件开发领域占据了重要地位。自 20 世纪 90 …

网络工程知识笔记

1. 什么是网络&#xff1f; 网络是由多个节点&#xff08;如计算机、打印机、路由器等&#xff09;通过物理或逻辑连接组成的系统&#xff0c;用于数据的传输和共享。这些节点可以通过有线&#xff08;如以太网&#xff09;或无线&#xff08;如 Wi-Fi&#xff09;方式进行连接…