当前位置: 首页 > news >正文

【模板】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

相关文章:

  • 【JavaEE进阶】Spring DI
  • 基于Springboot银行信用卡额度管理系统【附源码】
  • 学术论文翻译
  • 俄罗斯方块
  • 多线程群聊服务器设计
  • 500字理透react的hook闭包问题
  • RPC 框架项目剖析
  • 网络和操作系统基础篇
  • Python pip 缓存清理:全面方法与操作指南
  • 【算法通关村 Day9】二分查找与二叉树的中序遍历
  • 人工智能_大模型092_超简单_win10中安装deepseek_效果非常好_亲测_带RGA功能_桌面版---人工智能工作笔记0237
  • 【2025全网首发B站教程】YOLOv12训练数据集构建:标签格式转换-划分-YAML 配置 避坑指南 | 小白也能轻松玩转目标检测!
  • [oAuth2授权]Web前端+NodeCoze API Web后端程序+Coze授权服务器工作流程架构流程图详解
  • 在Ubuntu下通过Docker部署Nginx服务器
  • 6. Go接口
  • C++双指针:算法优化的“左右互搏术”与高效问题破解全指南
  • 蓝桥杯备赛-基础训练(三)哈希表 day16
  • 力扣-回溯-332 重新安排行程
  • 基于Flask的短视频流量数据可视化系统的设计与实现
  • 高速PCB电源层
  • 新能源车盈利拐点:8家上市车企去年合计净利854亿元,多家扭亏
  • 耶路撒冷发生山火,以防长宣布紧急状态
  • 2025五一档新片电影总票房破亿
  • 奈雪的茶叫停“能喝奶茶就不要喝水”宣传,当地市监称不要误导消费者
  • “人工智能是年轻的事业,也是年轻人的事业”,沪上高校师生畅谈感想
  • 新质观察|重塑低空经济的系统安全观