下载与装置
关于CLion的装置我引荐装置最新的CLion 2022.3之后的版别,因为从这个版别后性能提升了许多,并且还增加了对cmake代码的调试功用,并且对wsl的支撑得到进一步的增强,现在有了CLion在windows上运用Linux环境进行开发将是十分简略且舒适的进程。
主张先下载JetBrains家的toolbox然后再进行对应 CLion 的下载,这样也方便你办理与统一装备JB家的一切IDE。
官网链接如下:www.jetbrains.com/zh-cn/toolb…
下载完toolbox后,点开装置CLion 2022.3(或更新的版别) 即可。当然假如你不设置的话,下载完CLion后你会发现它默许装置在C盘,不要慌,toolbox也考虑到了这样的问题。
所以你只需求像下面这样操作:
更改完这个途径后,它会主动的把数据移动到这个文件夹中,之后下载的一切IDE数据也都会在这个文件夹中了。
咱们发现下面还有一个选项是署理,这对某些情况显然是很有用的,假如IDE中的某些东西的下载需求署理,那么能够在这儿设置署理。
现在CLion现已下载好了,点开后或许有些人无法正常运用,毕竟咱们都是白嫖党(),其实作为学生的咱们也彻底没有必要花这笔钱,咱们去官网请求一个资格即可,之后一切的JB家的产品都能够免费运用一年了,每年需求从头请求一次,请求的网站如下:www.jetbrains.com/shop/eform/…
请求前请用邮箱注册一个jb的账号,注册链接如下:account.jetbrains.com/login
请求有多种方法,学校邮箱假如有的话就很简略了,可是许多大学生没有这个,那么咱们能够运用官方文件的方法请求,这种方法略微麻烦一点,需求去学信网弄一个验证,详细流程如下:
上述邮箱相同也需求填入jb账号对应的邮箱,请求完后,一般7天内就会有邮箱通知你成功了,之后一切的jb家的产品都能够经过该账号免费运用。并且这个账号似乎能够供6/7个人一起运用(我不知道上限,可是我给了至少6/7个人)。
至此,CLion应该能够正常打开和运用了,可是打开的界面估量默许是中文,我主张去设置里边调成中文。
方法如下:1.点开设置 2.点开插件 3.点开已装置的插件 4.点击中文的那个插件禁用即可。
主题引荐
我引荐运用新UI + onedark的组合(我目前所运用的)。
作用如下:
假如你运用的是旧版别的UI,我之前常常运用的主题有以下三个:
- Atom Material Icons 作用大约如下,这个一个用于将文件夹颜色更亮堂的插件,新UI暂时不可用
- material-theme-ui:插件主页 plugins.jetbrains.com/plugin/8006…
- one-dark-theme:插件主页 plugins.jetbrains.com/plugin/1193…
编辑器与clang-format设置
鼠标滚轮改变字体大小
Editor -> General -> Change font size with Ctrl+Mouse Wheel 打上勾就行。
clang-format的运用
关于clang-format是什么,我截一段chatgpt的答复。
CLion是自带clang-format的,你只需求敞开即可,他会主动扫描项目根目录下的clang-format文件进行相应的格式化,敞开后你每次创立一个新项目他也会主动生成一个clang-format文件到项目根目录,这个文件装备是依据CLion默许的格式化的格式来的,假如想要更改格式化风格,只需求更改clang-formt装备文件即可。
一般来说,咱们只需求装备根本风格就行,一个.clang-format文件大约长这样:
一般来说没有什么特殊需求,那么就只需求填写 BasedOnStyle 即可,是Google风格仍是LLVM风格仍是Microsoft风格,都取决于上述的前三行代码,后边的都能够不必写。我这个装备文件是想要运用Google的格式化风格,可是Googel风格默许的代码边距太短了,所以进行了一系列的调整。
下面是CLion怎样敞开clang-format,敞开后CLion对代码的格式化将会以你项目根目录的clang-format文件为主。
我的 .clang-format 装备
BasedOnStyle: Google
Language: Cpp
AccessModifierOffset: -3
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: AcrossComments
AlignConsecutiveAssignments: AcrossComments
AlignConsecutiveDeclarations: AcrossComments
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: false
AfterClass: true
AfterControlStatement: Always
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: true
BeforeElse: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: "^ NOLINT:"
CompactNamespaces: false
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: true
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<ext/.*.h>'
Priority: 2
SortPriority: 0
- Regex: '^<.*.h>'
Priority: 1
SortPriority: 0
- Regex: "^<.*"
Priority: 2
SortPriority: 0
- Regex: ".*"
Priority: 3
SortPriority: 0
IncludeIsMainRegex: "([-_](test|unittest))?$"
IncludeIsMainSourceRegex: ""
IndentCaseLabels: true
IndentGotoLabels: true
IndentPPDirectives: None
IndentWidth: 3
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ""
MacroBlockEnd: ""
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Never
ObjCBlockIndentWidth: 4
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Right
RawStringFormats:
- Language: Cpp
Delimiters:
- cc
- CC
- cpp
- Cpp
- CPP
- "c++"
- "C++"
CanonicalDelimiter: ""
BasedOnStyle: google
- Language: TextProto
Delimiters:
- pb
- PB
- proto
- PROTO
EnclosingFunctions:
- EqualsProto
- EquivToProto
- PARSE_PARTIAL_TEXT_PROTO
- PARSE_TEST_PROTO
- PARSE_TEXT_PROTO
- ParseTextOrDie
- ParseTextProtoOrDie
CanonicalDelimiter: ""
BasedOnStyle: google
ReflowComments: true
SortIncludes: CaseInsensitive
SortUsingDeclarations: false
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 3
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Auto
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 4
编译东西链设置
编译东西链的增加与解说
这个装备是进行C++开发的要害,因为这个编译东西链就意味着C++的编译环境。
按下图点开对应的信息,假如你任何编译东西链都没有增加,因为新版别的CLion它会自带一个mingw的编译套件,所以默许会有一个CLion自带的mingw编译东西链,如下图所示我的编译东西链略微有点丰厚,有 msvc、g++、clang++、mingw,作为一个刚刚入门学编程的新手,我主张编译东西链这一块暂时就没必要了解了,但在CLion中编译的详细装备流程我以为仍是有必要讲清楚。
CLion中增加编译东西链十分简略,你本机把对应东西链的途径参加到了环境变量,那么在你点击 +
对应编译链类型后,会主动扫描到,假如真实没有扫描到,那么也能够自己填入对应的途径,整个编译链包括:
- cmake,用于跨渠道以及简化底层编译脚本的东西。
- cmake生成更底层的编译指令(对应上述的Build Tool),比方gmake也便是解析.makefile文件进行指令履行,比方 ninja 解析 .ninja文件进行指令履行(编译速度比makefile更快,亲自体会)。
- C言语的编译器(clang/gcc/cl等等)。
- C++的编译器(clang++/g++/cl等等)。
假如是mingw,那么上述的一套都是包括的,只需求把 Toolset 这个选项挑选为mingw对应的目录即可,挑选好后,CLion会主动辨认上述四件套的方位。
接下来简略介绍怎样增加一些东西链:
- 装置msvc编译东西链:直接到官网下载VS2022,然后装置对应C++环境,打开CLion后增加msvc环境时就会主动辨认。官网:visualstudio.microsoft.com/zh-hans/vs/
其实关于咱们C++程序员而言,最需求的便是一个Linux环境,因为许多底层的体系调用是不在C++规范之内的,C++想要做到跨渠道很难,所以咱们需求把开发环境切换到Linux体系,正好windows提供了Linux子体系,也便是wsl,完美的处理了这个问题,不要考虑日常的运用和开发环境咱们究竟选哪个了,我全都要!
而CLion对wsl的适配程度和正常的本机开发简直没有任何区别,咱们只需求现在Windows上装置wsl2后,CLion便能够主动辨认你本机的wsl环境了,可是你有了wsl,并不意味着你有了对应的编译链,之前说了,编译链是包括四个东西的,你需求一一手动再wsl上先装置好,CLion会主动辨认到的,假如辨认不到,由所以经过 apt install
指令装置的,咱们应该都清楚在详细那个目录下,真实不清楚能够运用 which
指令。
- 装置wsl2:其实wsl2的装置现已被简化到了极致,在powershell中
wsl --install
即可。 详细的官方文档如下 learn.microsoft.com/zh-cn/windo… ,一篇十分简练的博客教程:zhuanlan.zhihu.com/p/438255467,假如装置遇到问题(大约率网络问题),请自行谷歌或百度或bing或chatgpt。 - 假如需求运用CLion进行Qt开发,能够检查视频解说:www.bilibili.com/video/BV18q… ,对应的装备信息:gitee.com/yuexingqin/…
- 假如需求运用CLion进行STM32开发,那么能够检查稚晖君在知乎写的博客教程:zhuanlan.zhihu.com/p/145801160
cmake装备项的增加与解说
解说完上述编译链后,咱们发现CLion中有个很明显的 default
字眼,这个有什么用呢?
假如排在第一个的编译链,会被设置为默许编译链,假如想要其他的编译链为默许,点击上移即可。
至于详细的作用,别急,先等我讲完CLion中cmake装备项的处理。
如上图所示,第二个 CMake
选项便是咱们现在要讲的东西,而这两个正好也是整个开发环境中最重要的东西,第一个编译东西链决定了CLion中现已辨认了本机有哪些编译环境,而第二个 CMake
选项,则是用于装备 cmake 依据哪些装备项生成。
所以咱们现在应该了解了CLion是怎样去编译项目生成可履行文件的了。
- 经过cmake装备选项运转整个项意图CMakeList.txt
- 生成makefile或其他底层脚本后再经过对应的东西去履行这个脚本
- 运转编译好的程序
而咱们现在讲的便是增加cmake装备选项,假如你手动敲cmake指令的话,那样对应的便是指令行参数了。
上述图片中现已解说了一些装备的作用。这些装备项一般是不常改动,运用默许值就行,比方 Build options
是履行最后的脚本所用的参数,默以为 -j 12
,比方假如是makefile,那么便是 make -j12
。
下面是咱们或许需求进行一些装备的选项:
- Build type:这是程序终究编译的类型,意味着编译器该以何种程度对源代码进行优化,比方Debug版别一般再gcc中对应o2的优化,release版别对应o3的优化,两者一般存在10倍左右的性能差距。
- Toolchain:这是前面所说的编译东西链,一般来说,想要切换编译器,你切换这个选项就行了,默许运用default东西链。
- Generator:这是前面所说的东西链中的较为底层的脚本的运转东西,能够是makefile或许ninja,不选的话也是默许东西链里的那个。
- CMake options:这个是cmake运转时能够参加的指令行参数,比方咱们能够-D来界说对应的变量控制对应的cmake行为,甚至于前面的Build type咱们彻底能够不写(当然这是CLion,这个空必须得被填充),然后运用-DCMAKE_BUILD_TYPE=Release,这个变量能够决定终究cmake生成的履行脚本是按照release的规范去运转的,又比方-DBUILD_SHARED_LIBS=ON,那么终究是会生成动态库而不是静态库,我上图中的 -DENABLE_TEST=ON 是内部的cmake有界说一个变量默以为OFF值,假如为ON时会参加测验代码为子项目。
现在cmake在CLion中的装备项现已讲完了,简略实践一下来体会之前讲的CLion到整个运转的流程,我这儿就直接配图了:
- 经过cmake装备选项运转整个项意图CMakeList.txt。
- 生成makefile或其他底层脚本后再经过对应的东西去履行这个脚本。 咱们先看一眼上一步cmake生成的文件(放出了两个不同的装备项发生的脚本,第一个运用的Generator为ninja,第二个运用的为gmake): 假如想要继续履行这个脚本,应该在CLion中履行对应的源代码,CLion会主动辨认进口点函数,然后给出可履行的按钮,如图: 点击履行后,不只会直接对应的 makefile 或 build.ninja 还会顺便把这个程序运转到CLion内置的终端环境中。
- 运转编译好的程序:这一步现已在第二步一并履行了。
理解了这三步以及cmake的装备之后,我相信假如突然间CLion不出现履行程序的按钮,或许一个外部的项目咱们无法跑起来,那么咱们肯定是会有对应的排查思路了。比方没有履行程序的按钮,那或许对应的cmake装备项你还没设置好,假如外部项目跑不起来,你能够把那四个编译东西链中的某个换其他的环境试试?
cmake的运用与实战
经过上述文字和图片解说,咱们很自然的想到,整个CLion运转C++代码其实便是在运转cmake和makefile(或build.ninja),第二个进程咱们参加不了,可是第一个cmake的编写进程咱们却需求一直接触。
下面用CLion新建项目主动生成的cmake模板来简略对cmake语法热热身。
cmake_minimum_required(VERSION 3.22)
project(untitled)
set(CMAKE_CXX_STANDARD 17)
add_executable(untitled main.cpp)
-
cmake_minimum_required
指令:规矩了编译本项意图cmake东西至少需求3.22版别。 -
project
指令:规矩了本项意图项目称号,一起也依据这个传入的值生成了一堆变量,常用的如下:-
PROJECT_NAME
:项目称号 -
PROJECT_BINARY_DIR
:项意图二进制文件目录,即编译后的可履行文件和库文件的输出目录 -
PROJECT_SOURCE_DIR
:项意图源文件目录,即包括CMakeLists.txt文件的目录
举个简略例子阐明上述变量的作用: 比方一个测验的子项目中的CMakeList.txt,或许需求写下面的句子(先不论file指令),由所以作为直接的子项目,那么里边肯定不会存在project句子,所以PROJECT_SOURCE_DIR变量表明的仍然是整个项意图根目录,直接经过
${}
的方式来运用它即可,这样就不需求关怀相对或绝对途径了。file(GLOB SONIC_TEST_FILES "${PROJECT_SOURCE_DIR}/tests/*.h" "${PROJECT_SOURCE_DIR}/tests/*.cpp" )
-
-
set
指令:设置对应变量为对应的值,该变量存在,则修改该变量的值,假如不存在则会创立并初始化为对应的值,这儿对set的运用是设置了 CMAKE_CXX_STANDARD 变量为17,这个变量能够控制终究编译采用的C++版别,这儿是运用C++17。 -
add_executable
指令:这是用于生成可履行程序的指令,第一个参数为该履行程序终究编译后生成的文件名,后边跟着的都是需求编译的源代码。
关于新手而言,其实不太需求自己手写cmake,因为CLion会在你新建源文件的时分把相应源文件增加到add_excutable指令的后边,但项目略微大一点或许说引进了许多外部库,那么大约率会扔掉CLion的这种主动化了。
常用的cmake变量(入门)
下面只列出了部分变量的作用,更多的变量请检查文档:cmake.org/cmake/help/…
-
PROJECT_NAME
:项目称号 -
PROJECT_BINARY_DIR
:项意图二进制文件目录,即编译后的可履行文件和库文件的输出目录 -
PROJECT_SOURCE_DIR
:项意图源文件目录,即包括CMakeLists.txt文件的目录 -
CMAKE_BINARY_DIR
:当时CMake运转的二进制文件目录,一般和PROJECT_BINARY_DIR是同一个目录 -
CMAKE_SOURCE_DIR
:当时CMake运转的源文件目录,一般和PROJECT_SOURCE_DIR是同一个目录 -
CMAKE_C_STANDARD
:指定C言语的规范版别 -
CMAKE_CXX_STANDARD
:指定C++言语的规范版别 -
CMAKE_CXX_FLAGS
:指定编译C++代码时运用的编译选项 -
CMAKE_C_FLAGS
:指定编译C代码时运用的编译选项 -
CMAKE_EXE_LINKER_FLAGS
:指定链接可履行文件时运用的链接选项 -
CMAKE_SYSTEM_NAME
:指定当时操作体系称号(如Windows、Linux等) -
CMAKE_SYSTEM_PROCESSOR
:指定当时处理器的类型(如x86、x86_64等) -
CMAKE_CXX_COMPILER_ID
:指定了当时运用的C++编译器,同理可得C的编译器对应的名字。
对这些变量做一个简略的实践:
-
经过message打印出PROJECT_BINARY_DIR、PROJECT_SOURCE_DIR、CMAKE_BINARY_DIR、CMAKE_SOURCE_DIR来加以验证。 目录结构:
. ├── CMakeLists.txt ├── main.cpp └── sub └── CMakeLists.txt
cmake:
main: cmake_minimum_required(VERSION 3.14) project(main) add_subdirectory(sub) message(STATUS "main:${PROJECT_NAME}\n pro-src:${PROJECT_SOURCE_DIR}\n pro-bin:${PROJECT_BINARY_DIR}\n cmake-src:${CMAKE_SOURCE_DIR}\n cmake-bin:${CMAKE_BINARY_DIR}") sub: project(sub) message(STATUS "sub:${PROJECT_NAME}\n pro-src:${PROJECT_SOURCE_DIR}\n pro-bin:${PROJECT_BINARY_DIR}\n cmake-src:${CMAKE_SOURCE_DIR}\n cmake-bin:${CMAKE_BINARY_DIR}")
打印信息如下:咱们发现CMake对应的变量没有改变,而Prject有了变量,因为咱们在sub也运用了project指令。
-
经过变量检测环境履行不同的cmake代码:
#判别当时的操作体系 if (CMAKE_SYSTEM_NAME MATCHES "Linux") target_link_libraries(my-logger PUBLIC fmt-header-only pthread) message(STATUS "Now is Linux") elseif (CMAKE_SYSTEM_NAME MATCHES "Windows") target_link_libraries(my-logger PUBLIC fmt-header-only ws2_32) message(STATUS "Now is windows") endif () #判别当时运用的编译器 if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # Do something for GCC elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") # Do something for Intel C++ elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Microsoft") # Do something for Microsoft Visual C++ elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") # Do something for Clang endif() #判别当时的体系架构 if (CMAKE_SYSTEM_PROCESSOR MATCHES "i.86|x86|x86_64|AMD64") # Do something for x86 architecture elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm|aarch64)") # Do something for ARM architecture elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "^(mips|mipsel|mips64)") # Do something for MIPS architecture elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc64)") # Do something for PowerPC architecture endif()
-
经过调整链接时的flag避免动态链接,因为假如你是运用Windows渠道下的编译东西链,CLion有些时分终究链接并不是采用静态链接,导致你终究生成的可履行程序无法直接履行,这个时分你就需求运用下面的指令来强制静态链接了:
set(CMAKE_EXE_LINKER_FLAGS "-static")
常用的cmake指令(入门)
下列只列出了部分指令,假如你以后有需求用到的其他指令,请前往官网进行查询:cmake.org/cmake/help/…
我个人较为常用的指令:
-
project:用于界说项目称号、版别号和言语。
-
add_executable:用于增加可履行文件。第一个参数很重要,被称为target,能够作为target_xxx指令的接纳目标。
-
add_library:用于增加库文件,能够创立静态库或动态库。第一个参数很重要,被称为target,能够作为target_xxx指令的接纳目标。简略运用如下
add_library(test_lib a.cc b.cc) #默许生成静态库 add_library(test_lib SHARED a.cc b.cc) #默许生成静态库
-
add_definitions:用于增加宏界说,留意该指令没有履行次序的问题,只要改项目中用了该指令界说宏,那么一切的源代码都会被界说这个宏
add_definitions(-DFOO -DBAR ...)
。 -
add_subdirectory:用于增加子项目目录,假如有该条句子,就先会跑去履行子项意图cmake代码,这样会导致一些需求履行后立马收效的句子作用不到,比方include_directories和link_directories假如履行在这条句子后边,则他们增加的目录在子项目中无法收效。有些指令如target_include_directories和target_link_directories是依据目标target是否被链接运用来收效的,所以这些指令的作用规模与履行次序无关,且恰好同一个cmake项目中发生的库文件是能够直接经过称号链接的,不管链接目标是在子目录仍是父目录
-
target_link_libraries:用于将可履行文件或库文件链接到库文件或可履行文件。身为target_xxx的一员,很明显第二个参数也能够进行权限控制。
-
include_directories:用于指定头文件查找途径,长处是简略直接,缺点是无法进行权限控制,一旦被履行后,后续的一切代码都能查找到对应的文件途径。
-
target_include_directories:指定头文件查找途径,并将查找途径关联到一个target上,这儿的target一般是指生成可履行程序指令里的target或许生成库文件的target,与上一个指令的不同点在于能够设置导出权限,比方现在我写了一个项目,这个项目引进了其他库,可是我不想让其他库的符号暴露出去(毕竟运用这个项意图人只重视这个项意图接口,不需求重视其他依靠的接口)能够经过PRIVATE将头文件查找目录设置不导出的权限。
-
link_directories:与前面的include_directories指令相似,增加的是库的查找途径。
-
target_link_directories:和前面的include版别相同的,仅仅改成了库途径。
-
if\elseif\endif ,在编程言语立马现已用烂了,现在主要是了解 if(condition) 中的条件究竟怎样判别的,以及内部都支撑哪些操作,比方大于等于啥的,这方面直接看官方文档吧,十分好懂:cmake.org/cmake/help/…
-
aux_source_directory:这个指令简略有用,第一个参数传递一个文件目录,它会扫描这儿边一切的源文件放到第二个参数界说的变量名中。留意第一个参数只能是文件夹。
aux_source_directory(${PROJECT_SOURCE_DIR} SRC)
-
file:能够说是上面那个指令的增强版别,但假如了解这个指令的朋友肯定很快站出来对立,因为这个指令真实是太强大了,你假如翻一翻这个官方文档就会发现它具有简直文件体系的一切功用,什么读写文件啊,什么从网上下载文件,本地上传文件之类的它都有,核算文件的相对途径,途径转化等等。但咱们平时用到的最多的指令仍是用来获取文件到变量里。比方file(GLOB FILES “文件途径表明1” “文件途径表明2” …) GLOB会发生一个由一切匹配globbing表达式的文件组成的列表,并将其保存到第二个参数界说的变量中。Globbing 表达式与正则表达式相似,但更简略,比方假如要完成前一个指令的功用能够这么写:
file(GLOB SRC "${PROJECT_SOURCE_DIR}/*.cc")
假如GLOB 换成GLOB_RECURSE ,那么上述指令将递归的搜寻其子目录的一切契合条件的文件,而不只仅是一个层级。
-
execute_process:用于履行外部的指令,如下的示例代码是履行git clone指令,履行指令的作业目录在
${CMAKE_BINARY_DIR}/deps/
execute_process(COMMAND git clone https://github.com/<username>/<repository>.git WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/deps/<repository>)
-
message:打印出信息用于debug。
-
option:用于快速设置界说变量并赋值为对应的bool值,常被用于判别某些操作是否履行。
-
find_package:用于查找外界的package,其实便是查找外界对应的
<package>Config.cmake
和Find<package>.cmake
文件,这些文件里有外界包对应的变量信息以及库和头文件的各种途径信息。咱们需求留意一些有关find_package
指令查找 Config.cmake 途径的变量:-
CMAKE_PREFIX_PATH
变量是一个途径列表,CMake 会在这些途径中查找包的Config.cmake
文件。 -
<Package>_DIR
变量是指向包的Config.cmake
文件的途径。假如你手动设置了这个变量,那么find_package
指令就能够找到包的信息。
一起他的一些常用参数如下:
-
CONFIG
:显式指定find_package去查找<package>Config.cmake
文件,一般只要你在变量里边指定了<package>Config.cmake
的途径,那么该参数填不填都没差别。我主张最好仍是带上该参数比较好。 -
REQUIRED
:该参数表明假如没找到,那么直接发生cmake错误,退出cmake履行进程,假如没有REQUIRED,则即使没找到也不会终止编译。 -
PATHS
:这个参数的作用和前面的变量相似,也是指定查找的途径。 -
COMPONENTS
:用于指定查找的模块,模块分离在不同的文件中,需求运用哪个就指定哪个模块。典型的便是运用Qt时的cmake代码,比方find_package(Qt5 COMPONENT Core Gui Widgets REQUIRED)
。 - VERSION:或许有许多个不同版别的包,则需求经过该参数来指定,如:
find_package(XXX VERSION 1.2.3)
。
-
-
include:从文件或模块加载并运转 CMake 代码。我用这个指令实际上仅仅为了运用 FetchContent 这个module的功用,该功用是从cmake3.11开始支撑的,运用该module前需求经过include指令加载该模块,指令如下:
include(FetchContent)
-
FetchContent:这是一个模块功用,它用来从代码库房中拉取代码,例如我要把最近写的日志库引进到当时的项目中运用(留意这中心不会有任何署理,所以拉取GitHub的库房或许失败):
include(FetchContent)#引进功用模块 FetchContent_Declare( my-logger #项目称号 GIT_REPOSITORY https://github.com/ACking-you/my-logger.git #库房地址 GIT_TAG v1.6.2 #库房的版别tag GIT_SHALLOW TRUE #是否只拉取最新的记载 ) FetchContent_MakeAvailable(my-logger) add_excutable(main ${SRC}) #链接到程序进行运用 target_link_libraries(main my-logger)
这样引进第三方库的好处清楚明了,长处相似于包办理的作用了,但缺少了最要害的中心库房来确保资源的有效和稳定。参考golang再做个proxy层级就好了。 相同能够拉取最新的googletest能够运用下列句子:
FetchContent_Declare( googletest GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG release-1.12.1 GIT_SHALLOW TRUE ) # For Windows: Prevent overriding the parent project's compiler/linker settings set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) FetchContent_MakeAvailable(googletest) target_link_libraries(main gtest_main)
-
function/endfunction :在cmake中用于界说函数,复用cmake代码的指令。第一个参数为函数的称号,后边为参数的称号,运用参数和运用变量时相同的,可是假如参数是列表类型,则在传入的时分就会被打开,然后与函数参数顺次对应,多余的参数被
ARGN
参数吸收。
更多较为常用的指令:
- add_custom_command:增加自界说规矩指令,相同也是履行外界指令,但多了依据依靠和产物判别履行机遇的作用。
- install:增加install操作。
- string:对string的一切操作,比方字符串替换啥的。
- list:对list的一切操作,比方列表处理之类的。
- foreach:cmake中的for循环。
- …
运用上述指令完成Qt开发中调用uic东西把 大量的 .ui
文件转化为 .cpp
和 .h
文件,并完成当ui文件更新时或 .cpp/.h
文件不存在时才创立对应的 .cpp/.h
文件。
#函数功用完成
function(get_ui_source)
foreach (item ${ARGN})
set(UIC_EXE_PATH ${VCPKG_ROOT}/installed/x64-windows/tools/qt5/bin/uic.exe)
get_filename_component(name ${item} NAME_WLE)
string(PREPEND name "ui_")
set(output_h ${PROJECT_SOURCE_DIR}/ui_gen/${name}.h)
set(output_cpp ${PROJECT_SOURCE_DIR}/ui_gen/${name}.cpp)
file(TIMESTAMP ${item} ui_time)
#当.h文件现已存在时,仅当.ui文件被更新了才从头生成.h文件
if (EXISTS ${output_h})
file(TIMESTAMP ${output_h} h_time)
if (ui_time GREATER h_time)
execute_process(COMMAND ${UIC_EXE_PATH} ${item} -o ${output_h})
endif ()
else ()
execute_process(COMMAND ${UIC_EXE_PATH} ${item} -o ${output_h})
endif ()
#当.cpp文件现已存在时,仅当.ui文件被更新了才从头生成.cpp文件
if (EXISTS ${output_cpp})
file(TIMESTAMP ${output_cpp} cpp_time)
if (ui_time GREATER cpp_time)
execute_process(COMMAND ${UIC_EXE_PATH} ${item} -o ${output_cpp})
endif ()
else ()
execute_process(COMMAND ${UIC_EXE_PATH} ${item} -o ${output_cpp})
endif ()
endforeach ()
endfunction()
get_ui_source(${UI_FILES}) #功用的运用
ideaVim的运用与设置
关于vim的根本操作,这儿就不细讲,网络上大把大把的教程,我这儿只讲在CLion中怎样运用vim,怎样装备vim让它在CLion中更好用。
在运用ideaVim前,咱们需求先下载 IdeaVim 这个拓宽,ideaVim的链接:plugins.jetbrains.com/plugin/164-…,下载好后,应该是默许启用了的。
一、装备ctrl+c和ctrl+v和ctrl+a避免这些你常用的快捷键被vim占用
二、装备.ideavimrc。
点击 Open ~/.ideavimrc
后,参加下面的装备(这是我个人运用的装备)
let mapleader = ","
let g:mapleader = ","
set timeoutlen=300
" general
imap jk <Esc>
imap kj <Esc>
vnoremap q <Esc>
nmap <C-o> :action Back<CR>
nmap <C-i> :action Forward<CR>
nnoremap <Leader>r :<C-u>action RenameElement<CR>
" Redo
nnoremap U <C-r>
" code editing
nnoremap == :<C-u>action ReformatCode<CR>
vnoremap == :<C-u>action ReformatCode<CR>
nnoremap cc :<C-u>action CommentByLineComment<CR>
vnoremap cc :<C-u>action CommentByLineComment<CR>
" Run and debug
nnoremap \r :action RunClass<cr>
nnoremap \i :<C-u>action OptimizeImports<CR>
nnoremap \R :action Run<cr>
nnoremap [[ :action MethodUp<cr>
nnoremap ]] :action MethodDown<cr>
参加后点击右上角的小图标进行改写即可。
上述装备文件完成了下面的功用:
- 按下 j+k 或许 k+j 将会退出刺进模式。
- 在可视模式下按q退出。
- ctrl+o能够完成指针回退到上一次的方位,ctrl+i行进到上次的方位。能够类比为VS李的行进和撤退按钮(一般检查界说检查的比较深,能够运用该指令回退或行进)。
- , + r 能够完成CLion中的重构变量名。
- U吊销吊销(因为vim中按u是吊销,而吊销吊销需求ctrl+r,这让人很不习惯)
- = + =完成代码格式化。
- c + c完成代码注释
- [ + [跳转到前一个函数方位
- ] + ]跳转到下一个函数方位
- \ + r 运转当时的可履行程序(假如当时代码段里边有运转按钮的话)
- \ + R 运转当时可履行程序,这个是直接相当于按了右上角的三角按钮运转
- \ + i 优化导入的包