基于VSCode和CMake进行CC++开发【理论】+【实战】Linux篇 |第六讲:CMake

基于VSCode和CMake进行CC++开发【理论】+【实战】Linux篇 |第六讲:CMake,第1张

第六讲:CMake

前言:

  • CMake是一个跨平台的安装编译工具,可以用简单的语句来描述所有平台的安装(编译过程)
  • CMake可以说已经成为大部分C++开源项目标配

6.1 Cross-platfoem development
让我们假设您有一个跨平台的项目,在不同的平台/ ide上共享c++代码。假设你在Windows上使用visual studio,在OSX上使用Xcode,在Linux上使用Makefile:


What you will do if you want to add new bar.cpp source file? You have to add it to every tool you use:

为了保持环境一致,您必须多次进行类似的更新。最重要的是您必须手动完成(在这种情况下,图中用红色标记的箭头)。当然,这种方法容易出错且不灵活。
CMake 通过在开发过程中增加额外的步骤来解决这个设计缺陷。您可以在 CMakeLists.txt 文件中描述您的项目,并使用 CMake 生成您当前感兴趣的工具,使用跨平台 CMake 代码:


Same action - adding new bar.cpp file, will be done in one step now:

Note that the bottom part of the diagram was not changed. I.e. you still can keep using your favorite tools like Visual Studio/msbuild, Xcode/xcodebuild and Makefile/make!

6.2 语法特性
  • 基本语法格式:指令(参数1 参数2…)
    • 参数使用括弧括起
    • 参数之间使用空格或分号分开
  • 指令时大小写无关的,参数和变量是大小写相关的
set(HELLO hello.cpp) add_executable(hello main.cpp hello.cpp) ADD_EXECUTABLE(hello main.cpp ${HELLO})
  • 变量使用${}的方式取值,但是在IF控制语句中是直接使用变量名
if(HELLO)而不是 if($(HELLO))

6.3 重要的指令和CMake常用变量
6.3.1 重要指令
  • cmake_minimum_required -指定CMake的最小版本要求
    • 语法:cmake_minimum_required(VERSION versionNumber [FATAL_ERROR])

    #CMake 最小版本要求位2.8.3

    cmake_minimum_required(VERSION 2.8.3)
  • project定义工程名称,并指定工程支持的语言
    • 语法:project(projectname [CXX][C] [Java]). 中括号里的代表[可选项]

    #指定工程名为HELLOWORLD

    project(HELLOWORLD)
  • set -显式的定义变量
    • 语法:set(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])

#定义SRC变量,其值为sayhello.cpp hello.cpp
s#### et(SRC sayhello.cpp hello.cpp)

  • include_directories -向工程添加多个特定的头文件搜索路径—>相当于指定g++编译器的**-I**参数
    • 语法:include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2…)

#将/usr/include/myincludefolder和./include 添加到头文件搜索路径

include_directories(/usr/include/myincludefolder ./include)
  								     绝对路径                             相对路径
  • link_directories-向工程添加多个特定的库文件搜索路径—>相当于指定g++编译器的**-L**参数
    • 语法:link_directories(dir1 dir2 …)

#将/usr/lib/mylibfolder和./lib 添加到头文件搜索路径

link_directories(/usr/lib/mylibfolder ./lib)
  • add_library-生成库文件
    • 语法:add_library(libname [SHARED|STATIC|MODULE] [EXCLUDE_FORM_ALL] source1 source2 … sourceN)

#通过变量SRC生成libhello.so文件共享库

add_library(hello SHARED ${SRC})
  • add_compile_options-添加编译参数
    • 语法:add_compile_options( …)

#添加编译参数 -Wall -std=c++11

add_compile_options(-Wall -std=c++11 -o2)
  • add_executable-生成可执行文件
  • 语法: add_executable(exename source1 source2 … sourceN)

#编译main.cpp生成可执行文件main

add_executable(main main.cpp)
  • target_link_libraries-为target添加需要链接的共享库–>相当于指定g++编译器**-l参数**
    • 语法:target_link_libraries(target library1 library2 …)

#将hello动态库文件链接到可执行文件mian

target_link_libraries(main hello)
  • add_subdirectory-向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置
    • 语法:add_subdirectory(source_dir [binary_dir] [EXCLUDE_FRO M_ALL])

#添加src子目录,src中需有一个CMakeLists.txt

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

#定义SRC变量,其值为当前目录下随哦有的源代码文件

aux_source_director y(. SRC)

#编译SRC变量所代表的源代码文件,生成main可执行文件

add_executable(main ${SRC})

6.3.2 CMake常用变量
  • CMAKE_C_FLAGS gcc编译选项
  • CMAKE_CXX_FLAGS g++编译选项

#在CMAKE_CXX_FLAGS 编译选项后追加-std=c++11

set( CMAKE_CXX_FLAGS “${CMAKE_CXX_FLAGS } -std=c++11”
  • CMAKE_BUILD_TYPE编译类型(Debug,Release)

#设定编译类型为debug,调试时需要选择debug

set(CMAKE_BUILD_TYPE Debug)

#设定编译类型为release,发布时需要选择release

set(CMAKE_BUILD_TYPE Release)
  • CMAKE_BINARY_DIR
  • PROJECT_BINARY_DIR
  • _BINARY_DIR

1、这三个变量指代的内容是一致的
2、如果是in source build,指的就是工程顶层目录;
3、如果是out-of-source编译,指的就是工程编译发生的目录;
4、PROJECT_BINARY_DIR跟其他指令稍有区别,不过现在,你可以理解为他们是一致的。

  • CMAKE_SOURCE_DIR
    PROJECT_SOURCE_DIR
    _SOURCE_DIR

1、这三个变量指代的内容是一致的,不论采用何种编译方式,都是工程顶层目录;
2、也就是在 in source build时,他跟CMAKE_BINARY_DIR等变量一致;
3、PROJECT_SOURCE_DIR跟其他指令稍有区别,现在可以线理解为一致的。

  • CMAKE_C_COMPILER:指定C编译器
  • CMAKE_CXX_COMPILER:指定C++编译器
  • EXECUTABLE_OUTPUT_PATH:可执行文件输出的存放路径
  • LIBRARY_OUTPUT_PATH:库文件输出的存放路径

6.4 CMake编译工程

CMake目录结构:项目主目录存在一个CMakeLists.txt文件
两种方式设置编译规则:
1、包含源文件的子文件夹包含CMakeLists.txt文件,主目录的CMakeLists.txt通过add_subdirectory添加子目录即可;
2、包含源文件的子文件夹包含CMakeLists.txt文件,子目录编译规则体现在主目录的CMake.txt中;


6.4.1编译流程

在Linux平台下使用CMake构建C/C++工程的流程如下:

  • 1、手动编写CmakeLists.txt
  • 2、执行命令cmake PATH生成Makefile(PATH是顶层CMakeLists.txt所在的目录)。
  • 3、执行命令make进行编译。

#important tips

. #表示当前目录 ./ #表示当前目录 … #表示上级目录 …/ #表示上级目录

6.4.2 两种构建方式
  • 内部构建(in-source build):不推荐使用
    内部构建会在同级目录下产生一大堆中间文件,这些中间文件并不是最终需要的,和工程源文件放在一起会显得杂乱无章。

##内部构建
#在当前目录下,编译本目录的CMakeLists.txt,生成Makefile和其他文件

cmake .

#执行make命令,生成target

make
  • 外部构建(out-of-source build):推荐使用
    将编译文件输出文件与源文件放到不同目录中

##外部构建
#1、在当前目录下,创建build文件夹

mkdir build

#2、进入带build文件夹

cd build

#3、编译上级目录的CMakeLists.txt,生成Makefile和其他文件

cmake …

#4、执行make命令,生成target

make

6.5【实战】CMake代码时间

针对第五讲写的两个小项目来写对应的CMakeLists.txt


6.5.1最小CMake工程

#set the mimimum version of CMake that can be used

camke_mimimum_required(VERSION 3.0)

#set the project name

project(HELLO)

#add an executable

add_executable(hello_cmake main.cpp)
6.5.2多目录工程-直接编译

#set the mimimum version of CMake that can be used

cmake_minimum_required(VERSION 3.0)

#set the project name

project(SWAP)

#head file path

include_directories(include)

#add an executable

add_executable(main_cmake main.cpp src/swap.cpp)

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1353758.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-14
下一篇 2022-06-14

发表评论

登录后才能评论

评论列表(0条)

保存