CMake 笔记

文章目录

      • [1. Linux 系统介绍](#1. Linux 系统介绍)
        • [1.1 目录结构](#1.1 目录结构)
        • [1.2 指令与选项](#1.2 指令与选项)
      • [2. GCC 编译器](#2. GCC 编译器)
        • [2.1 编译过程](#2.1 编译过程)
        • [2.2 g++ 重要编译参数](#2.2 g++ 重要编译参数)
        • [2.3 实例](#2.3 实例)
          • [2.3.1 直接编译执行](#2.3.1 直接编译执行)
          • [2.3.2 生成库文件并编译](#2.3.2 生成库文件并编译)
      • [3. GDB 调试器](#3. GDB 调试器)
      • [4. VSCode](#4. VSCode)
      • [5. CMake](#5. CMake)
        • [5.1 语法特性](#5.1 语法特性)
        • [5.2 重要指令和 CMake 常用变量](#5.2 重要指令和 CMake 常用变量)
          • [5.2.1 重要指令](#5.2.1 重要指令)
          • [5.2.2 CMake 常用变量](#5.2.2 CMake 常用变量)
        • [5.3 CMake 编译工程](#5.3 CMake 编译工程)
      • [6 综合应用](#6 综合应用)
        • [6.1 合理设置项目目录](#6.1 合理设置项目目录)
        • [6.2 .json 文件配置](#6.2 .json 文件配置)

1. Linux 系统介绍

1.1 目录结构
  • 相对路径:./:当前目录, ../:上一级目录

  • 绝对路径

1.2 指令与选项

(1)完整的命令格式

复制代码
命令(空格)[选项](空格)[操作对象]    

(2)常用操作命令

  • pwd:打印当前工作目录;

  • ls:列出当前工作目录下所有文件/文件夹名称;

  • cd:切换当前工作目录;

  • mkdir:创建目录;

  • touch:创建新文件,如 touch myfile.txt

  • rm:删除文件/文件夹,且不可恢复,慎用;

    删除当前路径下的 file 文件

    rm file.txt

    删除绝对路径下的 file 文件

    rm /home/file.txt

    删除当前路径下所有文件/文件夹

    rm -rf myfolder

    删除绝对路径下所有文件/文件夹

    rm -rf /home/myfolder

  • cp:复制文件/文件夹到指定位置

  • mv:移动文件到新的位置,或者重命名文件

2. GCC 编译器

实际使用中:

  • 使用 gcc 编译 c 代码

  • 使用 g++ 编译 c++ 代码

2.1 编译过程
  1. 预处理:将头文件包含的内容都展开

    -E 表示编译器仅对输入文件进行

    g++ -E test.cpp -o test .i

注意:-o 表示输出 out,也就是 .cpp 输出为 .i

  1. 编译:生成汇编语言文件

    -S 编译选项告诉 g++ 在为 C++ 代码产生了汇编文件后停止编译

    g++ 产生的汇编语言文件的缺省扩展名为 .s

    g++ -S test.i -o test.s

  2. 汇编:生成二进制文件

    -C 选项告诉 g++ 仅把源代码编译为机器语言的目标代码

    缺省的扩展名为 -o

    g++ -C test.s -o test.o

  3. 链接:生成可执行文件

    生成可执行文件 .bin 文件

    g++ test.o -o test

  4. 实际处理时,直接用

    g++ test.cpp -o test

    ./test

2.2 g++ 重要编译参数

(1)-g 编译带调试信息的可执行文件

复制代码
g++ -g test.cpp -o test

(2)-O[n] 优化源代码,可以提高源代码的运行效率。

复制代码
-O0 表示不作优化
-O1 作默认优化
-O2 除了完成 -O1 的优化外,还进行一些额外的调整工作
-O3 进一步优化

g++ -O2 test.cpp -o test

(3)-l-L :分别指定库文件和库文件路径

(4)-I 指定头文件搜索目录

(5)-std=c++11:设定编译标准

(6)-o:指定输出文件名

g++ test.cpp -o test01

2.3 实例

假设有如下工作目录:

复制代码
.
|------include
|   |___Swap.h
|------main.cpp
|------src
|   |___Swap.cpp
2.3.1 直接编译执行

执行命令

复制代码
g++ main.cpp src/Swap.cpp -Iinclude -o main
./main

-I 后面是头文件目录

也可添加其他编译选项。

2.3.2 生成库文件并编译

就是一段编译好的二进制文件。

1、链接 静态库 生成可执行文件

复制代码
# 进入 src 目录下
cd src

# 汇编,生成 .o 文件
g++ Swap.cpp -C -I../include      // -C 表示汇编生成 Swap.o 文件

# 生成静态库 libSwap.a
ar rs libSwap.a Swap.o

# 回到上级目录
cd ..

# 链接静态库并执行
g++ main.cpp -lSwap -Lsrc -o static_main
./static_mian

2、链接 动态库 生成可执行文件

复制代码
# 进入 src 目录下
cd src

# 生成动态库 libSwap.so
g++ Swap.cpp -I../include -fPIC -shared -o libSwap.so
                               // -shared 表示生成动态库

# 回到上级目录
cd ..

# 链接动态库并执行
g++ mian.cpp -Iinlude -lSwap -Lsrc -o dyna_mian

LD_LIBRARY_PATH = src ./dyna_main

注意执行文件时的区别:静态库的代码在编译的过程中已经载入到可执行文件中,故直接运行即可;而动态库是分开的,只保留接口,需要调用,不在同一目录下时,需添加路径。所以,静态库也会比较大。

Windows 中静态库扩展名为 .lib,动态库扩展名为 .dll

3. GDB 调试器

4. VSCode

5. CMake

5.1 语法特性

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

中间用空格或分号隔开。

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

5.2 重要指令和 CMake 常用变量
5.2.1 重要指令

(1)cmake_mininum_required:指定 CMake 最小版本要求

复制代码
cmake_mininum_required(VERSION 2.8.3)

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

复制代码
project(HELLOWORLD)

(3)set:显式的定义变量

复制代码
# 定义变量 SRC,其值为 hello.cpp、sayhello.cpp
set(SRC hello.cpp sayhello.cpp)

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

复制代码
include_directories(/home/include)

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

复制代码
link_directories(dir1 dir2)

# 绝对路径、相对路径均可
link_directories(/home/myfolder ./lib)

(6)add_library:生成静态库/动态库文件

复制代码
通过变量 SRC 生成libhello.so 共享库
add_library(hello SHARED ${SRC})

这里的 SRC 就是前面定义的变量。

(7)add_compile_options:添加编译参数

复制代码
# 添加编译参数 -wall -std=c++11 -O2
add_compile_options(-wall -std=c++11 -O2)

(8)add_executable:生成可执行文件

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

(9)target_link_libraries:为 target 添加需要链接的共享库,相当于指定 g++ 编译器的 -l 参数

复制代码
# 将 hello 动态库文件链接到可执行文件 main
target_link_libraries(main hello)

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

复制代码
# 添加 src 子目录,src 中需要有一个 CMakeLists.txt
add_subdirectory(src)

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

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

# 编译,并生成 main 可执行文件
add_executale(main ${SRC})
5.2.2 CMake 常用变量
5.3 CMake 编译工程

编译过程:

  • 写 CMakeLists.txt 文件

  • 生成 Makefile 文件

  • 执行命令 make 进行编译

1、最小 CMake 工程

2、多文件 CMake 编译

假设有如下工作目录:

复制代码
.
|------include
|   |___Swap.h
|------main.cpp
|------src
|   |___Swap.cpp

CMakeLists.txt 文件为

复制代码
cmake_mininum_required(VIRSION 3.10)

project(SWAP)

add_directories(include)

add_executable(main main.cpp src/Swap.cpp )

外部构建(这样文件夹更整洁),终端中输入

复制代码
mkdir build
cd build
cmake ..
make
./main

当然,上面也等价于

复制代码
g++ main.cpp src/Swap.cpp -Iinclude -o main
./main

6 综合应用

6.1 合理设置项目目录
复制代码
.
|------build
|------include
|   |___...
|------src
|   |___...
|------main.cpp
|------CMakeLists.txt
6.2 .json 文件配置
相关推荐
maosheng11468 小时前
RHCSA的第一次作业
linux·运维·服务器
wifi chicken9 小时前
Linux 端口扫描及拓展
linux·端口扫描·网络攻击
旺仔.2919 小时前
Linux 信号详解
linux·运维·网络
放飞梦想C9 小时前
CPU Cache
linux·cache
Hoshino.4110 小时前
基于Linux中的数据库操作——下载与安装(1)
linux·运维·数据库
播播资源11 小时前
CentOS系统 + 宝塔面板 部署 OpenClaw源码开发版完整教程
linux·运维·centos
源远流长jerry12 小时前
在 Ubuntu 22.04 上配置 Soft-RoCE 并运行 RDMA 测试程序
linux·服务器·网络·tcp/ip·ubuntu·架构·ip
lay_liu12 小时前
Linux安装redis
linux·运维·redis
寂柒13 小时前
序列化与反序列化
linux·网络
lay_liu14 小时前
ubuntu 安装 Redis
linux·redis·ubuntu