提示:文章
文章目录
前言
前期疑问:
本文目标:
一 背景
需要安装CLion
主要是参考下面的文章
二、安装教程
参考https://blog.youkuaiyun.com/2301_77560238/article/details/138012794
2.1 配置环境
新建C++工程,选择工程路径,修改CMkaeList.txt文件,
此时Cmake状态是这样的,没有debug,点击reload CMake Project,运行程序,程序运行成功
二、使用相关
2.1 离线安装插件
CLion离线安装插件
下载插件网址:https://plugins.jetbrains.com/
2.1.1 UML
2.1.2 中文包
CLion导入插件包
2.2 设置代码样式
设置——编辑器——c/c++——换行和大括号——大括号位置——在函数中——改成下一行
2.3 代码加书签
ctrl+shift+[key]
2.4 收缩展开代码快捷键
Ctrl + NumPad+/- 展开或者收缩代码块
Ctrl + Shift + NumPad+ 展开收缩所有的代码块
2.4 Clion提交代码
这边会让登录信息
我这边记不得git账号密码了,在网上查找查看账号密码的方法也没看到。然后选了下面的“使用凭据帮助程序”可以正常提交代码。
三、编译程序
3.1 CMake
2.4 CMakeLists
创建项目后会自动进入到项目中,在左侧文件列表打开“CMakeLists.txt”,删掉原本内容,并复制粘贴如下内容:
C:
cmake_minimum_required(VERSION 3.26)
get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
string(REPLACE " " "_" ProjectId ${ProjectId})
project(${ProjectId} C)
set(CMAKE_C_STANDARD 11)
file(GLOB files "${CMAKE_CURRENT_SOURCE_DIR}/*.c")
foreach(file ${files})
get_filename_component(name ${file} NAME)
add_executable(${name} ${file})
endforeach()
C++:
cmake_minimum_required(VERSION 3.26)
get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
string(REPLACE " " "_" ProjectId ${ProjectId})
project(${ProjectId} CXX)
set(CMAKE_CXX_STANDARD 17)
file(GLOB files "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
foreach(file ${files})
get_filename_component(name ${file} NAME)
add_executable(${name} ${file})
endforeach()
而后,右键“CMakeLists.txt”,点击“Reload Cmake Project”,就可以愉快地使用啦~
3.2 CMake语句
https://blog.youkuaiyun.com/qq_43685921/article/details/124176069
3.2 CMakeList.txt编写
参考文章
CMakeLists.txt的超详细教程,带你进入第一个项目
自己新建的一个工程,验证模板类的代码,正好整理一下CmakeList.txt相关编写。该工程的cmakelist.txt的编写如下
cmake_minimum_required(VERSION 3.16.5)
message("this is cmakelist log")
get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
string(REPLACE " " "_" ProjectId ${ProjectId})
project(${ProjectId} CXX)
#添加宏定义Debug为CMAKE_BUILD_TYPE
SET(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_CXX_STANDARD 17)
if (CMAKE_BUILD_TYPE STREQUAL Debug)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -D_DEBUG")
else ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -D_DEBUG")
endif ()
#添加头文件
#例如:include_directories(/usr/include/abc /usr/include/xxx)
#是将“/usr/include/abc”和“/usr/include/xxx”这两个目录添加至编译器的头文件搜索目录(两个目录用空格分隔)。
include_directories(./include)
#通过编译源文件来创建一个可执行文件,其中,name是生成的可执行文件的名称,source是创建可执行文件所需要的源文件。
#源文件可以使用aux_source_directory指令返回的变量(将源文件保存在这个变量中),也可以是指定的.cpp文件(注意路径)。
add_executable(hello main.cpp)
SET(CMAKE_BUILD_TYPE "Debug")
SET(CMAKE_BUILD_TYPE "Release")
上述语句最终变量CMAKE_BUILD_TYPE的值是Release
3.3 cmakelist.txt调试打印
在写cmakelist.txt文件的时候其实是很懵逼的。这时候就迫切需要能够调试一下自己写的cmakelist语句。但是之前并不知道怎么调试cmakelist,今天查了一下,竟然真的可以调试,可以像shell脚本使用“echo”打印调试一样,cmakelist也可以使用message调试cmamkelist。
下面就介绍一下怎么调试cmakelist。基于平台是CLion软件,使用他的终端来调试cmakelist.txt文件。不过在windows上调试相对linux会快一些,不需要更新文件到linux机器上。下面是在windows平台上验证的。要保证windows安装了cmake软件。调试的cmakelist.txt文件是基于上面的cmakelist文件
进入终端查询版本号,执行
cmake --version
可以查询到版本号
D:\AppData\CLion\testProj> cmake --version
cmake version 3.26.0
CMake suite maintained and supported by Kitware (kitware.com/cmake).
既然有了cmake编译器,进入cmakelist.txt目录下,
执行cmake .
执行结果是
PS D:\AppData\CLion\testProj> cmake .
this is cmakelist log
-- Selecting Windows SDK version 10.0.17763.0 to target Windows 10.0.19045.
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: D:/AppData/CLion/testProj
然后修改cmakelist,肆意增加调试信息
cmake_minimum_required(VERSION 3.16.5)
message("this is cmakelist log")
message(${CMAKE_CURRENT_SOURCE_DIR})
get_filename_component(ProjectId ${CMAKE_CURRENT_SOURCE_DIR} NAME)
#打印ProjectId
message(${ProjectId})
#Hello World!赋值给ProjectId
set(ProjectId "Hello World!")
message(${ProjectId})
message(NAME)
string(REPLACE " " "_" ProjectId ${ProjectId})
message(${ProjectId})
project(${ProjectId} CXX)
#添加宏定义Debug为CMAKE_BUILD_TYPE
SET(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_CXX_STANDARD 17)
if (CMAKE_BUILD_TYPE STREQUAL Debug)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -D_DEBUG")
else ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -D_DEBUG")
endif ()
#添加头文件
#例如:include_directories(/usr/include/abc /usr/include/xxx)
#是将“/usr/include/abc”和“/usr/include/xxx”这两个目录添加至编译器的头文件搜索目录(两个目录用空格分隔)。
include_directories(./include)
#通过编译源文件来创建一个可执行文件,其中,name是生成的可执行文件的名称,source是创建可执行文件所需要的源文件。
#源文件可以使用aux_source_directory指令返回的变量(将源文件保存在这个变量中),也可以是指定的.cpp文件(注意路径)。
add_executable(hello main.cpp)
上述cmakelist.txt的打印信息如下
PS D:\AppData\CLion\testProj> cmake .
D:/AppData/CLion/testProj
testProj
NAME
testProj
-- Selecting Windows SDK version 10.0.17763.0 to target Windows 10.0.19045.
-- Configuring done (0.0s)
-- Generating done (0.0s)
D:/AppData/CLion/testProj
testProj
Hello World!
NAME
Hello_World!
哈哈,有了调试,简直无敌啊!
3.4 根据调试增加cmakelist知识点
CMAKE_CURRENT_SOURCE_DIR | cmakelist.txt文件同级目录 | |
---|---|---|
get_filename_component( [CACHE]) | 字符串解析处理,将filename的 [CACHE])部分赋值给 | DICECTORY:没有文件名的目录,路径返回时带有正斜杠,并且没有尾部斜杠。 NAME:不带名录的文件名 EXT:文件名的最长扩展名 NAME_WE:不带目录或最长扩展名的文件名 LAST_EXT:文件名的最后扩展名 NAME_WLE:文件目录或最后扩展名的文件名 PATH:DIRECTORY的就别名(cmake <= 2.8.11)。(https://www.cnblogs.com/faithlocus/p/15613720.html) |
string(REPLACE " " “_” ProjectId ${ProjectId}) | 将变量${ProjectId})中空格替换成’_'并赋值给ProjectId | |
add_executable( [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] [source1][source2…]) | 通过编译源文件来创建一个可执行文件,其中,name是生成的可执行文件的名称,source是创建可执行文件所需要的源文件。源文件可以使用aux_source_directory指令返回的变量(将源文件保存在这个变量中),也可以是指定的.cpp文件(注意路径)。 | |
SET(CMAKE_BUILD_TYPE “Debug”) #SET(CMAKE_BUILD_TYPE “Release”) | 解除Release注释,会使变量CMAKE_BUILD_TYPE 的值为Realse,编译优化方式不同,没有调试功能 |
3.5 CMakeList报错
cmakelist.txt
cmake_minimum_required(VERSION 2.8.12)
project(RelativelyTimeAnalysis)
project(${ProjectId})
#SET(CMAKE_CXX_COMPILER "g++")
#SET(CMAKE_C_COMPILER "gcc")
SET(CMAKE_BUILD_TYPE "Debug")
SET(PLATFORM "LINUX")
add_definitions(
-DTRACK_DEBUG
)
if (CMAKE_BUILD_TYPE STREQUAL Release)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FORTIFY_SOURCE=2 -O3 -DNDEBUG -s")
elseif (CMAKE_BUILD_TYPE STREQUAL Asan)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -D_ASAN -fsanitize=address -fsanitize-recover=address,all -fsanitize=leak -fsanitize-coverage=trace-pc")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftest-coverage -fprofile-arcs -fdump-rtl-expand -lgcov")
else ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -D_DEBUG")
endif ()
if (PLATFORM STREQUAL WINDOWS OR PLATFORM STREQUAL windows)
SET(PLATFORM windows)
add_definitions(
-DWIN32
)
else ()
SET(PLATFORM linux)
add_definitions(
-Dlinux
)
endif()
find_package(JNI)
if (JNI_FOUND)
include_directories(${JAVA_INCLUDE_PATH})
include_directories(${JAVA_INCLUDE_PATH2})
aux_source_directory(${JAVA_INCLUDE_PATH} JniLib)
aux_source_directory(${JAVA_INCLUDE_PATH2} JniLib)
message(STATUS "jni.h path is : ${JAVA_INCLUDE_PATH}")
message(STATUS "jni_md.h path is : ${JAVA_INCLUDE_PATH2}")
else (JNI_FOUND)
message(WARNING "Can't find JNI, using self jni, may cause some issue uncontrollable.")
endif (JNI_FOUND)
include_directories(./include)
aux_source_directory(./src staticsSrc)
add_executable(${ProjectId}
main.cpp)
报错如下:
CMake Error at CMakeLists.txt:4 (project):
project PROJECT called with incorrect number of arguments
CMake Error: Error required internal CMake variable not set, cmake may not be built correctly.
Missing variable is:
CMAKE_FIND_LIBRARY_PREFIXES
CMake Error: Error required internal CMake variable not set, cmake may not be built correctly.
Missing variable is:
CMAKE_FIND_LIBRARY_SUFFIXES
CMake Error: Error required internal CMake variable not set, cmake may not be built correctly.
Missing variable is:
CMAKE_FIND_LIBRARY_PREFIXES
CMake Error: Error required internal CMake variable not set, cmake may not be built correctly.
Missing variable is:
CMAKE_FIND_LIBRARY_SUFFIXES
原因是projectId有破折号,
3.6 cmakelist增加add_definitions
因为经常调试,感觉后面写代码还是最好使用全局宏定义吧。这就要用到add_definitions
之前一直没有弄懂怎么使用,今天又试了下
project(${ProjectId} CXX)
add_definitions(-DHELLOWORLD)
# 判断宏是否存在
if(DEFINED HELLOWORLD)
message(STATUS "HELLOWORLD已定义")
else()
message(STATUS "HELLOWORLD未定义")
endif()
增加了HELLOWORLD宏定义,但是cmakelist并没有按照"判断宏是否存在"执行,然后查资料百思不得解,而且查百度资料很少。写的代码如下:
int main()
{
#ifdef HELLOWORLD
std::cout << "hello world" << std::endl;
#else
std::cout << "no hello world" << std::endl;
#endif
return 0;
}
// 打印hello world,实现宏定义
3.7 cmakelist 一个工程多个main文件
在刷题时想在一个工程中创建多个小工程对应题目。可能出现多个main函数。下面这种方法可以实现多个main文件。
cmake_minimum_required(VERSION 3.16)
project(ojfileSystem)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -D_DEBUG")
set(CMAKE_CXX_STANDARD 17)
aux_source_directory(./oj_explorer exploreSrc)
aux_source_directory(./oj_fileSystem fileSystemSrc)
add_executable(ojexplorer
${exploreSrc}
./oj_explorer/main.cpp)
add_executable(ojfileSystem
${fileSystemSrc}
./oj_fileSystem/main.c)
这个工程中有两个小工程,对应两个文件夹:oj_fileSystem和oj_explorer。两个文件夹中有两个main文件。然后右上角可以切换两个工程。还是比较不错的。但是好像不能一次执行完多个main文件。暂时先这样。
但是这其中还遇到一个问题。那就是会错误重定义某个函数。实际上这个函数没有重定义。经过折腾,发现将这个函数定义成static就不会报错了。可能是跟多个工程包含文件有关吧。
尝试将上述cmakelist文件中project(ojfileSystem)改成project(oj)也不会发生错误。
四 MinGW
关于MinGW有了更多的认识
MinGW 的全称是:Minimalist GNU on Windows 。它实际上是将经典的开源 C语言 编译器 GCC 移植到了 Windows 平台下,并且包含了 Win32API ,因此可以将源代码编译为可在 Windows 中运行的可执行程序。而且还可以使用一些 Windows 不具备的,Linux平台下的开发工具。一句话来概括:MinGW 就是 GCC 的 Windows 版本 。
以上是 MinGW 的介绍,MinGW-w64 与 MinGW 的区别在于 MinGW 只能编译生成32位可执行程序,而 MinGW-w64 则可以编译生成 64位 或 32位 可执行程序。
正因为如此,MinGW 现已被 MinGW-w64 所取代,且 MinGW 也早已停止了更新,内置的 GCC 停滞在了 4.8.1 版本,而 MinGW-w64 内置的 GCC 则更新到了 6.2.0 版本。
https://www.cnblogs.com/mq0036/p/15992914.html
五
5.1 windows安装MinGW-w64
背景是我自己电脑gdb用不了,我需要在自己电脑上安装minGW,下面是安装过程
直接官网下载
https://sourceforge.net/projects/mingw-w64/files/mingw-w64/mingw-w64-release/
几个版本区别
因为网速问题,我在百度网盘下载的,路径——学习资源, 下载后解压缩,将mingw64文件夹放在D盘,复制路径到环境变量
在shell中查看是否安装成功
在clion中设置minGW编译器。将自绑定编译器改成安装的。实现gdb识别,可以长长调试代码。
5.2 linux安装Min-w64
六 新建工程
新建C++工程过程
文件——新建——项目——C++可执行文件——选择路径
建好之后修改CMakeList.txt文件,使用工程自带的代码编译运行,报错
gmake: *** No rule to make target 'testProj'. Stop.
这边是因为我使用了远程调试,需要将设置——工具链——选择MinGW,再运行就可以了。
需要调试需要加上下述语句
SET(CMAKE_BUILD_TYPE "Debug")
if (CMAKE_BUILD_TYPE STREQUAL Debug)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -D_DEBUG")
else ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -D_DEBUG")
endif ()
上述代码还支持切换模式
调试代码过程中遇到一个莫名其妙的问题,可以清理工程,方法:构建——清理
比我我这次代码,在构造函数中初始化两个类成员对象,然后一直报错,找不到原因,尝试清理后解决问题。另外还报一个错
MapTrafficLightService_zhuyf/engine/test/test_DataStatistics/src/ZeroErrorRatio.cpp:115: undefined reference to `ZeroErrorRatio::PrintAllRateBySlot(CalculateData2*)'
7/MapTrafficLightService_zhuyf/engine/test/test_DataStatistics/src/ZeroErrorRatio.cpp:116: undefined reference to `ZeroErrorRatio::PrintAllRateBySlot(CalculateData2*)'
原因是确实没有定义PrintAllRateBySlot这个函数。
关于清理,我刚才又遇到了一次,原由自己修改过一次文件名,然后远程调试服务器上就有了之前文件名不对的文件。执行了清理,然后又在服务器删除了错误文件名的文件,重新编译就好了。
七 遗留问题
7.1 windows安装MinGW-w64
7.2 linux安装Min-w64
7.3 CLion配置成visual studio使用
八、报错处理
/usr/bin/cmake --build /data2/engine/test/test_DataStatistics/cmake-build-debug --target testDataStatistics – -j 14
[ 1%] Linking CXX executable testDataStatistics
/usr/bin/ld: cannot find -lprotobuf
/usr/bin/ld: cannot find -lprotoc
工程中没有libprotobuf.a和libprotoc.a文件
所以静态库文件是如果用了.a文件就不需要源文件了,没有.a就要源文件。当然这是由cmakelist.txt文件设置的。
实际看代码,如果有.a文件了。cmakelist.txt文件也添加了头文件和源文件路径
九、官方参考文档
https://www.jetbrains.com/help/clion/remote-projects-support.html#resync
总结
未完待续