添加了 -r -o 参数

This commit is contained in:
Cloyir 2023-04-17 16:49:49 +08:00
parent 6c6656202d
commit 9c2fd3cd21
6 changed files with 106 additions and 28 deletions

View File

@ -11,3 +11,4 @@
1. 将本程序加入到Path或者干脆在每一个c/c++项目的根目录中加入一个,反正它不大 1. 将本程序加入到Path或者干脆在每一个c/c++项目的根目录中加入一个,反正它不大
2. 使用`--help`命令行参数查看使用说明 2. 使用`--help`命令行参数查看使用说明
3. 测试版需要环境里已经有gcc、g++的环境变量 3. 测试版需要环境里已经有gcc、g++的环境变量

View File

@ -8,6 +8,8 @@ pub trait BuildConfigTrait {
fn get_project_name(&self) -> &str; fn get_project_name(&self) -> &str;
fn getpath_target_bin(&self) -> String; fn getpath_target_bin(&self) -> String;
fn getpath_target_file(&self) -> String; fn getpath_target_file(&self) -> String;
fn get_extra_final_args(&self) -> &Vec<String>;
fn need_run(&self) -> bool;
} }
#[derive(Debug)] #[derive(Debug)]
@ -15,25 +17,44 @@ pub struct BuildConfig {
compiler_path: Option<PathBuf>, compiler_path: Option<PathBuf>,
project_path: PathBuf, project_path: PathBuf,
project_name: String, project_name: String,
extra_final_args: Vec<String>,
need_run: bool,
} }
impl BuildConfig { impl BuildConfig {
pub fn new( pub fn new(
compiler_path: Option<PathBuf>, compiler_path: Option<PathBuf>,
project_path: PathBuf,
project_name: String, project_name: String,
build_options: i32,
run: bool,
) -> Self { ) -> 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"));
}
_ => {}
}
Self { Self {
compiler_path, compiler_path,
project_path, project_path,
project_name, project_name,
extra_final_args: extra,
need_run: run,
} }
} }
} }
impl BuildConfigTrait for BuildConfig { impl BuildConfigTrait for BuildConfig {
fn getpath_gcc(&self) -> String { fn getpath_gcc(&self) -> String {
return self.getpath_gpp(); // 此处需要修改 return self.getpath_gpp(); // 此处需要修改
} }
fn getpath_gpp(&self) -> String { fn getpath_gpp(&self) -> String {
@ -82,8 +103,16 @@ impl BuildConfigTrait for BuildConfig {
} }
fn getpath_target_file(&self) -> String { fn getpath_target_file(&self) -> String {
let file_name = String::from(self.get_project_name()) + ".exe"; let file_name = super::utils::make_app_file_name(self.get_project_name());
let ans = PathBuf::from(self.getpath_target_bin()).join(file_name); let ans = PathBuf::from(self.getpath_target_bin()).join(file_name);
String::from(ans.to_str().unwrap()) String::from(ans.to_str().unwrap())
} }
fn get_extra_final_args(&self) -> &Vec<String> {
return &self.extra_final_args;
}
fn need_run(&self) -> bool {
return self.need_run;
}
} }

View File

@ -41,6 +41,7 @@ pub fn make_o_files_to_bin(
command: String, command: String,
source_paths: &mut Vec<PathBuf>, source_paths: &mut Vec<PathBuf>,
target_path: String, target_path: String,
extra_args: &Vec<String>,
) -> Result<(), std::io::Error> { ) -> Result<(), std::io::Error> {
// 创建指令 // 创建指令
let mut output = std::process::Command::new(command); let mut output = std::process::Command::new(command);
@ -48,6 +49,9 @@ pub fn make_o_files_to_bin(
let item = source_paths.pop().unwrap(); let item = source_paths.pop().unwrap();
output.arg(item.to_str().unwrap()); output.arg(item.to_str().unwrap());
} }
for item in extra_args {
output.arg(item);
}
output.args(["-o", &target_path]); output.args(["-o", &target_path]);
// 运行指令 // 运行指令

View File

@ -7,43 +7,53 @@ use std::path::PathBuf;
use config::{BuildConfig, BuildConfigTrait}; use config::{BuildConfig, BuildConfigTrait};
pub fn build_project() { pub fn build_project(
build_options: i32,
run: bool,
mingw: Option<PathBuf>,
) -> Result<(), std::io::Error> {
let project_path = std::env::current_dir().unwrap(); let project_path = std::env::current_dir().unwrap();
println!("{:?}", project_path); println!("{:?}", project_path);
// 获取配置 // 获取配置
let config: Box<dyn BuildConfigTrait> = Box::new(BuildConfig::new( let config: Box<dyn BuildConfigTrait> = Box::new(BuildConfig::new(
None, mingw,
// Some(PathBuf::from(r"C:\Program Files\CodeBlocks\MinGW")), String::from("main"),
PathBuf::from(project_path), build_options,
String::from("HelloWorld"), run,
)); ));
println!("{}: start to compile 开始编译", crate::PROJECT_NAME);
// 递归所有src目录下的.c/.cpp文件并编译为.o文件输出到@/target/o目录下 // 递归所有src目录下的.c/.cpp文件并编译为.o文件输出到@/target/o目录下
let mut file_set: Vec<PathBuf> = Vec::new(); // 所有应临时存储的文件路径集合 let mut file_set: Vec<PathBuf> = Vec::new(); // 所有应临时存储的文件路径集合
println!(
"{}: start to compile 开始编译 step: 1/2",
crate::PROJECT_NAME
);
std::fs::create_dir_all(config.getpath_target_o()).unwrap(); // 先创建这层目录 std::fs::create_dir_all(config.getpath_target_o()).unwrap(); // 先创建这层目录
cmake_o::cmake_o(&config, PathBuf::from(config.getpath_src()), &mut file_set).unwrap(); cmake_o::cmake_o(&config, PathBuf::from(config.getpath_src()), &mut file_set)?;
// 遍历@/target/o联合编译到@/target/bin中 // 遍历@/target/o联合编译到@/target/bin中
println!( std::fs::create_dir_all(config.getpath_target_bin())?; // 先创建这层目录
"{}: start to compile 开始编译 step: 2/2",
crate::PROJECT_NAME
);
std::fs::create_dir_all(config.getpath_target_bin()).unwrap(); // 先创建这层目录
if PathBuf::from(config.getpath_target_file()).exists() { if PathBuf::from(config.getpath_target_file()).exists() {
std::fs::remove_file(config.getpath_target_file()).unwrap(); // 先删除目标文件 std::fs::remove_file(config.getpath_target_file())?; // 先删除目标文件
} }
gcc::make_o_files_to_bin( gcc::make_o_files_to_bin(
config.getpath_gpp(), config.getpath_gpp(),
&mut file_set, &mut file_set,
config.getpath_target_file(), config.getpath_target_file(),
) config.get_extra_final_args(),
.unwrap(); )?;
// 删除@/target/o文件夹 // 删除@/target/o文件夹
std::fs::remove_dir_all(config.getpath_target_o()).unwrap(); std::fs::remove_dir_all(config.getpath_target_o())?;
// 构建完之后是否要立即运行
if config.need_run() {
println!("{}: 开始执行...", crate::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.output()?;
println!("{}: 执行完毕...", crate::PROJECT_NAME);
}
Ok(())
} }

View File

@ -33,3 +33,11 @@ pub fn file_is_c_or_cpp(file_name: &String) -> FileType {
} }
return FileType::Else; return FileType::Else;
} }
// 生成可执行程序的文件名(仅windows上有.exe结尾)
pub fn make_app_file_name(file_name: &str) -> String {
if cfg!(target_os = "windows") {
return String::from(file_name) + ".exe";
}
return String::from(file_name);
}

View File

@ -3,25 +3,42 @@ pub mod new_project;
pub const PROJECT_NAME: &str = "rust-cmaker"; pub const PROJECT_NAME: &str = "rust-cmaker";
use clap::{command, Parser, Subcommand}; use std::path::PathBuf;
use clap::{command, Parser};
/// 命令行参数 /// 命令行参数
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
#[command(author = "Cloyir min123456@foxmail.com", version = "1.0.0", about = None, long_about = None)] #[command(author = "Cloyir mine123456@foxmail.com", version = "1.0.0", about = None, long_about = None)]
struct Args { struct Args {
#[command(subcommand)] #[command(subcommand)]
command: Commands, command: Commands,
} }
#[derive(Subcommand, Debug)] #[derive(Parser, Debug)]
enum Commands { enum Commands {
/// 在当前目录新建项目 /// 在当前目录新建项目
#[command(about = "创建一个新项目")]
New { New {
/// 项目名称 /// 项目名称
#[clap(name = "new_project_name")]
project_name: String, project_name: String,
}, },
/// 在此项目内编译 /// 在此项目内编译
Build, #[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>,
},
} }
fn main() -> std::io::Result<()> { fn main() -> std::io::Result<()> {
@ -33,8 +50,17 @@ fn main() -> std::io::Result<()> {
Commands::New { project_name } => { Commands::New { project_name } => {
new_project::new_project(project_name); new_project::new_project(project_name);
} }
Commands::Build => { Commands::Build {
build_project::build_project(); 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)?;
} }
} }