更新时间:2023-11-27 08:33:37下载pdf
涂鸦 TuyaOS 基于 NDK Android.mk 的语法,实现了一套模块化的编译体系,您可以基于这套编译体系直接编译固件。也可以在按照规则在 IDE 中新增文件、文件夹,编译系统会自动加载在特定位置的新文件、文件夹,进行编译。
在 TuyaOS 开发框架中,编译体系主要由以下内容组成的:
build_app.sh
文件。Makefile
文件。./scripts/mk/
目录下的 *.mk
文件。local.mk
文件。vendor/$(TARGET_PLATFORM)/tuyaos/tuyaos_adapter
目录下的 build.sh
文件。build_app.sh
是应用编译入口,从 IDE 直接一键编译,会调用此脚本。build_app.sh
脚本需要提供一些参数,参数如下:
sh build_app.sh $1 $2 $3 $4
$1
:应用工程路径,如 apps/tuyaos_demo_quickstart
$2
:应用工程名,如 tuyaos_demo_quickstart
$3
:版本号,格式 XX.XX.XX,如 1.0.0
$4
:用户指令 (可选),如 clean
build_app.sh
编译出来的固件,保存在 $1/output
路径下,命名为 $2_xx_$3.bin
,其中 xx
为用途,如生产固件为 QIO
,升级固件为 UG
,用户区固件为 UA
等。
Makefile
是编译体系的入口,它汇聚了所有的 *.mk
和 local.mk
。您在执行编译的时候,从 IDE 直接一键编译,或者是在命令行输入 build_app.sh
并提供参数,或者是在命令行输入 make
,最终都会执行 Makefile
,实现对整个 TuyaOS 的编译、链接。
在 IDE 上直接执行 make
命令的时候,需要进行选择要编译的应用程序,并且版本会默认为 1.0.0
。
local.mk
用于描述文件所在目录的编译方式,包括源文件、头文件、编译选项、目标文件。它实际上是一个微小的 GNU MakeFile 片段,TuyaOS 编译体系会解析 local.mk
,然后按照 local.mk
的描述,对源码进行编译。
以下是一个 local.mk
的示例:
LOCAL_PATH := $(call my-dir) # 当前文件所在目录
#----
include $(CLEAR_VARS) # 清除 LOCAL_xxx 变量
LOCAL_MODULE := $(notdir $(LOCAL_PATH)) # 当前模块名
# 模块对外头文件(只能是目录)
# 加载至 CFLAGS 中提供给其他组件使用;打包进 SDK 产物中;
LOCAL_TUYA_SDK_INC := $(LOCAL_PATH)/include
# 模块对外 CFLAGS:其他组件编译时可感知到
LOCAL_TUYA_SDK_CFLAGS :=
# 模块源代码
LOCAL_SRC_FILES := $(shell find $(LOCAL_PATH)/src -name "*.c" -o -name "*.cpp" -o -name "*.cc")
# 模块内部 CFLAGS:仅供本组件使用
LOCAL_CFLAGS :=
# 全局变量赋值
TUYA_SDK_INC += $(LOCAL_TUYA_SDK_INC) # 此行勿修改
TUYA_SDK_CFLAGS += $(LOCAL_TUYA_SDK_CFLAGS) # 此行勿修改
include $(BUILD_STATIC_LIBRARY) # 生成静态库
include $(BUILD_SHARED_LIBRARY) # 生成动态库
#----
local.mk
文件在 IDE 中一般存在于 ./apps/$(APP_NAME)
目录以及 ./vendor/$(TARGET_PLATFORM)/tuyaos/tuyaos_adapter/
目录下。
*.mk
有很多个,保存在 ./scripts/mk/
目录下。主要分为两类:
第一类:描述编译目标的 mk
文件:这些 mk
文件主要描述了编译 TuyaOS 和编译应用的时候需要用到的各种目标。
例如 ./scripts/mk/app.mk
文件描述了编译固件的时候,会编译那些目标。显式目标有:
app_comp_static
:将./apps/$(APP_NAME)/libs/libtuyaapp_components.a
拷贝到 ./libs/
目录下。app_driv_static
:将./apps/$(APP_NAME)/libs/libtuyaapp_drivers.a
拷贝到 ./libs/
目录下。app_adapter_static
:将 $(OUTPUT_DIR)/lib/libtuyaos_adapter.a
拷贝到./libs/
目录下。除了以上显式的目标之外,还有通过 local.mk
描述的编译:
./vendor/$(TARGET_PLATFORM)/tuyaos/tuyaos_adapter/local.mk
编译成 $(OUTPUT_DIR)/lib/libtuyaos_adapter.a
。./apps/$(APP_NAME)/local.mk
编译成 $(OUTPUT_DIR)/lib/lib$(APP_NAME).a
。这些目标都是 app_by_name
的依赖项,在执行 make
命令的时候,默认目标是 app
,app
会让您选择合适的编译对象,然后调用 app_by_name
,对 app_comp_static
、app_driv_static
、app_adapter_static
进行编译,然后调用位于 vendor/$(TARGET_PLATFORM)/tuyaos/tuyaos_adapter
目录下的 build.sh
来进行链接操作。
第二类:编译过程需要使用的一些规则和操作:如 ./scripts/xmake.mk
里会提供编译过程需要的各种函数;需要编译静态库只要在文件末尾 include xmake_static.mk
;编译一个动态库只要在文件末尾 include xmake_shared.mk
等。
build.sh
是 TuyaOS 在编译完成之后,把生成的库文件保存在 ./libs/
目录之后,再进行一些芯片原厂组件编译、使用生成的这些库文件链接、打包成固件。
原厂组件编译:每个原厂都有一些自己的可以开源的组件,如驱动等,可以供您进行修改。这些不属于 TuyaOS 的内容,因此在 TuyaOS 编译之后,再进行编译。
链接:原厂开源组件编译完成之后,此时您拥有了 TuyaOS 编译生成的库文件、原厂开源编译的库文件、原厂闭源的库文件,可以进行二进制文件的生成。
打包生成固件:二进制文件生成之后,按照用途,需要把 BootLoader、固件、配置文件等按需打包生成各种场景下需要的固件,并保存到对应的文件夹之下。
在链接阶段,TuyaOS 编译产生的,存放于 ./libs
目录下的 *.a
文件,可以按照此顺序添加到最后的 LDFLAGS 中:-l$(APP_BIN_NAME) -ltuyaapp_components -ltuyaapp_drivers -ltuyaos -ltuyaos_adapter
。
TuyaOS 在 IDE 上支持三种编译方式:
software/TuyaOS/apps/
目录下子目录,右键菜单选择 build project。sh build_app.sh $1 $2 $3 $4
,参数请参考 build_app.sh 介绍。make
,需要进行选择要编译的应用程序,并且版本会默认为 1.0.0
。编译方式的内部操作流程如下图所示:
在执行 TuyaOS 编译操作的时候,TuyaOS 编译体系会自动的加载默认位置的 local.mk
,然后按照 local.mk
的描述去编译这些位置里的源码。这些位置如下表所示。
文件夹 | 用途 | 编译产物 |
---|---|---|
apps/$(APP_NAME) |
可执行程序目录,一般来说包含程序入口 | lib$(APP_NAME).a |
vendor/$(TARGET_PLATFORM)/tuyaos/tuyaos_adapter |
TuyaOS kernel Adapter 实现 | libtuyaos_adapter.a |
新增源文件放到 apps/$(APP_NAME)/src
目录下,编译系统会自动查找,加入到编译体系中进行编译。
apps/$(APP_NAME)/
路径中有个 local.mk
文件会通过 Shell 脚本自动遍历 apps/$(APP_NAME)/src/
下所有的源文件,并添加到 LOCAL_SRC_FILES
变量中进行编译,生成 lib$(APP_NAME).a
库。
如果您在开发过程中,想使用芯片原厂提供的功能接口,在使用的地方增加头文件引用,调用函数之外,还需要把函数的声明的头文件路径加入到编译搜索的列表中。此时,可以在对应目录中的 local.mk
文件里新增对应接口的头文件路径。示例如下:
# 模块源代码
LOCAL_SRC_FILES := $(shell find $(LOCAL_PATH)/src -name "*.c" -o -name "*.cpp" -o -name "*.cc")
# 模块内部 CFLAGS:仅供本组件使用
LOCAL_CFLAGS += -I$(ROOT_DIR)/vendor/bk7231n/bk7231n_os/beken378/func/user_driver
LOCAL_CFLAGS += -I$(ROOT_DIR)/vendor/bk7231n/bk7231n_os/beken378/driver/include
LOCAL_CFLAGS += -I$(ROOT_DIR)/vendor/bk7231n/bk7231n_os/beken378/common
LOCAL_CFLAGS += -I$(ROOT_DIR)/vendor/bk7231n/bk7231n_os/beken378/app/config
LOCAL_CFLAGS += -I$(ROOT_DIR)/vendor/bk7231n/bk7231n_os/beken378/driver/common
LOCAL_CFLAGS += -I$(ROOT_DIR)/vendor/bk7231n/bk7231n_os/beken378/os/include
LOCAL_CFLAGS += -I$(ROOT_DIR)/vendor/bk7231n/bk7231n_os/beken378/os/FreeRTOSv9.0.0
在开发过程遇到问题,您可以登录 TuyaOS 开发者论坛 联网单品开发版块 进行沟通咨询。
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈