添加了 -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++项目的根目录中加入一个,反正它不大
2. 使用`--help`命令行参数查看使用说明
3. 测试版需要环境里已经有gcc、g++的环境变量

View File

@ -8,6 +8,8 @@ pub trait BuildConfigTrait {
fn get_project_name(&self) -> &str;
fn getpath_target_bin(&self) -> String;
fn getpath_target_file(&self) -> String;
fn get_extra_final_args(&self) -> &Vec<String>;
fn need_run(&self) -> bool;
}
#[derive(Debug)]
@ -15,25 +17,44 @@ pub struct BuildConfig {
compiler_path: Option<PathBuf>,
project_path: PathBuf,
project_name: String,
extra_final_args: Vec<String>,
need_run: bool,
}
impl BuildConfig {
pub fn new(
compiler_path: Option<PathBuf>,
project_path: PathBuf,
project_name: String,
build_options: i32,
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"));
}
_ => {}
}
Self {
compiler_path,
project_path,
project_name,
extra_final_args: extra,
need_run: run,
}
}
}
impl BuildConfigTrait for BuildConfig {
fn getpath_gcc(&self) -> String {
return self.getpath_gpp(); // 此处需要修改
return self.getpath_gpp(); // 此处需要修改
}
fn getpath_gpp(&self) -> String {
@ -82,8 +103,16 @@ impl BuildConfigTrait for BuildConfig {
}
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);
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,
source_paths: &mut Vec<PathBuf>,
target_path: String,
extra_args: &Vec<String>,
) -> Result<(), std::io::Error> {
// 创建指令
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();
output.arg(item.to_str().unwrap());
}
for item in extra_args {
output.arg(item);
}
output.args(["-o", &target_path]);
// 运行指令

View File

@ -7,43 +7,53 @@ use std::path::PathBuf;
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();
println!("{:?}", project_path);
// 获取配置
let config: Box<dyn BuildConfigTrait> = Box::new(BuildConfig::new(
None,
// Some(PathBuf::from(r"C:\Program Files\CodeBlocks\MinGW")),
PathBuf::from(project_path),
String::from("HelloWorld"),
mingw,
String::from("main"),
build_options,
run,
));
println!("{}: start to compile 开始编译", crate::PROJECT_NAME);
// 递归所有src目录下的.c/.cpp文件并编译为.o文件输出到@/target/o目录下
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(); // 先创建这层目录
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中
println!(
"{}: start to compile 开始编译 step: 2/2",
crate::PROJECT_NAME
);
std::fs::create_dir_all(config.getpath_target_bin()).unwrap(); // 先创建这层目录
std::fs::create_dir_all(config.getpath_target_bin())?; // 先创建这层目录
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(
config.getpath_gpp(),
&mut file_set,
config.getpath_target_file(),
)
.unwrap();
config.get_extra_final_args(),
)?;
// 删除@/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;
}
// 生成可执行程序的文件名(仅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";
use clap::{command, Parser, Subcommand};
use std::path::PathBuf;
use clap::{command, Parser};
/// 命令行参数
#[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 {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand, Debug)]
#[derive(Parser, Debug)]
enum Commands {
/// 在当前目录新建项目
#[command(about = "创建一个新项目")]
New {
/// 项目名称
#[clap(name = "new_project_name")]
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<()> {
@ -33,8 +50,17 @@ fn main() -> std::io::Result<()> {
Commands::New { project_name } => {
new_project::new_project(project_name);
}
Commands::Build => {
build_project::build_project();
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)?;
}
}