lib.rs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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. #![feature(extract_if)]
  86. #![feature(io_error_more)]
  87. #[macro_use]
  88. extern crate lazy_static;
  89. extern crate log;
  90. extern crate serde;
  91. extern crate serde_json;
  92. #[cfg(test)]
  93. extern crate test_base;
  94. use std::{path::PathBuf, process::exit, sync::Arc};
  95. use clap::Parser;
  96. use log::info;
  97. use parser::task::DADKTask;
  98. use crate::{
  99. console::CommandLineArgs, context::DadkUserExecuteContextBuilder, scheduler::Scheduler,
  100. };
  101. mod console;
  102. mod context;
  103. mod executor;
  104. pub mod parser;
  105. mod scheduler;
  106. pub mod static_resources;
  107. mod utils;
  108. pub fn dadk_user_main() {
  109. let args = CommandLineArgs::parse();
  110. info!("DADK run with args: {:?}", &args);
  111. let context = DadkUserExecuteContextBuilder::default()
  112. .sysroot_dir(args.sysroot_dir)
  113. .config_dir(args.config_dir)
  114. .action(args.action)
  115. .thread_num(args.thread)
  116. .cache_dir(args.cache_dir)
  117. .build()
  118. .expect("Failed to build execute context");
  119. let context = Arc::new(context);
  120. context.init(context.clone());
  121. // DragonOS sysroot在主机上的路径
  122. info!(
  123. "DragonOS sysroot dir: {}",
  124. context
  125. .sysroot_dir()
  126. .map_or_else(|| "None".to_string(), |d| d.display().to_string())
  127. );
  128. info!(
  129. "Config dir: {}",
  130. context
  131. .config_dir()
  132. .map_or_else(|| "None".to_string(), |d| d.display().to_string())
  133. );
  134. info!("Action: {:?}", context.action());
  135. info!(
  136. "Thread num: {}",
  137. context.thread_num().map_or_else(|| 0, |t| t)
  138. );
  139. let mut parser = parser::Parser::new(context.config_dir().unwrap().clone());
  140. let r = parser.parse();
  141. if r.is_err() {
  142. exit(1);
  143. }
  144. let tasks: Vec<(PathBuf, DADKTask)> = r.unwrap();
  145. // info!("Parsed tasks: {:?}", tasks);
  146. let scheduler = Scheduler::new(
  147. context.clone(),
  148. context.sysroot_dir().cloned().unwrap(),
  149. *context.action(),
  150. tasks,
  151. );
  152. if scheduler.is_err() {
  153. exit(1);
  154. }
  155. let r = scheduler.unwrap().run();
  156. if r.is_err() {
  157. exit(1);
  158. }
  159. }