make、makefile、cmake、kconfig是怎么做工程管理的?

文章目录

    要解决的问题
    makefile和make
    cmake
    kconfig
    如何查看编译了哪些文件?
    如何增加驱动?
        将相关驱动加到现有文件夹中
        建立单独文件夹
    其他构建系统
    工程样例
    相关链接

要解决的问题

大型工程项目

    make、makefile、cmake、kconfig都是干什么的,他们之间什么关系
    如何查看编译了哪些文件?
    如何增加驱动?

大型工程一般使用make构建的,了解了相关原理就能解决上述问题。
本文用的工程样例是:https://github.com/sipeed/MaixPy.git
makefile和make

一个工程中的源码文件不计其数,需要有一系列的规则说明:

    需要编译哪些文件,如何编译指定编译顺序。哪些文件先编译、哪些文件后编译、哪些文件需要重新编译。
    需要创建哪些库文件以及如何创建这些库文件
    如何最后产生我们想要的可执行文件

把这些规则写到一个文件里,就是Makefile。
make是一个命令工具,用于解释Makefile中的指令。
尝试写一个hellloworld的程序

#include<stdio.h>
int main(){
     printf("hello 峡谷金城武\n");
     return 0;
}

    1
    2
    3
    4
    5

当我们想对这个hello.c生成可执行文件,通常采用

gcc hello.c -o hello

    1

我们采用Makefile来编写这段代码,新建文件Makefile:

hello:hello.c
        gcc hello.c -o hello

    1
    2

使用make指令运行makefile,我们可以看到如下效果
make
cmake

大型工程的makefile文件非常复杂,一般人根本搞不懂,也不会写。有没有简单的方法来生成目标文件呢?
当然有。
如果说make-makefile是一个工程构建系统,cmake就是生成这个构建系统的系统。他可以生成各种IDE的工程文件或解决方案和makefile。
cmake通过读取脚本文件——CMakeLists.txt 中的规则来构建编译系统
举例说明:
生成可运行文件,打印HelloWorld

    1.使用cmake构建系统生成makefile
    2.使用make生成目标文件
    3.最后运行目标文件

1.准备源文件
在这里插入图片描述
main.cpp:

//main.cpp
#include <iostream>
int main() {
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

    1
    2
    3
    4
    5
    6

CMakeLists.txt:

cmake_minimum_required(VERSION 3.9)
project(HelloWorld)
set(CMAKE_CXX_STANDARD 11)
add_executable(HelloWorld main.cpp)

    1
    2
    3
    4

2.执行cmake:

(base) andrew@myg-pc:~/src/learncmake$ ls
CMakeLists.txt  main.cpp
(base) andrew@myg-pc:~/src/learncmake$ mkdir build
(base) andrew@myg-pc:~/src/learncmake$ cd build/
(base) andrew@myg-pc:~/src/learncmake/build$ cmake ..
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc - works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/andrew/src/learncmake/build
(base) andrew@myg-pc:~/src/learncmake/build$ ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  Makefile
(base) andrew@myg-pc:~/src/learncmake/build$ cd ..
(base) andrew@myg-pc:~/src/learncmake$ ls
build  CMakeLists.txt  main.cpp
(base) andrew@myg-pc:~/src/learncmake$

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28

cmake之后文件,可以看到build文件夹下自动生成很多makefile相关文件
在这里插入图片描述
3.执行make,生成目标文件

(base) andrew@myg-pc:~/src/learncmake/build$ make
Scanning dependencies of target HelloWorld
[ 50%] Building CXX object CMakeFiles/HelloWorld.dir/main.cpp.o
[100%] Linking CXX executable HelloWorld
[100%] Built target HelloWorld
(base) andrew@myg-pc:~/src/learncmake/build$ ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  HelloWorld  Makefile

    1
    2
    3
    4
    5
    6
    7

可见生成了HelloWorld
在这里插入图片描述
4.运行HelloWorld

(base) andrew@myg-pc:~/src/learncmake/build$ ./HelloWorld
Hello, World!
(base) andrew@myg-pc:~/src/learncmake/build$

    1
    2
    3

cmake除了生成编译规则,还有其他功能:

    生成安装规则

# 指定 MathFunctions 库的安装路径
install (TARGETS MathFunctions DESTINATION bin)
install (FILES MathFunctions.h DESTINATION include)

    1
    2
    3

通过上面的定制,生成的 Demo 文件和 MathFunctions 函数库 libMathFunctions.o 文件将会被复制到 /usr/local/bin 中,而 MathFunctions.h 和生成的 config.h 文件则会被复制到 /usr/local/include 中。

    为工程添加测试
    添加测试同样很简单。CMake 提供了一个称为 CTest 的测试工具。我们要做的只是在项目根目录的 CMakeLists 文件中调用一系列的 add_test 命令。
    支持 gdb调试
    让 CMake 支持 gdb 的设置也很容易,只需要指定 Debug 模式下开启 -g 选项:

set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")

    1
    2
    3

    添加环境检查
    添加版本号
    生成安装包
    cmake提供Cpack打包工具,可以配置生成各平台的安装包,包括二进制安装包和源码安装包。
    将其他平台的项目迁移到 CMake

kconfig

了解了cmake,基本上能用比较简单的方式组织源文件结构了。
系统稍微复杂,又会出现新问题,举个例子:
一套代码有很多模块,lcd、触摸屏、摄像头、SPI、I2C、UART等。其中摄像头模块依赖I2C模块。
这套代码可以运行在N个单板,A单板没有摄像头,不需要编译摄像头模组;B单板需要编译全部模块。
如何灵活配置编译单元?
编译过linux就会知道,make menuconfig可以很方便选择编译单元并且配置相关参数。
make menuconfig使用的就是kconfig
kconfig用来做系统配置,生成配置文件:

    供cmake使用:CMakeList会使用这些参数
    用于编译源码

make menuconfig生成的配置文件有:

    *.cmake:cmake文件,里面是一些set指令,给变量赋值。
    *.mk:make的配置文件,里面是一些编译变量
    *.h:可在make或make之前的menuconfig时生成

举例说明:
https://github.com/sipeed/MaixPy.git
在这里插入图片描述
MaixPy/Kconfig:

mainmenu "C/CPP CMake project framework Kconfig configuration"

menu "Toolchain configuration"
    config TOOLCHAIN_PATH
        string "toolchain path"
        default ""
    
    config TOOLCHAIN_PREFIX
        string "toolchain prefix"
        default ""
endmenu

menu "Components configuration"
    osource "${SDK_PATH}/components/*/Kconfig"
    osource "${PROJECT_PATH}/*/Kconfig"
endmenu

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

在这里插入图片描述在这里插入图片描述工程提供了默认makefile配置文件:MaixPy/projects/maixpy_k210_minimum/config_defaults.mk 。里面是一些默认配置,make menuconfig读取这个文件生成默认菜单选项。

# Toolchain configuration
#
CONFIG_TOOLCHAIN_PATH="/opt/kendryte-toolchain/bin"
CONFIG_TOOLCHAIN_PREFIX="riscv64-unknown-elf-"
# end of Toolchain configuration
# Board config
CONFIG_BOARD_MAIX=y
# CONFIG_BOARD_M5STICK is not set
CONFIG_LCD_DEFAULT_WIDTH=320
CONFIG_LCD_DEFAULT_HEIGHT=240
CONFIG_LCD_DEFAULT_FREQ=15000000
CONFIG_SENSOR_FREQ=24000000

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

*.cmake:cmake文件,里面是一些set指令,给变量赋值。

set(CONFIG_TOOLCHAIN_PATH "/opt/kendryte-toolchain/bin")
set(CONFIG_TOOLCHAIN_PREFIX "riscv64-unknown-elf-")
set(CONFIG_BOARD_MAIX "y")
set(CONFIG_BOARD_M5STICK "")
set(CONFIG_LCD_DEFAULT_WIDTH "320")
set(CONFIG_LCD_DEFAULT_HEIGHT "240")
set(CONFIG_LCD_DEFAULT_FREQ "15000000")

    1
    2
    3
    4
    5
    6
    7

*.mk:make的配置文件,里面是一些编译变量

# Toolchain configuration
CONFIG_TOOLCHAIN_PATH="/opt/kendryte-toolchain/bin"
CONFIG_TOOLCHAIN_PREFIX="riscv64-unknown-elf-"
# end of Toolchain configuration
# Board config
CONFIG_BOARD_MAIX=y
# CONFIG_BOARD_M5STICK is not set
CONFIG_LCD_DEFAULT_WIDTH=320
CONFIG_LCD_DEFAULT_HEIGHT=240
CONFIG_LCD_DEFAULT_FREQ=15000000
CONFIG_SENSOR_FREQ=24000000
# end of Board config

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

*.h:可在make或make之前的menuconfig时生成

#define CONFIG_TOOLCHAIN_PATH "/opt/kendryte-toolchain/bin"
#define CONFIG_TOOLCHAIN_PREFIX "riscv64-unknown-elf-"
#define CONFIG_BOARD_MAIX 1
#define CONFIG_LCD_DEFAULT_WIDTH 320
#define CONFIG_LCD_DEFAULT_HEIGHT 240
#define CONFIG_LCD_DEFAULT_FREQ 15000000

    1
    2
    3
    4
    5
    6

如何查看编译了哪些文件?

    make menuconfig,查看编译选项
    查看各个目录下的CMakeList.txt
    语法比较简单,根据list、append_srcs_dir等函数可以看出来包含了哪些文件夹。
    下面例子中的宏定义就是在make menuconfig阶段确定的,其值可以在*.mk(MaixPy/projects/maixpy_k210/build/config/global_config.mk)中查阅。
    MaixPy/components/kendryte_sdk/CMakeLists.txt

if(CONFIG_COMPONENT_KENDRYTE_SDK_ENABLE)

################# Add include #################
list(APPEND ADD_INCLUDE "include"
                        "kendryte-standalone-sdk/lib/bsp/include"
                        "kendryte-standalone-sdk/lib/drivers/include"
                        "kendryte-standalone-sdk/lib/utils/include"
    )

############## Add source files ###############
append_srcs_dir(ADD_SRCS "kendryte-standalone-sdk/lib/bsp")
append_srcs_dir(ADD_SRCS "kendryte-standalone-sdk/lib/drivers")
append_srcs_dir(ADD_SRCS "src")
if(CONFIG_FREERTOS_ENABLE)
    append_srcs_dir(ADD_SRCS "kendryte-standalone-sdk/lib/freertos")
    append_srcs_dir(ADD_SRCS "kendryte-standalone-sdk/lib/freertos/portable")

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

如何增加驱动?
将相关驱动加到现有文件夹中

不需要改动CMakeList.txt、*.mk和Kconfig
建立单独文件夹

    在Kconfig中添加相关目录、配置信息
    在*.mk中增加相关配置开关
    在CMakeList.txt中增加相关文件夹

其他构建系统

除了makefile+cmake这套构建系统,还有其他构建系统,比如

    automake
    与cmake类似
    SCons
    Scons是一个开放源码、以Python语言编码的自动化构建工具,可用来替代make编写复杂的makefile。并且scons是跨平台的,只要scons脚本写的好,可以在Linux和Windows下随意编译。

    What is SCons?
    SCons is an Open Source software construction tool—that is, a next-generation build tool. Think of SCons as an improved, cross-platform substitute for the classic Make utility with integrated functionality similar to autoconf/automake and compiler caches such as ccache. In short, SCons is an easier, more reliable and faster way to build software.

    Ninja
    与make类似,可通过cmake生成Ninja的配置

    Ninja is a small build system with a focus on speed. It differs from other build systems in two major respects: it is designed to have its input files generated by a higher-level build system, and it is designed to run builds as fast as possible.

工程样例

    https://github.com/Neutree/c_cpp_project_framework
    https://github.com/wzpan/cmake-demo
        CMake 入门实战
    https://github.com/XierHacker/LearningCMake
        CMake入门实践(一) 什么是cmake
        CMake入门实践(二) 多文件构建
        CMake入门实践(三) :复杂的HelloWorld项目
    https://github.com/sipeed/MaixPy

相关链接

    https://blog.csdn.net/zhuiyunzhugang/article/details/88142908
    https://zhuanlan.zhihu.com/p/87283287
————————————————
版权声明:本文为CSDN博主「myg22」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/myg22/article/details/104572113

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值