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 文件配置
相关推荐
keep__go1 小时前
Linux 批量配置互信
linux·运维·服务器·数据库·shell
矛取矛求1 小时前
Linux中给普通账户一次性提权
linux·运维·服务器
Fanstay9851 小时前
在Linux中使用Nginx和Docker进行项目部署
linux·nginx·docker
大熊程序猿1 小时前
ubuntu 安装kafka-eagle
linux·ubuntu·kafka
daizikui3 小时前
Linux文件目录命令
linux·运维·服务器
NikitaC3 小时前
ldconfig 和 LD_LIBRARY_PATH 区别
linux·c++
清源妙木真菌3 小时前
Linux:进程概念
linux
许嵩664 小时前
IC 脚本之VIM 记录
linux·编辑器·vim
花生的酱5 小时前
Shell编程之正则表达式与文本处理器
linux·运维·正则表达式