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

ubuntu/vscode下的c/c++开发之-CMake语法与练习

Cmake学习

1 语法特性介绍

  • 基本语法格式:指令(参数 1 参数 2...)

    • 参数使用括弧括起
    • 参数之间使用空格分号分开
  • 指令是大小写无关的,参数和变量是大小写相关的

    set(HELLO hello.cpp)
    add_executable(hello main.cpp hello.cpp)
    ADD_EXECUTABLE(hello main.cpp ${HELLO})
    
  • 变量使用${}方式取值,但是在 IF 控制语句中是直接使用变量名 if (HELLO)

2重要指令和CMake常用变量

2.1 重要指令
  • cmake_minimum_required ,指定CMake的最小版本要求

    # CMake最小版本要求为2.8.3
    cmake_minimum_required(VERSION 2.8.3)
    
    • 语法: cmake_minimum_required(VERSION versionNumber [FATAL_ERROR])
  • project 定义工程名称,并可指定工程支持的语言

    # 指定工程名为HELLOWORLD
    project(HELLOWORLD)
    
    • 语法: project(projectname [CXX] [C] [Java])
  • set 显式的定义变量

    # 定义SRC变量,其值为sayhello.cpp hello.cpp
    set(SRC sayhello.cpp hello.cpp)
    
    • 语法:set(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
  • include_directories 向工程添加多个特定的头文件搜索路径 --->相当于指定g++编译器的 -I 参数。语法: include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)

        直接写 include,不写绝对路径,即相对于cmakelists文件所在的路径

  • link_directories 向工程添加多个特定的库文件搜索路径 --->相当于指定g++编译器的-L参数

    # 将/usr/lib/mylibfolder 和 ./lib 添加到库文件搜索路径
    link_directories(/usr/lib/mylibfolder ./lib)
    

          语法: link_directories(dir1 dir2 ...)

  • add_library 生成库文件

    # 通过变量 SRC 生成 libhello.so 共享库
    add_library(hello SHARED ${SRC})
    
    • 语法: add_library(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN)
  • add_compile_options 添加编译参数

    # 添加编译参数 -Wall -std=c++11 -O2
    add_compile_options(-Wall -std=c++11 -O2)
    

  • add_executable 生成可执行文件

    # 编译main.cpp生成可执行文件main
    add_executable(main main.cpp)
    
    • 语法:add_executable(exename source1 source2 ... sourceN)

  • target_link_libraries 为 target 添加需要链接的共享库 -->相同于指定g++编译器-l参数

    # 将hello动态库文件链接到可执行文件main
    target_link_libraries(main hello)
    
    • 语法: target_link_libraries(target library1<debug | optimized> library2...)
  • add_subdirectory 向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置

    # 添加src子目录,src中需有一个CMakeLists.txt
    add_subdirectory(src)
    

        语法: add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

使用案例,推荐查看下面链接的第五章节:

Linux下CMake简明教程_linux cmake-CSDN博客

  • aux_source_directory 发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指令临时被用来自动构建源文件列表

    • 语法: aux_source_directory(dir VARIABLE)
    # 定义SRC变量,其值为当前目录下, 所有的源代码文件
    aux_source_directory(. SRC)
    # 编译SRC变量所代表的源代码文件,生成main可执行文件
    add_executable(main ${SRC})
    
2.2 CMake常用变量
  • CMAKE_C_FLAGS  gcc编译选项

  • CMAKE_CXX_FLAGS  g++编译选项

    # 在CMAKE_CXX_FLAGS编译选项后追加-std=c++11
    set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
    
  • CMAKE_BUILD_TYPE  编译类型(Debug, Release)

    # 设定编译类型为debug,调试时需要选择debug
    set(CMAKE_BUILD_TYPE Debug)
    # 设定编译类型为release,发布时需要选择release
    set(CMAKE_BUILD_TYPE Release)
    
  • CMAKE_BINARY_DIR

    PROJECT_BINARY_DIR

    <projectname>_BINARY_DIR

    这三个变量指代的内容是一致的。如果是 in source build,指的就是工程顶层目录路径。如果是 out-of-source 编译,指的是工程编译发生的目录路径。

  • CMAKE_SOURCE_DIR

    PROJECT_SOURCE_DIR

        <projectname>_SOURCE_DIR

        这三个变量指代的内容是一致的,不论采用何种编译方式,都是指工程顶层目录的绝对你路径。

        例如: include_directories(${CMAKE_SOURCE_DIR}/include)

        当我们想指明我们头文件所在的位置时,可以借用CMAKE_SOURCE_DIR宏,先导航到你的代码工程文件的绝对路径。

使用示例:

include_directories(${CMAKE_SOURCE_DIR}/include)
  • CMAKE_C_COMPILER:指定C编译器
  • CMAKE_CXX_COMPILER:指定C++编译器
  • EXECUTABLE_OUTPUT_PATH:可执行文件输出的存放路径
  • LIBRARY_OUTPUT_PATH:库文件输出的存放路径

3 CMake编译工程

CMake目录结构:项目主目录存在一个CMakeLists.txt文件

两种方式设置编译规则

  1. 包含源文件的那个子文件夹包含CMakeLists.txt文件,主目录的CMakeLists.txt通过add_subdirectory添加子目录即可;
  2. 包含源文件的子文件夹未包含CMakeLists.txt文件,子目录编译规则体现在主目录的CMakeLists.txt中;
3.1 编译流程

在 linux 平台下使用 CMake 构建C/C++工程的流程如下:

  • 手动编写 CMakeLists.txt。
  • 执行命令 cmake PATH生成 Makefile ( PATH 是顶层CMakeLists.txt 所在的目录 )。
  • 执行命令make 进行编译。
# important tips
.  		# 表示当前目录
./ 		# 表示当前目录..  	# 表示上级目录
../ 	# 表示上级目录
3.2 两种构建方式
  • 内部构建(in-source build):不推荐使用

    内部构建会在同级目录下产生一大堆中间文件,这些中间文件并不是我们最终所需要的,和工程源文件放在一起会显得杂乱无章。

    ## 内部构建# 在当前目录下,编译本目录的CMakeLists.txt,生成Makefile和其他文件
    cmake .
    # 执行make命令,生成target
    make
    
  • 外部构建(out-of-source build):推荐使用

    将编译输出文件与源文件放到不同目录中,(源cmakelist放在一级项目文件夹里面,再在一级项目文件夹里新建一个 build文件夹,存放cmakelist执行输出的makefile等生成文件,不使得项目结构杂乱

    ## 外部构建# 1. 在当前目录下,创建build文件夹
    mkdir build
    # 2. 进入到build文件夹
    cd build
    # 3. 编译上级目录的CMakeLists.txt,生成Makefile和其他文件
    cmake ..
    # 4. 执行make命令,生成target
    make
    

4【实战】CMake代码实践

4.1 最小CMake工程
4.1.1 项目代码

项目文件只有一个,就是一个helloworld.cpp

4.1.2 cmake工程 

1)在helloworld.cpp文件夹下,新建一个CMakeList.txt,一个build文件夹

2)CMakeLists.txt文件内写入如下内容(注意写指令借助tab)

3)在build 目录下执行 cmake . .;会发现 build文件夹 下生成许多cmake工程文件,包括makefile

4)在 build目录下执行makefile;该目录下会生成 最终可执行的目标二进制文件。

CMakeLists.txt:

# Set the minimum version of CMake that can be used
cmake_minimum_required(VERSION 3.0)# Set the project name
project (HELLO)# Add an executable
add_executable(hello_cmake main.cpp)
4.2 多目录工程

//mian.cpp
#include "swap.h"int main() {swap obj_ab(2,3);obj_ab.print_info();obj_ab.run();obj_ab.print_info();
}
//swap.h	
#pragma once
#include <iostream>class swap
{
private:int a, b;
public:swap(int a, int b){this->a = a;this->b = b;}void run();void print_info();
};
//swap.cpp
#include "swap.h"void swap::run() {int temp;temp = a;a = b;b = temp;
}void swap::print_info() {std::cout << "a = " << a << std::endl;std::cout << "b = " << b << std::endl;
}

4.2.1 多目录工程-直接编译

这个案例直接编译的cmakelists的写法和上面的helloworld案例的套路基本上一样,区别就是多了一个指定头文件、练习使用下set。 

CMakeLists.txt:

cmake_minimum_required(VERSION 3.0)project(SWAP)include_directories(include)set(SOURCES main.cpp src/swap.cpp)add_executable(swap_cmake ${SOURCES})

编译后的工程结构: 

.
├── build
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   │   ├── 3.22.1
│   │   │   ├── CMakeCCompiler.cmake
│   │   │   ├── CMakeCXXCompiler.cmake
│   │   │   ├── CMakeDetermineCompilerABI_C.bin
│   │   │   ├── CMakeDetermineCompilerABI_CXX.bin
│   │   │   ├── CMakeSystem.cmake
│   │   │   ├── CompilerIdC
│   │   │   │   ├── a.out
│   │   │   │   ├── CMakeCCompilerId.c
│   │   │   │   └── tmp
│   │   │   └── CompilerIdCXX
│   │   │       ├── a.out
│   │   │       ├── CMakeCXXCompilerId.cpp
│   │   │       └── tmp
│   │   ├── cmake.check_cache
│   │   ├── CMakeDirectoryInformation.cmake
│   │   ├── CMakeOutput.log
│   │   ├── CMakeTmp
│   │   ├── main_cmake.dir
│   │   │   ├── build.make
│   │   │   ├── cmake_clean.cmake
│   │   │   ├── compiler_depend.make
│   │   │   ├── compiler_depend.ts
│   │   │   ├── DependInfo.cmake
│   │   │   ├── depend.make
│   │   │   ├── flags.make
│   │   │   ├── link.txt
│   │   │   ├── main.cpp.o
│   │   │   ├── main.cpp.o.d
│   │   │   ├── progress.make
│   │   │   └── src
│   │   │       ├── swap.cpp.o
│   │   │       └── swap.cpp.o.d
│   │   ├── Makefile2
│   │   ├── Makefile.cmake
│   │   ├── progress.marks
│   │   ├── swap_cmake.dir
│   │   │   ├── build.make
│   │   │   ├── cmake_clean.cmake
│   │   │   ├── compiler_depend.make
│   │   │   ├── compiler_depend.ts
│   │   │   ├── DependInfo.cmake
│   │   │   ├── depend.make
│   │   │   ├── flags.make
│   │   │   ├── link.txt
│   │   │   ├── main.cpp.o
│   │   │   ├── main.cpp.o.d
│   │   │   ├── progress.make
│   │   │   └── src
│   │   │       ├── swap.cpp.o
│   │   │       └── swap.cpp.o.d
│   │   └── TargetDirectories.txt
│   ├── cmake_install.cmake
│   ├── Makefile
│   └── swap_cmake
├── CMakeLists.txt
├── include
│   └── swap.h
├── main.cpp
└── src└── swap.cpp

4.2.2 多目录工程-src做成(静态/动态)库,间接编译 

4.2.2.1 src分别做成 动态库(.so)/ 静态库(.a)

        直接在项目文件的一级目录修改cmakelists.txt的内容,先忽略 main.cpp,把src做成静态库或者动态库,保存在 /usr/lib 中。

cmake_minimum_required(VERSION 3.0)project(SWAP)include_directories(include)set(SOURCES src/swap.cpp)add_library(SwapTest SHARED ${SOURCES})
add_library(SwapTest STATIC ${SOURCES})set (LIBRARY_OUTPUT_PATH /usr/lib)

4.2.2.2 使用静态库或动态库

        再次在项目文件的一级目录修改cmakelists.txt的内容,编译 main.cpp,并链接所需要的库。生成最终可执行二进制。

cmake_minimum_required(VERSION 3.0)project(SWAP_TEST)include_directories(include)#选择链接静态库或者动态库
#set (PROJECT_LINK_LIBS /usr/lib/libswapTest_shared.so)
set (PROJECT_LINK_LIBS /usr/lib/libswapTest_static.a)add_executable(swap_cmake main.cpp)target_link_libraries (swap_cmake ${PROJECT_LINK_LIBS})# libswapTest_shared.so
# libswapTest_static.a
4.3 更完整的项目c++开发过程

案例名称:士兵突击

需求列表:

  1. 士兵 许三多 有一把,叫做 AK47
  2. 士兵 可以 开火
  3. 士兵 可以 给枪装填子弹
  4. 能够 发射 子弹
  5. 能够 装填子弹 —— 增加子弹数量

开发过程:

  • 开发枪类
  • 开发士兵类
4.3.1 合理设置项目目录

//Gun.h
#pragma once
#include <string>class Gun
{
public:Gun(std::string type){this->_bullet_count = 0;this->_type = type;}void addBullet(int bullet_num);bool shoot();private:int _bullet_count;std::string _type;};
//Soldier.h
#pragma once#include <string>
#include "Gun.h"class Solider
{
public:Solider(std::string name);~Solider();void addGun(Gun *ptr_gun);void addBulletToGun(int num);bool fire();private:std::string _name;Gun *_ptr_gun;
};
4.3.2 编写项目源文件
//Gun.cpp
#include "Gun.h"
#include "iostream"
using namespace std;void Gun::addBullet(int bullet_num)
{this->_bullet_count += bullet_num;
}bool Gun::shoot()
{if (this->_bullet_count<=0){cout << "There is no bullet!" << endl;return false;}this->_bullet_count -= 1;cout << "shoot successfully!" << endl;return true;}
//Soldier.cpp
#include "Soldier.h"Solider::Solider(std::string name)
{this->_name = name;this->_ptr_gun = nullptr;
}void Solider::addGun(Gun *ptr_gun)
{this->_ptr_gun = ptr_gun;
}void Solider::addBulletToGun(int num)
{this->_ptr_gun->addBullet(num);
}bool Solider::fire()
{return(this->_ptr_gun->shoot());
}Solider::~Solider()
{if (this->_ptr_gun==nullptr){return;}delete this->_ptr_gun;this->_ptr_gun = nullptr;}
#include "Gun.h"
#include "Soldier.h"
#include <iostream>void test()
{Solider sanduo("xusanduo");sanduo.addGun(new Gun("AK47"));sanduo.addBulletToGun(20);sanduo.fire();
}int main()
{std::cout << "This is a test string..." << std::endl;std::cout << "This is a test string..." << std::endl;test();return 0;
}
4.3.3 编写CMakeLists.txt
cmake_minimum_required(VERSION 3.0)project(SOLIDERFIRE)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")set(CMAKE_BUILD_TYPE Debug)include_directories(${CMAKE_SOURCE_DIR}/include)add_executable(my_cmake_exe main.cpp src/Gun.cpp src/Solider.cpp)
4.3.4 编译CMake项目

操作和4.1完全相同。

        这里强调一点,当我们随着代码的迭代开发,要修改项目中的文件,重新编译获得可执行文件时,我们只需要重新make一下。注意:这个时候只会重新编译你修改的文件。这一点非常重要,对于大型项目的编译时间。

makefile和CMakeLists使用区别与联系

CMake主要是编写CMakeLists.txt文件,然后用cmake命令将CMakeLists.txt文件转化为make所需要的makefile文件,最后用make命令编译源码生成可执行程序或共享库。

简单来说:

makefile里面封装的是最底层的gcc/g++编译命令、编译参数、文件之间的依赖关系等;

CMakeLists.txt 则在makefile基础上更抽象了一层,使得项目编译工程的书写更简洁。

二者关系如下图:

  6.1Cross-platform development 6.2 语法特性介绍_哔哩哔哩_bilibili

更详细的:

        CMake是一个跨平台的自动化构建系统,可以用于管理和构建项目的源代码,比make更为高级。而Makefile是一种构建工具,用于自动化构建可执行文件和库。CMake可以生成Makefile,但是CMake不仅仅可以生成Makefile,还可以生成Visual Studio项目、Xcode项目等。因此,CMake可以完全代替Makefile使用。

CMake的使用场景包括但不限于以下几种:

  1. 跨平台构建:CMake可以在不同的平台上生成相应的构建文件,使得项目可以在不同的平台上构建。在 Linux/Unix 平台,生成 makefile,在苹果平台,可以生成 xcode,在 Windows 平台,可以生成 MSVC 的工程文件。想像如果平台的构建工程使用 makefile构建,换平台将会很麻烦。
  2. 管理大型项目:CMake可以管理大型项目的构建,包括多个子目录和库的构建。
  3. 自定义构建:CMake可以根据用户的需求自定义构建过程,包括编译选项、链接选项等。

而Makefile的使用场景包括但不限于以下几种:

  1. 简单项目构建:对于简单的项目,使用Makefile可以快速构建可执行文件和库。
  2. 熟悉Unix/Linux环境:Makefile是Unix/Linux环境下的标准构建工具,熟悉Makefile可以更好地理解Unix/Linux环境下的构建过程。
  3. 自定义构建:Makefile可以根据用户的需求自定义构建过程,包括编译选项、链接选项等。

因此,CMake适用于大型、跨平台的项目,而Makefile适用于简单的项目和熟悉Unix/Linux环境的用户。

学习参考:

6.1Cross-platform development 6.2 语法特性介绍_哔哩哔哩_bilibiliNotion – The all-in-one workspace for your notes, tasks, wikis, and databases.

认识Make、Makefile、CMake和CMakeLists_cmakelists makefile-CSDN博客 ​ 

CMake入门教程_cmake -dgcov=on -dcmake_build_type=debug-CSDN博客

Linux下CMake简明教程_linux cmake-CSDN博客

相关文章:

ubuntu/vscode下的c/c++开发之-CMake语法与练习

Cmake学习 1 语法特性介绍 基本语法格式&#xff1a;指令(参数 1 参数 2...) 参数使用括弧括起参数之间使用空格或分号分开 指令是大小写无关的&#xff0c;参数和变量是大小写相关的 set(HELLO hello.cpp) add_executable(hello main.cpp hello.cpp) ADD_EXECUTABLE(hello ma…...

Java(119):ExcelUtil工具类(org.apache.poi读取和写入Excel)

ExcelUtil工具类(XSSFWorkbook读取和写入Excel),入参和出参都是:List<Map<String,Object>> 一、读取Excel testdata.xlsx 1、new XSSFWorkbook对象 File file = new File(filePath); FileInputStream fis = new FileInputStream(file);…...

Kong处理web服务跨域

前言 好久没写文章了&#xff0c;大概有半年多了&#xff0c;这半年故事太多&#xff0c;本文写不下&#xff0c;就写写文章标题问题&#xff01; 问题描述 关于跨域的本质问题我这里不过多介绍&#xff0c;详细请看历史文章 跨域产生的原因以及常见的解决方案。 我这边是新…...

Kotlin学习——kt里的作用域函数scope function,let,run,with,apply,also

Kotlin 是一门现代但已成熟的编程语言&#xff0c;旨在让开发人员更幸福快乐。 它简洁、安全、可与 Java 及其他语言互操作&#xff0c;并提供了多种方式在多个平台间复用代码&#xff0c;以实现高效编程。 https://play.kotlinlang.org/byExample/01_introduction/02_Functio…...

informer辅助笔记:utils/timefeatures.py

定义了一套与时间特征相关的类和函数&#xff0c;旨在从时间序列数据中提取有用的时间特征&#xff0c;以支持各种时间序列分析和预测任务 from typing import Listimport numpy as np import pandas as pd from pandas.tseries import offsets from pandas.tseries.frequenc…...

[Verilog语法]:===和!==运算符使用注意事项

[Verilog语法]&#xff1a;和!运算符使用注意事项 1&#xff0c; 和 !运算符使用注意事项2&#xff0c;3&#xff0c; 1&#xff0c; 和 !运算符使用注意事项 参考文献&#xff1a; 1&#xff0c;[SystemVerilog语法拾遗] 和!运算符使用注意事项 2&#xff0c; 3&#xff0c;...

mybatis 高并发查询性能问题

场景&#xff1a; 使用Mybatis &#xff08;3.5.10&#xff09;SelectProvider注解执行动态sql 在高并发查询时 QPS 很低 问题复现 mybatis 配置 &#xff08;getOfflineConfigSqlTemplate 该方法返回的是动态sql &#xff09; 压测结果 观察线程阻塞情况 此时的QPS 在 …...

我在Vscode学OpenCV 图像处理一(阈值处理、形态学操作【连通性,腐蚀和膨胀,开闭运算,礼帽和黑帽,内核】)

文章目录 一、阈值处理1.1 OpenCV 提供了函数 cv2.threshold()和函数 cv2.adaptiveThreshold()&#xff0c;用于实现阈值处理1.1.1. cv2.threshold()&#xff1a;(1)在函数cv2.threshold()中&#xff0c;参数threshold_type用于指定阈值处理的方式。它有以下几种可选的阈值类型…...

Yolov8实现瓶盖正反面检测

一、模型介绍 模型基于 yolov8n数据集采用SKU-110k&#xff0c;这数据集太大了十几个 G&#xff0c;所以只训练了 10 轮左右就拿来微调了 基于原木数据微调&#xff1a;训练 200 轮的效果 10 轮SKU-110k 20 轮原木 200 轮瓶盖正反面 微调模型下载地址https://wwxd.lanzouu.co…...

GAN:WGAN前作

WGAN前作&#xff1a;有原则的方法来训练GANs 论文&#xff1a;https://arxiv.org/abs/1701.04862 发表&#xff1a;ICLR 2017 本文是wgan三部曲的第一部。文中并没有引入新的算法&#xff0c;而是标是朝着完全理解生成对抗网络的训练动态过程迈进理论性的一步。 文中基本是…...

数据库应用:MongoDB 文档与索引管理

目录 一、理论 1.MongoDB文档管理 2.MongoDB索引管理 二、实验 1.MongoDB文档管理 2.MongoDB索引管理&#xff08;索引添加与删除&#xff09; 3.MongoDB索引管理&#xff08;全文索引&#xff09; 4.MongoDB索引管理&#xff08;多列索引&#xff09; 5.MongoDB索引管…...

Python批处理PDF文件,PDF附件轻松批量提取

PDF附件是指在PDF文档中嵌入的其他文件&#xff0c;如图像、表格、音频、视频或其他文档。这些附件可以与PDF文档一起存储、传输和共享&#xff0c;为文档提供了更丰富的内容和更多的功能。通过添加附件&#xff0c;我们可以将相关文件和信息捆绑在一起&#xff0c;使其更易于管…...

Python可迭代对象排序:深入排序算法与定制排序

更多Python学习内容&#xff1a;ipengtao.com 排序在计算机科学中是一项基础而关键的操作&#xff0c;而Python提供了强大的排序工具来满足不同场景下的排序需求。本文将深入探讨Python中对可迭代对象进行排序的方法&#xff0c;涵盖基础排序算法、sorted函数的应用、以及定制排…...

基于matlab的图像去噪算法设计与实现

摘 要 随着我们生活水平的提高&#xff0c;科技产品飞速更新换代&#xff0c;在信息传输中&#xff0c;图像传输所占的比重越来越大。但自然噪声会在图像传输时干扰其传输过程&#xff0c;甚至会使图片不能表达其原来的意义。去噪处理就是为了去除图像中的噪声&#xff0c;从而…...

NFTScan 正式上线 Starknet NFTScan 浏览器和 NFT API 数据服务

2023 年 11 月 30 号&#xff0c;NFTScan 团队正式对外发布了 Starknet NFTScan 浏览器&#xff0c;将为 Starknet 生态的 NFT 开发者和用户提供简洁高效的 NFT 数据搜索查询服务。NFTScan 作为全球领先的 NFT 数据基础设施服务商&#xff0c;Starknet 是继 Bitcoin、Ethereum、…...

2023年亚太杯APMCM数学建模大赛A题水果采摘机器人的图像识别

2023年亚太杯APMCM数学建模大赛 A题 水果采摘机器人的图像识别 原题再现 中国是世界上最大的苹果生产国&#xff0c;年产量约3500万吨。同时&#xff0c;中国也是世界上最大的苹果出口国&#xff0c;世界上每两个苹果中就有一个是中国出口的&#xff0c;世界上超过六分之一的…...

mysql which is not in SELECT list; this is incompatible with DISTINCT解决方案

mysql报错Expression #1 of ORDER BY clause is not in SELECT list, references column ‘xxx’ which is not in SELECT list; this is incompatible with DISTINCT解决方案&#xff1a; 这是在 mysql5.7 版本&#xff0c;DISTINCT 与 order by 在一起用时则会报3065错误。因…...

linux /proc 文件系统

/proc系统是一个伪文件系统&#xff0c;它只存在内存当中&#xff0c;而不占用外存空间&#xff0c;以文件系统的方式为内核与进程提供通信的接口。 /proc目录下有很多以数字命名的目录&#xff0c;每个数字代表进程号PID它们是进程目录。系统中当前运行的每一个进程在/proc下都…...

java开发之个微群聊自动添加好友

请求URL&#xff1a; http://域名/addRoomMemberFriend 请求方式&#xff1a; POST 请求头Headers&#xff1a; Content-Type&#xff1a;application/jsonAuthorization&#xff1a;login接口返回 参数&#xff1a; 参数名必选类型说明wId是String登录实例标识chatRoom…...

Git .gitignore 忽略文件不生效解决方法

.gitignore 匹配规则 *.sample    # 忽略所有 .sample 结尾的文件 !lib.sample    # 但 lib.sample 除外 /TODO    # 仅仅忽略项目根目录下的 TODO 文件&#xff0c;不包括 subdir/TODO build/    # 忽略 build/ 目录下的所有文件 doc/*.txt    # 会…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

网站指纹识别

网站指纹识别 网站的最基本组成&#xff1a;服务器&#xff08;操作系统&#xff09;、中间件&#xff08;web容器&#xff09;、脚本语言、数据厍 为什么要了解这些&#xff1f;举个例子&#xff1a;发现了一个文件读取漏洞&#xff0c;我们需要读/etc/passwd&#xff0c;如…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...