在之前的博客中提到,ESP-IDF采用的是CMake来构建项目,因此需要学习一下CMake,以对ESP32的开发有更好的把握

参考:

Windows下CMake安装教程

从零开始详细介绍CMake

CMake是一种高级编译配置工具,当多人用不同的语言或编译器开发一个项目,最终要输出一个可执行文件或共享库(dll,so等),就可以使用CMake,CMake的所有操作都是通过编译CMakeLists.txt来完成的

CMake的学习其实最好还是在开发中不断的学习,不过掌握一点基础的知识也是可以的,在这里推荐一个github的项目:

cmake-examples

里面有一些案例,可以一步步学习CMake,而且这个项目是英文的,可以锻炼一下自己的英文水平(~ ̄▽ ̄)~

CMake编译helloworld

// helloworld.cpp
#include <iostream>
int int main() {
std::cout << "hello world" << std::endl;
}
# CMakeLists.txt
PROJECT(helloworld)
SET(SRC_LIST helloworld.cpp)
MESSAGE(STATUS "This is BINARY dir" ${helloworld_BINARY_DIR})
MESSAGE(STATUS "This is SOURCE dir" ${helloworld_SOURCE_DIR})
ADD_EXECUTABLE(hello ${SRC_LIST})

CMake可以搜索平台环境,然后生成平台上用于build的文件,比如在windows上安装了visual studio,能够生成.sln,.vcxproj文件,在Linux上能够生成Makefile,CMakeLists.txt本质上就是和平台无关的配置文件,里面存有要运行的CMake指令,接下来是使用CMake在Ubuntu上构建helloworld的过程:

关于上面的CMakeLists.txt的语法说明:

  • PROJECT关键字:用于指定工程的名字和支持的语言,默认支持所有语言

    • PROJECT(helloworld):指定了工程名字,且支持所有语言
    • PROJECT(helloworld cxx):指定了工程名字,且支持语言是c++
    • PROJECT(helloworld c cxx):指定了工程名字,且支持语言是c和c++
    • 该指令隐式定义了两个CMake的变量
      • <project_name>_BINARY_DIR,本例中是helloworld_BINARY_DIR
      • <project_name>_SOURCE_DIR,本例中是helloworld_SOURCE_DIR
      • MESSAGE关键字可以直接使用这两个变量,都指向当前的工作目录,在外部编译时有所区别
  • SET关键字:用于显式指定变量

    • SET(SRC_LIST helloworld.cpp):SRC_LIST变量包含了helloworld.cpp
    • 也可以SET(SRC_LIST helloworld.cpp a.cpp b.cpp)
  • MESSAGE关键字:向终端输出用户自定义信息,主要包含三种信息:

    • SEND_ERROR:产生错误,生成过程被跳过
    • STATUS:输出前缀为--的信息
    • FATAL_ERROR:立即终止所有CMake过程
  • ADD_EXECUTABLE关键字:生成可执行文件

    • ADD_EXECUTABLE(hello ${SRC_LIST}):生成可执行文件名是hello,源文件读取变量SRC_LIST中的内容
    • 可以直接写ADD_EXECUTABLE(hello helloworld.cpp)

因此上述例子可简写为:

PROJECT(helloworld)

ADD_EXECUTABLE(hello helloworld.cpp)

上面的工程名和生成的可执行文件名是没有任何关系的

CMake语法的基本规则

  • 变量使用${}方式取值,但是在IF控制语句中直接使用变量名
  • 指令(参数1,参数2,...):参数用括弧括起,参数之间使用空格或分号分开
  • 指令是大小无关的,参数和变量时大小写相关的,推荐使用大写指令

其他注意事项:

  • SET(SRC_LIST helloworld.cpp)可以写为SET(SRC_LIST "helloworld.cpp"):如果源文件名中含有空格,则必须要加双引号
  • ADD_EXECUTABLE(hello helloworld):后缀可以不写,会自动去找.c和.cpp,但是因为可能有两个文件因此最好不要这样写

CMake内部构建和外部构建

上述的helloworld的例子使用的是内部构建,生成的临时文件较多,不方便清理

外部构建会把生成的临时文件放在build目录下,不会对源文件产生影响

步骤:

  • 在当前目录建立一个build目录,可以在任何地方,这一点便于在任何时候都可以从头开始使用CMake进行构建
  • 进入build,运行cmake..(..表示上一级目录,可以写CMakeLists.txt所在的绝对路径,生产的文件都在build目录下,当然这个是建立在你创建的build目录是在当前目录下的)
  • 在build目录下,运行make来构建工程

在外部构建下的两个变量:

  • helloworld_BINARY_DIR:仍为工程路径
  • helloworld_SOURCE_DIR:编译路径,即用户名/cmake/build

【ESP32学习】CMake学习的更多相关文章

  1. CMake学习(1)---简单程序与库

    cmake是linux平台下重要的工具,可以方便的组织makefile.之前一直在windows平台下进行软件开发,在vs2010的IDE里,只要一点run程序就能跑出结果.但是程序的编译并没有那么简 ...

  2. cmake 学习笔记(六)

    希望这是现阶段阻碍阅读shiboken和PySide源码的涉及cmake的最后一个障碍 ^ _^ 学习 cmake 的单元测试部分 ctest. 简单使用 最简单的使用ctest的方法,就是在 CMa ...

  3. cmake学习笔记(五)

    在cmake 学习笔记(三) 中简单学习了 find_package 的 model 模式,在cmake 学习笔记(四)中了解一个CMakeCache相关的东西.但靠这些知识还是不能看懂PySide使 ...

  4. cmake 学习笔记(三)

    转自:http://blog.csdn.net/dbzhang800/article/details/6329314 接前面的 Cmake学习笔记(一) 与 Cmake学习笔记(二) 继续学习 cma ...

  5. cmake 学习笔记(二)

    在 Cmake学习笔记一 中通过一串小例子简单学习了cmake 的使用方式. 这次应该简单看看语法和常用的命令了. 简单的语法 注释 # 我是注释 命令语法 COMMAND(参数1 参数2 ...) ...

  6. 一起学习CMake – 03

    这一节我们就一起来看看如何用CMake来链接自己写的lib库,如何进行这些库文件的管理. 一个团队共同开发软件时,一般都是分模块进行作业的,每个人负责整个软件中的一部分,然后再整合成一个完整的软件系统 ...

  7. 一起学习CMake – 02

    本节介绍如何用CMake来设置软件的版本号 在<一起学习CMake - 01>中我们看到了如何用CMakeLists.txt来构建一个最简单的工程,这一节里我们一起来看看如何用CMake对 ...

  8. CMake学习

    CMake学习 本篇分享一下有关CMake的一些学习心得以及相关使用. 作者:AlphaGL.版权所有,欢迎保留原文链接进行转载 :) 本文目录如下: 1.CMake介绍 2.CMake安装与使用 2 ...

  9. cmake 学习笔记(三) (转)

    接前面的 Cmake学习笔记(一) 与 Cmake学习笔记(二) 继续学习 cmake 的使用. 学习一下cmake的 finder. finder是神马东西? 当编译一个需要使用第三方库的软件时,我 ...

  10. 一起学习CMake – 01

    一起学习CMake – 01 本节介绍CMake里最常用的三个命令,分别是cmake_minimum_required; project; add_executable等. CMake是个好东西,在使 ...

随机推荐

  1. cmake:macro,function中ARGV,ARGN参数的区别

    cmake中的宏(macro)和函数(function)都支持动态参数 变量ARGC记录传入的参数个数 变量ARGV0,ARGV1,...顺序代表传入的参数 变量ARGV则是一个包含所有传入参数的li ...

  2. 人脸识别:face_recognition初尝试

    在学习face_recognition之前先看git上的另一个项目:face_collection .face_collection某种程度上可以看做是demo,便于我们更好的理解和使用face_re ...

  3. go环境 依赖管理 基本命令

    Go安装 Go官网下载地址:https://golang.org/dl/ Go官方镜像站(推荐):https://golang.google.cn/dl/ Windows 选择Windows版本下载安 ...

  4. vue3 reactive值不更新

    即上一个随笔里面的form表单数据定义的问题之后,又出现了另一个问题. 页面里面有一个数组: let ruleForm = reactive([     { name:'123456' } ]) 我要 ...

  5. winform 子控件触发父控件事件

    private void circlePanel_Click(object sender, EventArgs e) { var panel=sender as UIPanel; if (panel. ...

  6. Django里ORM常用关键字

    一.ORM常用关键字 # 关键概览 1.create() 2.filter() 3.first() last() 4.update() 5.delete() 6.all() 7.values() 8. ...

  7. ENGG1340 Computer Programming II

    课程内容笔记,自用,不涉及任何 assignment,exam 答案 Notes for self use, not included any assignments or exams Module ...

  8. NXOpen拉伸

    #include <NXOpen/Annotations.hxx> #include <NXOpen/Assemblies_Component.hxx> #include &l ...

  9. 日志分析查看—— cat+grep+awk+uniq+sort+wc+join

    有个统计日志信息的需求,下面是使用到的命令 //按 \t 对文件每一行进行切割,正则匹配第二列为32896时,输出第一列:再进行排序并去重,最后统计行数 cat file.log|awk -F '\t ...

  10. 反射 1 加载指定的DLL

    我们通常 都是用反射来操作指定的程序集(dll,exe). 需要引用 System.Reflection 有三种加载方式 Assembly assembly = Assembly.Load(" ...