添加了 -r -o 参数
This commit is contained in:
parent
6c6656202d
commit
9c2fd3cd21
@ -11,3 +11,4 @@
|
||||
1. 将本程序加入到Path或者干脆在每一个c/c++项目的根目录中加入一个,反正它不大
|
||||
2. 使用`--help`命令行参数查看使用说明
|
||||
3. 测试版需要环境里已经有gcc、g++的环境变量
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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]);
|
||||
|
||||
// 运行指令
|
||||
|
||||
@ -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(())
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
38
src/main.rs
38
src/main.rs
@ -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)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user