From c594cbf22ab7eff38601a2b177ab2f6fbaa8aa21 Mon Sep 17 00:00:00 2001 From: Cloyir Date: Tue, 18 Apr 2023 17:29:17 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E9=BD=90=E4=BA=86=E6=8C=87=E4=BB=A4,?= =?UTF-8?q?=20=E7=A8=8D=E5=BE=AE=E8=AE=A9main.rs=E5=A5=BD=E7=9C=8B?= =?UTF-8?q?=E4=BA=86=E4=BA=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cadd/mod.rs | 12 ++++ src/{build_project => cbuild}/cmake_o.rs | 0 src/{build_project => cbuild}/config.rs | 34 +++-------- src/{build_project => cbuild}/gcc.rs | 16 +++-- src/{build_project => cbuild}/mod.rs | 52 ++++++++++++---- src/{build_project => cbuild}/utils.rs | 0 src/cnew/mod.rs | 50 ++++++++++++++++ src/{new_project => cnew}/text.rs | 0 src/const_value.rs | 17 ++++++ src/cstore/mod.rs | 12 ++++ src/ctest/mod.rs | 12 ++++ src/main.rs | 76 +++++++++++------------- src/new_project/mod.rs | 23 ------- 13 files changed, 199 insertions(+), 105 deletions(-) create mode 100644 src/cadd/mod.rs rename src/{build_project => cbuild}/cmake_o.rs (100%) rename src/{build_project => cbuild}/config.rs (76%) rename src/{build_project => cbuild}/gcc.rs (81%) rename src/{build_project => cbuild}/mod.rs (56%) rename src/{build_project => cbuild}/utils.rs (100%) create mode 100644 src/cnew/mod.rs rename src/{new_project => cnew}/text.rs (100%) create mode 100644 src/const_value.rs create mode 100644 src/cstore/mod.rs create mode 100644 src/ctest/mod.rs delete mode 100644 src/new_project/mod.rs diff --git a/src/cadd/mod.rs b/src/cadd/mod.rs new file mode 100644 index 0000000..e8c907b --- /dev/null +++ b/src/cadd/mod.rs @@ -0,0 +1,12 @@ +use clap::Parser; + +#[derive(Parser, Debug)] +pub struct CommandsAdd { + /// 项目名称 + #[clap(name = "lib_name")] + lib_name: String, +} + +pub fn run(_config: CommandsAdd) -> Result<(), std::io::Error> { + Ok(()) +} diff --git a/src/build_project/cmake_o.rs b/src/cbuild/cmake_o.rs similarity index 100% rename from src/build_project/cmake_o.rs rename to src/cbuild/cmake_o.rs diff --git a/src/build_project/config.rs b/src/cbuild/config.rs similarity index 76% rename from src/build_project/config.rs rename to src/cbuild/config.rs index 62198f4..402e4c9 100644 --- a/src/build_project/config.rs +++ b/src/cbuild/config.rs @@ -14,7 +14,7 @@ pub trait BuildConfigTrait { #[derive(Debug)] pub struct BuildConfig { - compiler_path: Option, + compiler_path: Option, project_path: PathBuf, project_name: String, extra_final_args: Vec, @@ -23,24 +23,15 @@ pub struct BuildConfig { impl BuildConfig { pub fn new( - compiler_path: Option, + compiler_path: Option, project_name: String, - build_options: i32, + release: bool, run: bool, ) -> Self { let project_path = std::env::current_dir().unwrap(); let mut extra = Vec::new(); - match build_options { - 1 => { - extra.push(String::from("-O1")); - } - 2 => { - extra.push(String::from("-O2")); - } - 3 => { - extra.push(String::from("-O3")); - } - _ => {} + if release { + extra.push(String::from("-O3")); } Self { compiler_path, @@ -58,18 +49,11 @@ impl BuildConfigTrait for BuildConfig { } fn getpath_gpp(&self) -> String { - if self.compiler_path.is_none() { - return String::from("g++"); + let t = self.compiler_path.clone(); + match t { + Some(str) => String::from(PathBuf::from(str).join("bin").join("g++").to_str().unwrap()), + None => String::from("g++"), } - String::from( - self.compiler_path - .clone() - .unwrap() - .join("bin") - .join("g++") - .to_str() - .unwrap(), - ) } fn getpath_src(&self) -> String { diff --git a/src/build_project/gcc.rs b/src/cbuild/gcc.rs similarity index 81% rename from src/build_project/gcc.rs rename to src/cbuild/gcc.rs index aed9126..8537597 100644 --- a/src/build_project/gcc.rs +++ b/src/cbuild/gcc.rs @@ -18,17 +18,20 @@ pub fn make_file_to_target_o( // 输出调试信息 let state = if output.status.success() { - format!("{}: success to compile 编译成功", crate::PROJECT_NAME) + format!( + "{}: success to compile 编译成功", + crate::const_value::THIS_PROJECT_NAME + ) } else { format!( "{}: failed to compile 编译失败 \n错误信息: {:?}", - crate::PROJECT_NAME, + crate::const_value::THIS_PROJECT_NAME, String::from_utf8(output.stderr).unwrap() ) }; println!( "{}: file : {:?} ---> new file : {:?} ---> {}", - crate::PROJECT_NAME, + crate::const_value::THIS_PROJECT_NAME, Path::new(source_file_path).file_name().unwrap(), Path::new(new_file_path).file_name().unwrap(), state @@ -57,11 +60,14 @@ pub fn make_o_files_to_bin( // 运行指令 let output = output.output()?; if output.status.success() { - println!("{}: success to compile 编译成功", crate::PROJECT_NAME); + println!( + "{}: success to compile 编译成功", + crate::const_value::THIS_PROJECT_NAME + ); } else { println!( "{}: failed to compile 编译失败\n{:?}", - crate::PROJECT_NAME, + crate::const_value::THIS_PROJECT_NAME, output ); } diff --git a/src/build_project/mod.rs b/src/cbuild/mod.rs similarity index 56% rename from src/build_project/mod.rs rename to src/cbuild/mod.rs index 7d4970d..b45271e 100644 --- a/src/build_project/mod.rs +++ b/src/cbuild/mod.rs @@ -7,23 +7,52 @@ use std::path::PathBuf; use config::{BuildConfig, BuildConfigTrait}; -pub fn build_project( - build_options: i32, +#[derive(clap::Parser, Debug)] +pub struct CommandsBuild { + /// 静默执行 + #[clap(short, long, default_value = "false")] + quiet: bool, + + /// 对构建优化(默认只有o3优化) + #[clap(long, default_value = "false")] + release: bool, + + /// 编译后是否立即运行 + #[clap(short, long, default_value = "false")] run: bool, - mingw: Option, -) -> Result<(), std::io::Error> { + + /// MinGW编译器地址, 不填默认已配置为环境变量 + #[clap(short, long, default_value = None)] + mingw: Option, +} + +impl CommandsBuild { + pub fn new_run() -> CommandsBuild { + CommandsBuild { + quiet: true, + release: false, + run: true, + mingw: None, + } + } +} + +pub fn run(config: CommandsBuild) -> Result<(), std::io::Error> { let project_path = std::env::current_dir().unwrap(); println!("{:?}", project_path); // 获取配置 let config: Box = Box::new(BuildConfig::new( - mingw, + config.mingw, String::from("main"), - build_options, - run, + config.release, + config.run, )); - println!("{}: start to compile 开始编译", crate::PROJECT_NAME); + println!( + "{}: start to compile 开始编译", + crate::const_value::THIS_PROJECT_NAME + ); // 递归所有src目录下的.c/.cpp文件并编译为.o文件输出到@/target/o目录下 let mut file_set: Vec = Vec::new(); // 所有应临时存储的文件路径集合 @@ -45,14 +74,15 @@ pub fn build_project( // 删除@/target/o文件夹 std::fs::remove_dir_all(config.getpath_target_o())?; - // 构建完之后是否要立即运行 + // 构建完之后判断是否要立即运行 if config.need_run() { - println!("{}: 开始执行...", crate::PROJECT_NAME); + println!("{}: 开始执行...", crate::const_value::THIS_PROJECT_NAME); let mut command = std::process::Command::new(config.getpath_target_file()); command.stdin(std::process::Stdio::inherit()); command.stdout(std::process::Stdio::inherit()); + command.stderr(std::process::Stdio::inherit()); command.output()?; - println!("{}: 执行完毕...", crate::PROJECT_NAME); + println!("\n{}: 执行完毕...", crate::const_value::THIS_PROJECT_NAME); } Ok(()) diff --git a/src/build_project/utils.rs b/src/cbuild/utils.rs similarity index 100% rename from src/build_project/utils.rs rename to src/cbuild/utils.rs diff --git a/src/cnew/mod.rs b/src/cnew/mod.rs new file mode 100644 index 0000000..2adf771 --- /dev/null +++ b/src/cnew/mod.rs @@ -0,0 +1,50 @@ +use clap::Parser; + +mod text; + +#[derive(Parser, Debug)] +pub struct CommandsNew { + /// 项目名称 + #[clap(name = "new_project_name")] + project_name: String, + + /// 静默执行 + #[clap(short, long, default_value = "false")] + quiet: bool, + + /// 从自定义模板构建 + #[clap(short, long, name = "module_name", default_value = "defult")] + module: String, +} + +/// 创建新项目 +pub fn run(config: CommandsNew) -> Result<(), std::io::Error> { + let target_path = std::env::current_dir().unwrap().join(&config.project_name); + + if !config.quiet { + println!("新建项目: {}", config.project_name); + println!("目标路径: {:?}", target_path); + } + + if let Ok(_) = target_path.read_dir() { + if !config.quiet { + println!("创建项目失败, 已存在名为{}的文件夹", config.project_name); + } + return Ok(()); + } + let src_path = target_path.join("src"); + std::fs::create_dir_all(&src_path).unwrap(); + + // 新建README.md文件 + std::fs::write(target_path.join("README.md"), text::get_readme_text())?; + + // 新建main.cpp文件 + std::fs::write(src_path.join("main.cpp"), text::get_maincpp_text())?; + + if !config.quiet { + println!("创建成功"); + println!("请进入{}文件夹再使用build指令构建项目", config.project_name); + } + + Ok(()) +} diff --git a/src/new_project/text.rs b/src/cnew/text.rs similarity index 100% rename from src/new_project/text.rs rename to src/cnew/text.rs diff --git a/src/const_value.rs b/src/const_value.rs new file mode 100644 index 0000000..678e2dd --- /dev/null +++ b/src/const_value.rs @@ -0,0 +1,17 @@ +// 定义一些全局常数变量 + +/// 本项目的名称 +pub const THIS_PROJECT_NAME: &str = "rust-cmaker"; + +/// 作者信息 +pub const AUTHOR: &str = "Cloyir mine123456@foxmail.com"; + +/// 项目版本 +pub const VERSION: &str = "v0.0.1-alpha"; + +/// -h 指令写在标头的内容 +pub const ABOUT: &str = "rcm——一个类cargo的c/c++项目构建管理工具"; + +/// --help 指令写在标头的内容 +pub const LONG_ABOUT: &str = + "rust-cmaker——一个类cargo的c/c++项目构建管理工具\n什么年代了还在用传统cmake?"; diff --git a/src/cstore/mod.rs b/src/cstore/mod.rs new file mode 100644 index 0000000..df704da --- /dev/null +++ b/src/cstore/mod.rs @@ -0,0 +1,12 @@ +use clap::Parser; + +#[derive(Parser, Debug)] +pub struct CommandsStore { + /// 指定静态库名称 + #[clap(short, long)] + name: Option, +} + +pub fn run(_config: CommandsStore) -> Result<(), std::io::Error> { + Ok(()) +} diff --git a/src/ctest/mod.rs b/src/ctest/mod.rs new file mode 100644 index 0000000..5ecd984 --- /dev/null +++ b/src/ctest/mod.rs @@ -0,0 +1,12 @@ +use clap::Parser; + +#[derive(Parser, Debug)] +pub struct CommandsTest { + /// 每完成一个测试暂停一次 + #[clap(short, long, default_value = "false")] + pause: bool, +} + +pub fn run(_config: CommandsTest) -> Result<(), std::io::Error> { + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index a5095e4..a7492e0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,17 @@ -pub mod build_project; -pub mod new_project; +pub mod const_value; -pub const PROJECT_NAME: &str = "rust-cmaker"; - -use std::path::PathBuf; +mod cadd; +mod cbuild; +mod cnew; +mod cstore; +mod ctest; use clap::{command, Parser}; +use const_value::{ABOUT, AUTHOR, LONG_ABOUT, VERSION}; /// 命令行参数 #[derive(Parser, Debug)] -#[command(author = "Cloyir mine123456@foxmail.com", version = "1.0.0", about = None, long_about = None)] +#[command(author = AUTHOR, version = VERSION, about = ABOUT, long_about = LONG_ABOUT)] struct Args { #[command(subcommand)] command: Commands, @@ -18,49 +20,41 @@ struct Args { #[derive(Parser, Debug)] enum Commands { /// 在当前目录新建项目 - #[command(about = "创建一个新项目")] - New { - /// 项目名称 - #[clap(name = "new_project_name")] - project_name: String, - }, - /// 在此项目内编译 - #[command(about = "构建当前文件夹下的项目")] - Build { - /// -O优化选项 - #[clap(short = 'o', long = "option", name = "0~3", default_value = "0")] - build_options: i32, - - /// 编译后是否立即运行 - #[clap(short, long, default_value = "false")] - run: bool, - - /// MinGW编译器地址, 不填默认已配置为环境变量 - #[clap(short, long, default_value = None)] - mingw: Option, - }, + New(cnew::CommandsNew), + /// 构建当前打开的项目 + Build(cbuild::CommandsBuild), + /// `rcm build -q -r` 的简写 + Run, + /// 生成静态库并存储到静态仓库 + Store(cstore::CommandsStore), + /// 在当前项目下添加静态库依赖 + Add(cadd::CommandsAdd), + /// 运行单元测试 + Test(ctest::CommandsTest), } fn main() -> std::io::Result<()> { // 解析命令行参数 let args = Args::parse(); - // println!("args: {:?}", args); match args.command { - Commands::New { project_name } => { - new_project::new_project(project_name); + Commands::New(config) => { + cnew::run(config)?; } - Commands::Build { - build_options, - run, - mingw, - } => { - let mingw = if let Some(t) = mingw { - Some(PathBuf::from(t)) - } else { - None - }; - build_project::build_project(build_options, run, mingw)?; + Commands::Build(config) => { + cbuild::run(config)?; + } + Commands::Run => { + cbuild::run(cbuild::CommandsBuild::new_run())?; + } + Commands::Store(config) => { + cstore::run(config)?; + } + Commands::Add(config) => { + cadd::run(config)?; + } + Commands::Test(config) => { + ctest::run(config)?; } } diff --git a/src/new_project/mod.rs b/src/new_project/mod.rs deleted file mode 100644 index fb31232..0000000 --- a/src/new_project/mod.rs +++ /dev/null @@ -1,23 +0,0 @@ -mod text; - -/// 创建新项目 -pub fn new_project(project_name: String) { - println!("新建项目: {}", project_name); - let target_path = std::env::current_dir().unwrap().join(&project_name); - println!("目标路径: {:?}", target_path); - if let Ok(_) = target_path.read_dir() { - println!("创建项目失败, 已存在名为{}的文件夹", project_name); - return; - } - let src_path = target_path.join("src"); - std::fs::create_dir_all(&src_path).unwrap(); - - // 新建README.md文件 - std::fs::write(target_path.join("README.md"), text::get_readme_text()).unwrap(); - - // 新建main.cpp文件 - std::fs::write(src_path.join("main.cpp"), text::get_maincpp_text()).unwrap(); - - println!("创建成功"); - println!("请进入{}文件夹再使用build指令构建项目", project_name); -}