embedded-framework/README.md
2024-06-07 17:57:34 +08:00

123 lines
4.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 1. 一个嵌入式软件架构的示例
## 1.1. 概述
  从嵌入式软件角度来描述软件架构开发方法。
欢迎在仓库里面提issue交流学习。
## 1.2. 嵌入式软件架构基本要素
```mermaid
pie
title 嵌入式软件开发
"源码构建" : 10
"架构设计" : 30
"代码调试/版本测试" : 10
"代码动态测试" : 20
"代码静态检测" : 5
"代码自动格式化" : 5
"平台适配" : 10
"设计文档" : 5
"工具使用" : 5
```
  本仓库从上述全方面来部署一个嵌入式软件开发项目。各部分环环相扣不分彼此,组成一个完整的健康的敏捷的可持续的嵌入式开发体系。
### 1.2.1. 源码构建
  源码构建是一个嵌入式软件项目的开始,属于嵌入式软件开发的最基础要素,他决定了开发者使用何种方式何种工具来部署 / 编译项目源码。源码构建方案设计会直接影响到开发效率。
  源码构建的工具很多嵌入式开发中常见的有Makefile / CMake / Scons / GN等例如国内比较热门的开源项目鸿蒙系统使用GN作为构建工具。由于历史原因Makefile是相对古老的源码构建工具大部分开源项目使用的都是Makefile随着发展部分开源项目开始增加使用CMake构建脚本此时开源项目同时支持Makefile和CMake两种构建方案。构建工具的选择没有好坏之分大部分后开发的工具都会针对性解决前者的一些缺陷往往后来者会有更多的优点。本仓库自研部分使用的是CMake工具进行源码构建。
**一个CMakeList.txt脚本示例**
  通俗来讲CMakeList.txt脚本就是告诉编译器从哪里搜索头文件 / 把哪些源代码编译 / 从哪里找到哪些链接库 /输出什么文件到哪个目录。
```code
include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake) // 一个配置文件
set(EXECUTABLE_OUTPUT_PATH ${EXEC_OUTPUT_PATH}) // 设置可执行文件的输出目录
set(LIBRARY_OUTPUT_PATH ${LIBS_OUTPUT_PATH}) // 设置库的输出目录
include_directories( // 编译时搜索头文件路径
./src
./include
${UTILS_SOURCE_PATH}/StatusCode/include
${UTILS_SOURCE_PATH}/Log/include
)
#use link_directories when need to link any other library.
#link_directories( // 链接时链接库的搜索路径
#)
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
aux_source_directory(./src SRC_FILES) // 设置需要编译的源码文件
set(TARGET_NAME StatusCode)
add_library(${TARGET_NAME} STATIC ${SRC_FILES}) // 生成一个静态库
target_link_libraries(${TARGET_NAME} Log) // 设置前述静态库的库依赖关系
if ("${CLANG_TIDY_SUPPORT}" MATCHES "true") // 静态代码检测
add_custom_target(
StatusCode_code_check
COMMAND ${CLANG_TIDY_EXE}
-checks='${CLANG_TIDY_CHECKS}'
--header-filter=.*
--system-headers=false
${SRC_FILES}
${CLANG_TIDY_CONFIG}
-p ${CMAKE_SOURCE_DIR_IPCSDK}/cmake-shell-linux
WORKING_DIRECTORY ${UTILS_SOURCE_PATH}/StatusCode
)
add_custom_command(
TARGET ${TARGET_NAME}
# TARGET ${ABSTRACT_TARGET}
PRE_BUILD
COMMAND make StatusCode_code_check
WORKING_DIRECTORY ${PROJECT_ROOT_PATH}/cmake-shell-linux/
)
endif()
```
#### 1.2.1.1. 源码构建当中的工具使用
##### 1.2.1.1.1. 代码静态检测(编码规范)
  在编译的时候使用clang-tidy工具针对性选择对自研部分的代码进行静态检测。
示例:
```code
add_custom_target(
SharedData_code_check
COMMAND ${CLANG_TIDY_EXE}
-checks='${CLANG_TIDY_CHECKS}'
--header-filter=.*
--system-headers=false
${SRC_FILES}
${CLANG_TIDY_CONFIG}
-p ${CMAKE_SOURCE_DIR_IPCSDK}/cmake-shell
WORKING_DIRECTORY ${UTILS_SOURCE_PATH}/SharedData
)
```
##### 1.2.1.1.2. 代码格式化
  在编译的时候使用clang-format工具针对性选择对自研部分的代码进行自动格式化实现编码格式的客观绝对统一。
示例:
```code
add_custom_target(
SharedData_code_format
COMMAND ${CLANG_FORMAT_EXE}
-style=file
-i ${SRC_FILES} ${HEADER_FILES}
WORKING_DIRECTORY ${UTILS_SOURCE_PATH}/SharedData
)
```
### 1.2.2. 架构设计
  抛开产品业务不进行描述,代码部署主要使用分层模块化的代码结构,结合面向对象的多态设计模式进行代码开发,使得业务代码在部署时具备灵活多变的特性,进一步提高代码的复用性,最终实现产品业务软件层面的敏捷迭代。