clion相关资料理解记录

554 阅读11分钟

clion相关资料理解记录

前言

本文为《CUDA与TensorRT部署学习笔记》系列中环境配置篇。本文主要记录主要配置clion中可能会存在的一些问题。

1 clion是用哪个构建工具 ?

CLion​ 使用的是 CMake​。CMake​ 是一个跨平台的自动化构建工具,它可以用于构建各种类型的软件,包括 C/C++​、Java​、Python​ 等。

CLion​ 通过 CMake​ 构建 CUDA​ 应用程序时,会自动生成 Makefile​ 或 Visual Studio ​项目文件。您可以使用这些文件来构建您的应用程序。

如果您想使用 CLion​ 构建 CUDA​ 应用程序,您需要先安装 CMake​ 和 NVIDIA​ 的 CUDA​ 驱动程序和工具包。然后,您可以创建一个 CMake​ 项目文件,并在其中指定 CUDA​ 的相关设置。

以下是一个简单的 CMake​ 项目文件示例:

cmake_minimum_required(VERSION 3.10)
project(my_cuda_project)
find_package(CUDA 11.0 REQUIRED)
add_executable(my_cuda_app my_cuda_app.cu)
target_link_libraries(my_cuda_app CUDA::cudart)

这个项目文件将构建一个名为 my_cuda_app​ 的 CUDA​ 应用程序。应用程序的源代码位于 my_cuda_app.cu ​文件中。

要构建该应用程序,您可以使用以下命令:

​cmake .. 
make​

这将生成一个名为 my_cuda_app​ 的可执行文件。

CLion​ 还提供了一些用于构建 CUDA​ 应用程序的特定功能,例如:

  • CUDA​ 编辑器:提供语法高亮显示、代码自动完成和错误检查等功能。
  • CUDA​ 调试器:支持断点、单步执行、查看变量等功能。
  • CUDA​ 性能分析器:帮助您分析 CUDA​ 应用程序的性能。

2 clion 远程调试原理是什么 ?

CLion的远程调试原理涉及使用GDB(GNU Debugger)来在远程服务器上进行调试。

(1)远程调试原理

  • 服务器端:

    在远程服务器上,确保已安装GDB,并且在构建时生成了调试信息(debug symbols)。

  • 本地端:

    在本地端,配置CLion以使用远程服务器上的GDB。这包括指定远程GDB的路径和调试信息文件的位置。

  • 传输信息:

    当你在CLion中启动远程调试时,CLion会将源代码文件和调试信息文件传输到远程服务器。

  • 远程GDB启动:

    在远程服务器上,CLion通过SSH协议启动GDB,并传递调试信息。

  • 本地GDB与远程GDB通信:

    CLion在本地启动一个GDB客户端,与远程服务器上的GDB服务端建立连接。

  • 调试会话:

    通过连接,CLion可以发送GDB命令(如设置断点、单步执行等)到远程服务器,并接收调试信息。

大白话理解

当你使用CLion进行远程调试时,想象你就像是一个指挥官,而远程服务器就像是你的士兵。你在本地发送命令,士兵(远程服务器)执行这些命令,然后把执行结果告诉你。CLion就是这个指挥官,而GDB就是你们之间的通讯手段,通过它你能在本地看到远程服务器上的程序运行情况。

(2)例子

假设你在本地有一个C++程序,但为了进行更大规模的计算,你决定将它部署在远程服务器上。你希望使用CLion的调试功能,就像在本地一样。

  • 在CLion中,设置远程服务器的GDB路径和调试信息文件的位置。
  • 在本地启动调试,CLion将源代码文件和调试信息传输到远程服务器。
  • CLion在远程服务器上启动GDB,并通过SSH与之通信。
  • 在CLion中下达命令,比如在某一行设置断点。
  • GDB在远程服务器上执行这个命令,程序停在设置的断点处。
  • CLion获取程序的调试信息,将它们传输回本地,然后就可以在本地看到程序的状态,就像它在面前一样。

这样,就能在本地使用CLion的舒适调试环境,实际上是通过GDB在远程服务器上执行和获取调试信息。

3 什么是 GDB 调试器?

(1)GDB理解

GDB 调试器是一个命令行工具,可以帮助我们调试程序。它可以让我们在程序运行时设置断点、单步执行、查看变量值、跟踪函数调用堆栈等。

大白话理解

GDB就像是程序员的神奇放大镜。 当你写一个程序时,有时候会遇到各种各样的问题,比如程序崩溃、逻辑错误等。而GDB就像是一个强大的调查工具,帮你找到问题出现的地方,以及问题的本质是什么。

(2)功能说明

  • 设置断点

断点是 GDB 调试器的一个重要功能。设置断点可以让程序在指定的位置停止执行。

比如,我们有一个简单的程序:

#include <stdio.h>

int main() {
  int a = 10;
  int b = 20;
  int c = a + b;
  printf("c = %d\n", c);
  return 0;
}

我们可以使用以下命令设置断点:

gdb my_program
break main

这将在 main() ​函数的起始位置设置断点。

当我们运行程序时,程序会在 main() ​函数的起始位置停止执行。我们可以使用以下命令查看程序的状态:

gdb> info frame

这将输出以下信息:

#0  main () at my_program.c:5

这表示程序当前正在 my_program.c​ 文件的第 5 行执行。

我们可以使用以下命令单步执行程序:

gdb> step

这将让程序执行下一条指令。

当程序执行到 c = a + b; ​语句时,我们可以使用以下命令查看变量 c​ 的值:

gdb> print c

这将输出以下信息:

$1 = 30

这表示 c 的值为 30。

我们可以使用以下命令继续执行程序:

gdb> continue

这将让程序继续执行,直到下一个断点或程序结束。

  • 单步执行

单步执行是 GDB​ 调试器的另一个重要功能。单步执行可以让程序以单步方式执行,以便我们逐步跟踪程序执行过程。

比如,我们可以使用以下命令让程序单步执行:

gdb> step

这将让程序执行下一条指令。

如果我们想让程序跳过函数调用,可以使用 next​ 命令:

gdb> next

这将让程序执行下一条指令,但跳过函数调用。

  • 查看变量值

GDB​ 调试器可以让我们查看程序中变量的值。

比如,我们可以使用以下命令查看变量 c​ 的值:

gdb> print c

这将输出以下信息:

$1 = 30
  • 跟踪函数调用堆栈

GDB​ 调试器可以让我们跟踪函数调用堆栈。函数调用堆栈是记录程序执行过程中函数调用顺序的结构。

比如,我们可以使用以下命令查看函数调用堆栈:

gdb> bt

这将输出以下信息:

#0 main () at my_program.c:5
#1 0x000000000040062a in __libc_start_main (main=0x00000000004005f0, argc=1, argv=0x7fffffffe4e8, init=, fini=, rtld_fini=, stack_end=0x7fffffffe4e0) at libc.so.6:226

这表示程序当前正在 main() 函数执行, main() 函数是由 __libc_start_main() 函数调用的。

4 怎么理解clion中 Build, Execution, Deployment中ToolChains?

(1)ToolChains选项理解

在 CLion 中的 "Toolchains"(工具链)选项用于配置和管理编译和构建工具的设置。

大白话解释

Toolchains 就像是 CLion 的工作台,你在这里配置你的工具,告诉 CLion 使用哪些工具来编译、构建和调试你的代码。每个变量就是工具台上的一个工具。

(2)原理说明

"Toolchains​" 的原理是将这些配置信息传递给 CLion​ 的构建系统。当你点击构建按钮时,CLion​ 将使用你在 "Toolchains​" 中配置的工具来生成构建文件,然后调用相应的编译器、构建工具和调试器来完成构建、编译和调试的过程。这确保了项目的开发和调试能够使用你指定的工具链进行。

(3)变量说明

image

  • Name(名称):

    • 作用: 为你的工具链起个名字,方便在项目中识别。
    • 例子: 如果你有多个不同版本的 GCC,可以给它们起不同的名字,比如 "GCC 9" 和 "GCC 10"。
  • Credentials(凭证):

    • 作用: 在远程开发环境中,指定连接远程服务器所需的凭证信息,如用户名、密码等。
    • 例子: 如果你的项目需要在远程服务器上构建,你可以在这里设置连接所需的用户名和密码。
  • CMake:

    • 作用: 指定 CMake 的路径,确保 CLion 能够正确使用 CMake 生成构建文件。
    • 例子: 如果你安装了不同版本的 CMake,选择你想要使用的版本的路径。如果你已经成功安装cmake,路径通过命令where cmake即可
  • Build Tool(构建工具):

    • 作用: 指定构建工具的路径,比如 make。
    • 例子: 如果你的项目使用 make 进行构建,选择 make 工具的路径。
  • C Compiler(C 编译器):

    • 作用: 指定用于编译 C 代码的编译器,比如 GCC。
    • 例子: 如果你有多个版本的 GCC,选择你想要使用的版本。
  • C++ Compiler(C++ 编译器):

    • 作用: 指定用于编译 C++ 代码的编译器,比如 G++。
    • 例子: 如果你有多个版本的 G++,选择你想要使用的版本。
  • Debugger(调试器):

    • 作用: 指定用于调试的调试器,比如 GDB。
    • 例子: 如果你有不同版本的 GDB,选择你想要使用的版本。

备注:应该只需要填1-2-3-8即可,剩下会自己检索

5 怎么理解clion中 Build, Execution, Deployment中CMake 选项?

(1)cmake选项理解

CLion 中的 Build, Execution, Deployment 的 CMake 选项用于配置 CMake 构建系统。CMake 是一个构建系统,可以帮助我们构建 C/C++ 项目。

大白话理解

CMake 就像是项目的指挥官,它告诉 CLion 如何构建和组织你的项目。这里的设置就是你给这位指挥官下达的指示,告诉他应该使用哪种构建方式,用什么工具,构建到哪个目录,等等。

(2)变量说明

image

  • Enable profile(是否启用配置文件):

    • 作用: 配置文件是一组命名的生成选项。
    • 例子: 为调试和发布版本创建单独的配置文件,并在需要时在它们之间切换。
  • Name(名称):

    • 作用: 为你的 CMake 配置起个名字,方便在项目中识别。
    • 例子: 如果你有多个不同的构建配置,比如 "Debug" 和 "Release",给它们起不同的名字。
  • Build type(构建类型):

    • 作用: 指定构建的类型,比如 "Debug" 或 "Release"。
    • 例子: 如果你想要构建调试版本,选择 "Debug";如果是发布版本,选择 "Release"。
  • Toolchain(工具链):

    • 作用: 指定使用的工具链,即编译器和其他构建工具的组合。
    • 例子: 选择你想要使用的编译器和构建工具。选择自己已经创建好的工具链即可。
  • Generator(生成器):

    • 作用: 指定生成构建系统文件的工具,比如 Makefile、Ninja、Visual Studio等。
    • 例子: 如果你的项目使用 Make 构建系统,选择 "Makefile"。
  • CMake options(CMake 选项):

    • 作用: 允许你传递额外的选项给 CMake,可以是 CMake 命令行参数。
    • 例子: 如果你需要为CMake添加额外的选项,可以在这里输入。如需要指定cuda路径在此添加。
  • Cache variables(缓存变量):

    • 作用: 允许你设置 CMake 缓存变量,即预定义的变量,影响项目的配置。
    • 例子: 如果你的项目需要依赖某个库,可以在这里设置相关的缓存变量。
  • Build directory(构建目录):

    • 作用: 指定构建系统生成的文件存放的目录。
    • 例子: 如果你想把构建文件放在项目根目录下的一个叫做 "build" 的文件夹里,可以在这里设置。
  • Build options(构建选项):

    • 作用: 允许你指定构建过程中的其他选项,比如并行构建的线程数。
    • 例子: 如果你的机器有多个核心,可以在这里设置并行构建的线程数。
  • Environment(环境变量):

    • 作用: 允许你设置项目构建过程中使用的环境变量。
    • 例子: 如果你的项目依赖于一些需要设置环境变量的库,可以在这里配置。

6 cuda​项目中在CMake options​ 中加入-DCMAKE_CUDA_COMPILER=/usr/local/cuda/bin/nvcc​ 是什么意思,cuda​项目用cmake​必须加入?

(1)路径解释

CMake options ​中加入 -DCMAKE_CUDA_COMPILER=/usr/local/cuda/bin/nvcc​ 表示使用 /usr/local/cuda/bin/nvcc​ 作为 CUDA​ 编译器。

CUDA​ 项目使用 CMake​ 构建时,需要指定 CUDA​ 编译器的路径。如果不指定,CLion​ 将无法找到 CUDA​ 编译器,并会报错。

因此,CUDA​ 项目使用 CMake​ 需要加入这句话。

具体的解释如下:

  • -D​ 表示这是 CMake​ 的变量定义。在这个例子中,我们定义了名为 CMAKE_CUDA_COMPILER​ 的变量。
  • CMAKE_CUDA_COMPILER​ 是 CMake​ 的变量名,表示 CUDA​ 编译器的路径。
  • /usr/local/cuda/bin/nvcc ​是 CUDA​ 编译器的路径。

(2)CUDA项目是否必须加入这句话?

并不是所有的CUDA​项目都必须加入这句话。

通常情况下,CMake​会自动查找系统上已安装的CUDA​,并使用找到的CUDA​版本。然而,有时候你可能希望明确指定使用的CUDA​版本,或者系统上有多个CUDA​版本,你想使用特定版本进行编译。

加入 -DCMAKE_CUDA_COMPILER=/usr/local/cuda/bin/nvcc​ 主要用于以下情况:

  1. 明确指定CUDA版本: 你希望明确指定使用的CUDA​版本而不是由CMake​自动查找。
  2. 多个CUDA版本: 当系统上存在多个CUDA​版本时,你可以通过这种方式选择特定版本。
  3. 非标准安装路径: 如果CUDA​安装在非默认路径下,你需要通过这种方式告诉CMake CUDA​的位置。

如果你的项目在默认情况下能够正确找到CUDA​,并且你不需要明确指定使用的CUDA​版本,那么不加入 -DCMAKE_CUDA_COMPILER=/usr/local/cuda/bin/nvcc ​通常是可以的。CMake​会根据系统环境自动查找并使用已安装的CUDA​版本。

总的来说,加入这句话是一个灵活的选择,特别是在涉及到多个​CUDA​版本或者非标准安装路径的情况下。如果你的项目能够正常构建而不加入这个选项,你可能不需要手动指定CUDA​编译器。