补齐了指令, 稍微让main.rs好看了些

This commit is contained in:
Cloyir 2023-04-18 17:29:17 +08:00
parent d76da588cd
commit c594cbf22a
13 changed files with 199 additions and 105 deletions

12
src/cadd/mod.rs Normal file
View File

@ -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(())
}

View File

@ -14,7 +14,7 @@ pub trait BuildConfigTrait {
#[derive(Debug)]
pub struct BuildConfig {
compiler_path: Option<PathBuf>,
compiler_path: Option<String>,
project_path: PathBuf,
project_name: String,
extra_final_args: Vec<String>,
@ -23,24 +23,15 @@ pub struct BuildConfig {
impl BuildConfig {
pub fn new(
compiler_path: Option<PathBuf>,
compiler_path: Option<String>,
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 {

View File

@ -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
);
}

View File

@ -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<PathBuf>,
) -> Result<(), std::io::Error> {
/// MinGW编译器地址, 不填默认已配置为环境变量
#[clap(short, long, default_value = None)]
mingw: Option<String>,
}
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<dyn BuildConfigTrait> = 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<PathBuf> = 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(())

50
src/cnew/mod.rs Normal file
View File

@ -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(())
}

17
src/const_value.rs Normal file
View File

@ -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?";

12
src/cstore/mod.rs Normal file
View File

@ -0,0 +1,12 @@
use clap::Parser;
#[derive(Parser, Debug)]
pub struct CommandsStore {
/// 指定静态库名称
#[clap(short, long)]
name: Option<String>,
}
pub fn run(_config: CommandsStore) -> Result<(), std::io::Error> {
Ok(())
}

12
src/ctest/mod.rs Normal file
View File

@ -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(())
}

View File

@ -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<String>,
},
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)?;
}
}

View File

@ -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);
}