dadk_user/
lib.rs

1//! # DADK - DragonOS Application Development Kit
2//! # DragonOS 应用开发工具
3//!
4//! ## 简介
5//!
6//! DADK是一个用于开发DragonOS应用的工具包,设计目的是为了让开发者能够更加方便的开发DragonOS应用。
7//!
8//! ### DADK做什么?
9//!
10//! - 自动配置libc等编译用户程序所需的环境
11//! - 自动处理软件库的依赖关系
12//! - 自动处理软件库的编译
13//! - 一键将软件库安装到DragonOS系统中
14//!
15//! ### DADK不做什么?
16//!
17//! - DADK不会帮助开发者编写代码
18//! - DADK不提供任何开发DragonOS应用所需的API。这部分工作由libc等库来完成
19//!
20//! ## License
21//!
22//! DADK is licensed under the [GPLv2 License](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html).
23//!
24//! ## 快速开始
25//!
26//! ### 安装DADK
27//!
28//! DADK是一个Rust程序,您可以通过Cargo来安装DADK。
29//!
30//! ```shell
31//! # 从GitHub安装最新版
32//! cargo install --git https://github.com/DragonOS-Community/DADK.git
33//!
34//! # 从crates.io下载
35//! cargo install dadk
36//!
37//! ```
38//!
39//! ## DADK的工作原理
40//!
41//! DADK使用(任务名,任务版本)来标识每个构建目标。当使用DADK构建DragonOS应用时,DADK会根据用户的配置文件,自动完成以下工作:
42//!
43//! - 解析配置文件,生成DADK任务列表
44//! - 根据DADK任务列表,进行拓扑排序。这一步会自动处理软件库的依赖关系。
45//! - 收集环境变量信息,并根据DADK任务列表,设置全局环境变量、任务环境变量。
46//! - 根据拓扑排序后的DADK任务列表,自动执行任务。
47//!
48//! ### DADK与环境变量
49//!
50//! 环境变量的设置是DADK能正常工作的关键因素之一,您可以在您的编译脚本中,通过引用环境变量,来获得其他软件库的编译信息。
51//! 这是使得您的应用能够自动依赖其他软件库的关键一步。
52//!
53//! 只要您的编译脚本能够正确地引用环境变量,DADK就能够自动处理软件库的依赖关系。
54//!
55//! DADK会设置以下全局环境变量:
56//!
57//! - `DADK_CACHE_ROOT`:DADK的缓存根目录。您可以在编译脚本中,通过引用该环境变量,来获得DADK的缓存根目录。
58//! - `DADK_BUILD_CACHE_DIR_任务名_任务版本`:DADK的任务构建结果缓存目录。当您要引用其他软件库的构建结果时,可以通过该环境变量来获得。
59//! 同时,您也要在构建您的app时,把构建结果放到您的软件库的构建结果缓存目录(通过对应的环境变量获得)中。
60//! - `DADK_SOURCE_CACHE_DIR_任务名_任务版本`:DADK的某个任务的源码目录。当您要引用其他软件库的源码目录时,可以通过该环境变量来获得。
61//!
62//! 同时,DADK会为每个任务设置其自身在配置文件中指定的环境变量。
63//!
64//! #### 全局环境变量命名格式
65//!
66//! 全局环境变量中的任务名和任务版本,都会被转换为大写字母,并对特殊字符进行替换。替换表如下:
67//!
68//! | 原字符 | 替换字符 |
69//! | ------ | -------- |
70//! | `.`    | `_`      |
71//! | `-`    | `_`      |
72//! | `\t`   | `_`      |
73//! | 空格   | `_`      |
74//! | `+`    | `_`      |
75//! | `*`    | `_`      |
76//!
77//! **举例**:对于任务`libc-0.1.0`,其构建结果的全局环境变量名为`DADK_BUILD_CACHE_DIR_LIBC_0_1_0`。
78//!
79//!
80//! ## TODO
81//!
82//! - 支持从在线归档文件下载源码、构建好的软件库
83//! - 支持自动更新
84//! - 完善clean命令的逻辑
85
86#![feature(extract_if)]
87#![feature(io_error_more)]
88
89#[macro_use]
90extern crate lazy_static;
91pub extern crate clap;
92extern crate log;
93extern crate serde;
94extern crate serde_json;
95
96#[cfg(test)]
97extern crate test_base;
98
99use std::{path::PathBuf, process::exit, sync::Arc};
100
101use context::DadkUserExecuteContext;
102use log::info;
103use parser::task::DADKTask;
104
105use crate::scheduler::Scheduler;
106
107pub mod context;
108pub mod executor;
109pub mod parser;
110mod scheduler;
111mod utils;
112
113pub fn dadk_user_main(context: DadkUserExecuteContext) {
114    let context = Arc::new(context);
115    context.init(context.clone());
116    // DragonOS sysroot在主机上的路径
117
118    info!(
119        "DragonOS sysroot dir: {}",
120        context
121            .sysroot_dir()
122            .map_or_else(|| "None".to_string(), |d| d.display().to_string())
123    );
124    info!(
125        "Config dir: {}",
126        context
127            .config_dir()
128            .map_or_else(|| "None".to_string(), |d| d.display().to_string())
129    );
130    info!("Action: {:?}", context.action());
131    info!(
132        "Thread num: {}",
133        context.thread_num().map_or_else(|| 0, |t| t)
134    );
135
136    let mut parser = parser::Parser::new(context.config_dir().unwrap().clone());
137    let r = parser.parse();
138    if r.is_err() {
139        exit(1);
140    }
141    let tasks: Vec<(PathBuf, DADKTask)> = r.unwrap();
142    // info!("Parsed tasks: {:?}", tasks);
143
144    let scheduler = Scheduler::new(
145        context.clone(),
146        context.sysroot_dir().cloned().unwrap(),
147        *context.action(),
148        tasks,
149    );
150    if scheduler.is_err() {
151        exit(1);
152    }
153
154    let r = scheduler.unwrap().run();
155    if r.is_err() {
156        exit(1);
157    }
158}