文章目录
要解决的问题
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