Linux学习日记22——vscode和cmake

Linux学习日记22——vscode和cmake,第1张

学习视频链接 

基于VSCode和CMake实现C/C++开发 | Linux篇_哔哩哔哩_bilibili倾心打造 | 独具匠心 | 全面综合1. 这是一个将 *** 作系统Linux、编译器GCC、调试器GDB、IDE-VSCode、交叉编译工具CMake综合起来讲解的一个系列教程;2. 本教程把每个知识点中最为重要的干货部分呈现给读者,并以七讲课程的形式将所有知识点串联起来;3. 读者通过本教程能够掌握在Linux系统中使用VSCode和CMake实现C/C++的开发,并且不仅要知其然,还要知其所以https://www.bilibili.com/video/BV1fy4y1b7TC

目录

一、安装相应的软件

1.1 安装cmake

1.2 安装vscode

二、g++编译相关参数

2.1 -g

2.2 -O[n]

2.3 -l 和 -L

2.4 -I

2.5 警告信息

2.6 设置编译标准和输出文件名

2.7 查看手册

三、编译C++项目

3.1 打开vscode

3.2 编写项目

3.3 编译项目

四、CMake

4.1 简介

4.2 语法特性介绍

4.3 重要指令和 CMake 常用变量

4.4 CMake 编译工程

4.5 实战

五、使用vscode进行完整项目开发

5.1 合理设置项目目录、编写编译项目源文件

5.2 编写 CMakeLists.txt 构建项目编译规则、使用外部构建,手动编译 CMake 项目

5.3 配置json文件并调试项目


一、安装相应的软件 1.1 安装cmake

sudo apt update 更新软件包来源

sudo apt install cmake 安装cmake

cmake --version 查看是否安装成功

1.2 安装vscode

 

二、g++编译相关参数 2.1 -g

1、作用

编译带调试信息的可执行文件

2、案例

g++ -g test.cpp -o test

2.2 -O[n]

1、作用

优化源码

2、案例

-O 同时减小代码的长度和执行时间,其效果等价于 -O1

-O0 表示不做优化

-O1 为默认优化

-O2 除了完成 -O1 的优化之外,还进行一些额外的调整工作,如指令调整等

-O3 则包括循环展开和其他一些与处理特性相关的优化工作

选项将使编译的速度比使用 -O 时慢,但通常产生的代码执行速度会更快

g++ -O2 test.cpp -o test

3、测试

 

2.3 -l 和 -L

1、作用

指定库文件 | 指定库文件路径

2、案例

(1) -l 参数(小写)就是用来指定程序要链接的库,-l 参数紧接着就是库名

在 /lib 和 /usr/lib 和 /usr/local/lib 里的库直接用 -l 参数就能链接

链接 glog 库

g++ -lglog test.cpp -o test

(2) 如果库文件没放在上面三个目录里,需要使用 -L 参数(大写)指定库文件所在目录

-L 参数跟着的是库文件所在的目录名

链接 mytest 库,libmytest.so 在 /home/bing/mytestlibfolder 目录下

g++ -L/home/bing/mytestlibfolder -lmytest test.cpp -o test

2.4 -I

1、作用

指定头文件搜索目录

2、案例

/usr/include 目录一般是不用指定的,gcc 知道去那里找,但是如果头文件不在 /usr/icnclude 里我们就要用 -I 参数指定了,比如头文件放在 /myinclude 目录里,那编译命令行就要加上 -I/myinclude 参数了,如果不加你会得到一个 "xxxx.h: No such file or directory" 的错误。-I 参数可以用相对路径,比如头文件在当前目录,可以用 -I . 来指定

g++ -I/myinclude test.cpp -o test

2.5 警告信息

2.6 设置编译标准和输出文件名

2.7 查看手册

man gcc

三、编译C++项目 3.1 打开vscode

3.2 编写项目

3.3 编译项目

四、CMake 4.1 简介

cmake 是一个跨平台的安装编译工具,可以用简单的语句来描述所有平台的安装(编译过程)

CMake 是大部分 C++ 开源项目标配

4.2 语法特性介绍

1、基本语法格式

(1) 指令(参数1 参数2 ...)

        参数使用括弧括起

        参数之间使用空格或分号分开

(2) 指令是大小写无关的,参数和变量是大小写相关的

set(HELLO hello.cpp)
add_executab1e(hello main.cpp hello.cpp)
ADD_EXECUTABLE(he11o main.cpp ${HELLO})


(3) 变量使用 ${} 方式取值,但是在 IF 控制语句中是直接使用变量名

4.3 重要指令和 CMake 常用变量

1、重要指令

(1)cmake_minimum_required    指定 CMake 的最小版本要求

语法:cmake_minimum_required(VERSION versionNumber [FATAL_ERROR])

# CMake 最小版本要求为 2.8.3
2 cmake_minimum_required(VERSION 2.8.3)


(2)project    定义工程名称,并可指定工程支持的语言

语法:project(projectname [CXX] [C] [Java])

# 指定工程名为 HELLOWORLD
project(HELLOWORLD)

(3)set    显式的定义变量

语法:set(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])

# 定义 SRC 变量,其值为 sayhe11o. cpp he11o. cpp
set(SRC sayhel1o.cpp he11o.cpp)


(4)include_directories    向工程添加多个特定的头文件搜索路径 --> 相当于指定 g++ 编译器的 -I 参数

语法:include_directories([AFTER | BEFORE] [SYSTEM] dir1 dir2 ...)

# 将/usr/include/myincludefolder 和./include 添加到头文件搜索路径
include_directories(/usr/include/myincludefo1der ./include)


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

语法:link_directories(dir1 dir2 ....)

# 将/usr/1ib/my1ibfo1der 和./1ib 添加到库文件搜索路径
1ink_directories(/usr/1ib/mylibfolder ./1ib)

(6)add_ library    生成库文件

语法: add_ library(libname [SHARED | STATIC | MODULE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN)

# 通过变量 SRC 生成 libhe11o.so 共享库
add_library(he11o SHARED ${SRC})


(7)add_compile_options   添加编译参数

语法:add_compile_options(

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


(8)add_executable    生成可执行文件

语法:add_library(exename source1 source2 ... sourceN)

# 编译 main.cpp 生成可执行文件 main
add_executable(main main.cpp)

(9)target_link libraries    为 target 添加需要链接的共享库 ---> 相同于指定 g++ 编译器 -I 参数

语法:target link_libraries(target library1 library2...)

# 将 he11o 动态库文件链接到可执行文件 main
target_link_libraries(main he11o) 


(10)add_subdirectory     向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置

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

# 将 he11o 动态库文件链接到可执行文件 main
target_link_libraries(main he11o) 


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

语法:aux_source_directory(dir VARIABLE)

# 定义 SRC 变量,其值为当前目录下所有的源代码文件
aux_source_directory(. SRC)

# 编译 SRC 变量所代表的源代码文件,生成 main 可执行文件
add_executable(main ${SRC})

2、CMake 常用变量

(1)CMAKE_C_FLAGS gcc 编译选项

(2)CMAKE_CXX_FLAGS g++ 编译选项

# 在 CMAKE_CXX_FLAGS 编译选项后追加 -std=c++11
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")


(3)CMAKE_ BUILD TYPE编译类型(Debug, Release)

# 设定编译类型为 debug,调试时需要选择 debug
set(CMAKE_BUILD_TYPE Debug)

# 设定编译类型为 release,发布时需要选择 release
set(CMAKE_BUILD_TYPE Release)


(4)CMAKE_BINARY DIR

PROJECT_BINARY_DIR

_BINARY DIR

a. 这三个变量指代的内容是一致的

b. 如果是 in source build,指的就是工程顶层目录

c. 如果是 out-of-source 编译指的是工程编译发生的目录

d. PROJECT_BINARY_DIR 跟其他指令稍有区别,不过现在,你可以理解为他们是一致的

(5)CMAKE_SOURCE_DIR

PROJECT_SOURCE_DIR

_SOURCE_DIR

a. 这三个变量指代的内容是一 致的,不论采用何种编译方式,都是工程顶层目录

b. 也就是在 in source build 时,他跟 CMAKE_BINARY_DIR 等变量一致

c. PROJECT_SOURCE_DIR 跟其他指令稍有区别,现在,你可以理解为他们是一致的

(6)CMAKE_C_COMPILER:指定 C 编译器

(7)CMAKE_CXX_COMPILER:指定 C++ 编译器

(8)EXECUTABLE_OUTPUT_PATH:可执行文件输出的存放路径

(9)LIBRARY_OUTPUT_PATH:库文件输出的存放路径

4.4 CMake 编译工程

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

两种方式设置编译规则:

a. 包含源文件的子文件夹包含 CMakeLists.txt 文件,主目录的 CMakeLists.txt 通过 add_subdirectory 添加子目录即可;

b. 包含源文件的子文件夹未包含 CMakeLists.txt 文件,子目录编译规则体现在主目录 CMakeLists.txt 中;

1、编译流程

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

a. 手动编写 CmakeLists.txt

b. 执行命令 cmake PATH 生成 Makefile( PATH 是顶层 CMakeLists.txt 所在的目录)

c. 执行命令 make 进行编译

2、两种构建方式

(1)内部构建 (in-source build):不推荐使用

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

# 内部构建

# 在当前目录下,编译本目录的 CMakeLists.txt,生成 Makefile 和其他文件
cmake .

# 执行 make 命令,生成 target
make

(2)外部构建 (out-of-source build):推荐使用将编译输出文件与源文件放到不同目录中

# 外部构建

# 1. 在当前目录下,创建 build 文件夹
mkdir build

# 2. 进入到 bui1d 文件夹
cd build

# 3. 编译上级月录的 CMakeLists.txt,生成 Makefile 和其他文件
cmake

# 4. 执行 make 命令,生成 target
make

4.5 实战

1、编写项目

2、编译

运行可执行文件

 

3、外部构建

 

4、项目编译

五、使用vscode进行完整项目开发

案例:土兵突击

需求:

1. 兵许三多有一把q,叫做 AK47

2. 士兵可以开火

3. 士兵可以给q装填子d

4. q能够发射子d

5. q能够装填子d--增加子d数量

开发:

开发q类

开发士兵类

5.1 合理设置项目目录、编写编译项目源文件

1、设置项目目录

2、编写项目

Gun.h

#pragma once

#include 

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;
};

Gun.cpp

#include "Gun.h"
#include 

using namespace std;

void Gun::addBullet(int bullet_num)
{
    this->_bullet_count += bullet_num;
}

bool Gun::shoot()
{
    if (this->_bullet_count <= 0)
    {
        cout << "Thers is no bullet!" << endl;
        return false;
    }

    this->_bullet_count -= 1;
    cout << "shoot successfully!" << endl;
    return true;
}

Solider.h

#pragma once

#include 
#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;
};

Solider.cpp

#include "Solider.h"

using namespace std;

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;
}

main.cpp

#include "Gun.h"
#include "Solider.h"

void test()
{
    Solider sanduo("xusanduo");
    sanduo.addGun(new Gun("AK47"));
    sanduo.addBulletToGun(20);
    sanduo.fire();
}

int main(void)
{
    test();
    return 0;
}

3、编译项目

5.2 编写 CMakeLists.txt 构建项目编译规则、使用外部构建,手动编译 CMake 项目

 给编译添加参数

5.3 配置json文件并调试项目

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1352566.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-14
下一篇 2022-06-14

发表评论

登录后才能评论

评论列表(0条)

保存