修改了屎山代码的同时可以链接静态链接库了
This commit is contained in:
parent
2df87f19c1
commit
e21382ae29
@ -15,6 +15,20 @@ impl File {
|
|||||||
extension,
|
extension,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_by_path(path: PathBuf) -> Self {
|
||||||
|
let name = path.file_name().unwrap().to_string_lossy().into_owned(); // 带扩展名的文件
|
||||||
|
let extension = std::path::Path::new(&path).extension().unwrap();
|
||||||
|
let extension = extension.to_string_lossy().into_owned();
|
||||||
|
let name = String::from(
|
||||||
|
std::path::Path::new(&name)
|
||||||
|
.file_stem()
|
||||||
|
.unwrap()
|
||||||
|
.to_str()
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
Self::new(path, name, extension)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -29,49 +43,12 @@ pub struct FilesSet {
|
|||||||
|
|
||||||
impl FilesSet {
|
impl FilesSet {
|
||||||
/// 输入root/src的路径, 整理该路径下的所有文件
|
/// 输入root/src的路径, 整理该路径下的所有文件
|
||||||
pub fn read(path: PathBuf) -> Self {
|
pub fn read_src(path: PathBuf) -> Self {
|
||||||
let mut entry_files = Vec::new();
|
let mut entry_files = Vec::new();
|
||||||
let mut c_files = Vec::new();
|
let mut c_files = Vec::new();
|
||||||
let mut h_files = Vec::new();
|
let mut h_files = Vec::new();
|
||||||
|
|
||||||
/// 将路径文件夹内所有文件信息整理到集合中
|
// 将src文件夹单独处理, 逻辑和fileset_read_dir差不多
|
||||||
fn read_dir(
|
|
||||||
path: &PathBuf,
|
|
||||||
c_files: &mut Vec<File>,
|
|
||||||
h_files: &mut Vec<File>,
|
|
||||||
) -> std::io::Result<()> {
|
|
||||||
for file in std::fs::read_dir(path)? {
|
|
||||||
let file = file?;
|
|
||||||
if file.file_type()?.is_dir() {
|
|
||||||
let name = file.file_name().to_string_lossy().into_owned();
|
|
||||||
// 忽略test文件夹
|
|
||||||
if name == "test" {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let new_path = path.join(name);
|
|
||||||
read_dir(&new_path, c_files, h_files)?;
|
|
||||||
} else {
|
|
||||||
if let Some(name) = file.path().file_name() {
|
|
||||||
let file_name: String = name.to_string_lossy().into_owned();
|
|
||||||
let extension = std::path::Path::new(&file_name).extension().unwrap();
|
|
||||||
let file_name: String = file
|
|
||||||
.path()
|
|
||||||
.file_stem()
|
|
||||||
.unwrap()
|
|
||||||
.to_string_lossy()
|
|
||||||
.into_owned();
|
|
||||||
let extension: String = extension.to_string_lossy().into_owned();
|
|
||||||
if extension == "c" || extension == "cpp" {
|
|
||||||
c_files.push(File::new(file.path(), file_name, extension));
|
|
||||||
} else if extension == "h" || extension == "hpp" {
|
|
||||||
h_files.push(File::new(file.path(), file_name, extension));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
for file in std::fs::read_dir(&path).unwrap() {
|
for file in std::fs::read_dir(&path).unwrap() {
|
||||||
let file = file.unwrap();
|
let file = file.unwrap();
|
||||||
if file.file_type().unwrap().is_dir() {
|
if file.file_type().unwrap().is_dir() {
|
||||||
@ -84,38 +61,33 @@ impl FilesSet {
|
|||||||
// 将src下其它文件夹视作正常.c/.cpp文件
|
// 将src下其它文件夹视作正常.c/.cpp文件
|
||||||
if name == "bin" {
|
if name == "bin" {
|
||||||
let new_path = path.join("bin");
|
let new_path = path.join("bin");
|
||||||
read_dir(&new_path, &mut entry_files, &mut h_files).unwrap();
|
fileset_read_dir(&new_path, &mut entry_files, &mut h_files).unwrap();
|
||||||
} else {
|
} else {
|
||||||
let new_path = path.join(name);
|
let new_path = path.join(name);
|
||||||
read_dir(&new_path, &mut c_files, &mut h_files).unwrap();
|
fileset_read_dir(&new_path, &mut c_files, &mut h_files).unwrap();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 如果是文件
|
// 如果是文件
|
||||||
if let Some(name) = file.path().file_name() {
|
let file = File::new_by_path(file.path());
|
||||||
let file_name = name.to_string_lossy().into_owned();
|
if file.extension == "c" || file.extension == "cpp" {
|
||||||
let file_path = file.path();
|
if file.name == "main" {
|
||||||
let extension = std::path::Path::new(&file_name).extension().unwrap();
|
entry_files.push(file);
|
||||||
let file_name: String = file
|
} else {
|
||||||
.path()
|
c_files.push(file);
|
||||||
.file_stem()
|
|
||||||
.unwrap()
|
|
||||||
.to_string_lossy()
|
|
||||||
.into_owned();
|
|
||||||
let extension: String = extension.to_string_lossy().into_owned();
|
|
||||||
let file = File::new(file_path, file_name, extension);
|
|
||||||
if file.extension == "c" || file.extension == "cpp" {
|
|
||||||
if file.name == "main" {
|
|
||||||
entry_files.push(file);
|
|
||||||
} else {
|
|
||||||
c_files.push(file);
|
|
||||||
}
|
|
||||||
} else if file.extension == "h" || file.extension == "hpp" {
|
|
||||||
h_files.push(file);
|
|
||||||
}
|
}
|
||||||
|
} else if file.extension == "h" || file.extension == "hpp" {
|
||||||
|
h_files.push(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果src目录下仅有一个.c/.cpp文件, 则视为唯一项目入口
|
||||||
|
if entry_files.len() == 0 && c_files.len() == 1 {
|
||||||
|
let t = entry_files;
|
||||||
|
entry_files = c_files;
|
||||||
|
c_files = t;
|
||||||
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
entry_files,
|
entry_files,
|
||||||
c_files,
|
c_files,
|
||||||
@ -123,3 +95,31 @@ impl FilesSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 将路径文件夹内所有文件分组整理到集合中
|
||||||
|
fn fileset_read_dir(
|
||||||
|
path: &PathBuf,
|
||||||
|
c_files: &mut Vec<File>,
|
||||||
|
h_files: &mut Vec<File>,
|
||||||
|
) -> std::io::Result<()> {
|
||||||
|
for file in std::fs::read_dir(path)? {
|
||||||
|
let file = file?;
|
||||||
|
if file.file_type()?.is_dir() {
|
||||||
|
let name = file.file_name().to_string_lossy().into_owned();
|
||||||
|
// 忽略test文件夹
|
||||||
|
if name == "test" {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let new_path = path.join(name);
|
||||||
|
fileset_read_dir(&new_path, c_files, h_files)?;
|
||||||
|
} else {
|
||||||
|
let file = File::new_by_path(file.path());
|
||||||
|
if file.extension == "c" || file.extension == "cpp" {
|
||||||
|
c_files.push(file);
|
||||||
|
} else if file.extension == "h" || file.extension == "hpp" {
|
||||||
|
h_files.push(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
mod command;
|
mod command;
|
||||||
mod files;
|
mod files;
|
||||||
|
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::const_value::console_log;
|
use crate::const_value::console_log;
|
||||||
|
|
||||||
use self::files::FilesSet;
|
use self::files::FilesSet;
|
||||||
@ -11,10 +13,6 @@ pub struct CommandsBuild {
|
|||||||
#[clap(short, long, default_value = "false")]
|
#[clap(short, long, default_value = "false")]
|
||||||
quiet: bool,
|
quiet: bool,
|
||||||
|
|
||||||
/// 对构建优化(默认只有o3优化)
|
|
||||||
#[clap(long, default_value = "false")]
|
|
||||||
release: bool,
|
|
||||||
|
|
||||||
/// 编译后是否立即运行
|
/// 编译后是否立即运行
|
||||||
#[clap(short, long, default_value = "false")]
|
#[clap(short, long, default_value = "false")]
|
||||||
run: bool,
|
run: bool,
|
||||||
@ -26,13 +24,17 @@ pub struct CommandsBuild {
|
|||||||
/// 采用gcc编译指令而不是g++
|
/// 采用gcc编译指令而不是g++
|
||||||
#[clap(short, default_value = "false")]
|
#[clap(short, default_value = "false")]
|
||||||
c: bool,
|
c: bool,
|
||||||
|
|
||||||
|
/// 其它自定义选项, 需要在语句前加'.', 举例: --other ".-O3 .-mwindows"
|
||||||
|
#[clap(long)]
|
||||||
|
other: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(config: CommandsBuild) -> Result<(), std::io::Error> {
|
pub fn run(config: CommandsBuild) -> Result<(), std::io::Error> {
|
||||||
// 获取项目路径
|
// 获取项目路径
|
||||||
let project_path = std::env::current_dir().unwrap();
|
let project_path = std::env::current_dir().unwrap();
|
||||||
|
|
||||||
// 获取指定的路径
|
// 获取生成文件的目标路径
|
||||||
// let bin_path = project_path.join("target").join("bin");
|
// let bin_path = project_path.join("target").join("bin");
|
||||||
let bin_path = project_path.join("target");
|
let bin_path = project_path.join("target");
|
||||||
std::fs::create_dir_all(&bin_path).unwrap(); // 确保bin目录存在
|
std::fs::create_dir_all(&bin_path).unwrap(); // 确保bin目录存在
|
||||||
@ -43,25 +45,20 @@ pub fn run(config: CommandsBuild) -> Result<(), std::io::Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 将src目录下的文件整理归纳
|
// 将src目录下的文件整理归纳
|
||||||
let files: FilesSet = {
|
let files: FilesSet = FilesSet::read_src(project_path.join("src"));
|
||||||
let mut files = FilesSet::read(project_path.join("src"));
|
|
||||||
// 如果src目录下仅有一个.c/.cpp文件, 则视为唯一项目入口
|
|
||||||
if files.entry_files.len() == 0 && files.c_files.len() == 1 {
|
|
||||||
let t = files.entry_files;
|
|
||||||
files.entry_files = files.c_files;
|
|
||||||
files.c_files = t;
|
|
||||||
}
|
|
||||||
files
|
|
||||||
};
|
|
||||||
|
|
||||||
// build指令需要读取rust-cmaker下的config文件
|
// build指令需要读取rust-cmaker下的config文件
|
||||||
let r_config = crate::rtools::config::RConfig::read();
|
let r_config = crate::rtools::config::RConfig::read();
|
||||||
let mut need_run = None;
|
let mut need_run = None;
|
||||||
|
|
||||||
|
// 命令通用部分
|
||||||
|
let current_args: Vec<String> = make_current_args(&config, &files, project_path.join("lib"));
|
||||||
|
|
||||||
// 将每一个entry_file构建到指定目录下
|
// 将每一个entry_file构建到指定目录下
|
||||||
for entry_file in &files.entry_files {
|
for entry_file in &files.entry_files {
|
||||||
let mut gcc_cmd = command::get_gcc_command(&config, &r_config);
|
let mut gcc_cmd = command::get_gcc_command(&config, &r_config);
|
||||||
|
|
||||||
|
// 指定生成文件名称
|
||||||
gcc_cmd.arg("-o").arg({
|
gcc_cmd.arg("-o").arg({
|
||||||
let mut target_name = entry_file.name.clone();
|
let mut target_name = entry_file.name.clone();
|
||||||
if cfg!(target_os = "windows") {
|
if cfg!(target_os = "windows") {
|
||||||
@ -71,27 +68,35 @@ pub fn run(config: CommandsBuild) -> Result<(), std::io::Error> {
|
|||||||
target_path
|
target_path
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 添加入口文件
|
||||||
gcc_cmd.arg(&entry_file.path);
|
gcc_cmd.arg(&entry_file.path);
|
||||||
|
|
||||||
for c_file in &files.c_files {
|
// 组装通用命令
|
||||||
gcc_cmd.arg(&c_file.path);
|
for item in ¤t_args {
|
||||||
}
|
gcc_cmd.arg(item);
|
||||||
|
|
||||||
if !config.run {
|
|
||||||
console_log(&format!("{:?}", gcc_cmd));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 执行命令
|
||||||
let output = gcc_cmd.output();
|
let output = gcc_cmd.output();
|
||||||
|
|
||||||
match output {
|
match output {
|
||||||
Ok(output) => {
|
Ok(output) => {
|
||||||
if !config.run {
|
if !output.status.success() {
|
||||||
console_log(&format!("编译成功: {:?}", output));
|
if !config.quiet {
|
||||||
|
let msg = String::from_utf8_lossy(&output.stderr);
|
||||||
|
console_log(&format!("编译失败: {}", msg));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
} else if !config.quiet {
|
||||||
|
console_log(&format!(
|
||||||
|
"编译成功: {}.{}",
|
||||||
|
entry_file.name, entry_file.extension
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if !config.run {
|
if !config.quiet {
|
||||||
console_log(&format!("执行出错: {}", err));
|
console_log(&format!("编译失败: {:?}", err));
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -103,6 +108,7 @@ pub fn run(config: CommandsBuild) -> Result<(), std::io::Error> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果满足条件, 运行需要立即执行的程序
|
||||||
if let Some(run_file) = need_run {
|
if let Some(run_file) = need_run {
|
||||||
if !config.quiet {
|
if !config.quiet {
|
||||||
console_log(&format!("{}开始执行: ", run_file.name));
|
console_log(&format!("{}开始执行: ", run_file.name));
|
||||||
@ -120,3 +126,49 @@ pub fn run(config: CommandsBuild) -> Result<(), std::io::Error> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn make_current_args(config: &CommandsBuild, files: &FilesSet, lib_path: PathBuf) -> Vec<String> {
|
||||||
|
let mut current_args: Vec<String> = Vec::new();
|
||||||
|
|
||||||
|
// 添加所有非入口文件
|
||||||
|
for c_file in &files.c_files {
|
||||||
|
let arg = String::from(&c_file.path.clone().into_os_string().into_string().unwrap());
|
||||||
|
current_args.push(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从project/lib文件夹里获取所有的.a文件作为静态链接库
|
||||||
|
if let Ok(entries) = std::fs::read_dir(&lib_path) {
|
||||||
|
let mut a_files = Vec::new();
|
||||||
|
|
||||||
|
for entry in entries {
|
||||||
|
if let Ok(entry) = &entry {
|
||||||
|
let file_path = entry.path();
|
||||||
|
if file_path.is_file() {
|
||||||
|
let file = files::File::new_by_path(file_path);
|
||||||
|
if file.extension == "a" && file.name.starts_with("lib") {
|
||||||
|
a_files.push(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if a_files.len() != 0 {
|
||||||
|
current_args.push(String::from("-L"));
|
||||||
|
current_args.push(lib_path.into_os_string().into_string().to_owned().unwrap());
|
||||||
|
for item in a_files {
|
||||||
|
let ans = item.name.replacen("lib", "-l", 1);
|
||||||
|
current_args.push(ans);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 组装config.other
|
||||||
|
if let Some(other) = &config.other {
|
||||||
|
for option in other.split_whitespace() {
|
||||||
|
let op: String = option.chars().skip(1).collect(); // 去除前置'.'
|
||||||
|
current_args.push(op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
current_args
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user