Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3575497448 |
131
src/main.rs
131
src/main.rs
@@ -1,4 +1,4 @@
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use anyhow::{Context, Result, anyhow};
|
||||
use clap::{Parser, ValueEnum};
|
||||
use inquire::{Confirm, Select, Text};
|
||||
use regex::Regex;
|
||||
@@ -85,7 +85,11 @@ fn generate_cmakelists(
|
||||
) -> String {
|
||||
let mut lines = vec![
|
||||
"cmake_minimum_required(VERSION 3.20)".to_string(),
|
||||
format!("project({} LANGUAGES {})", project_name, get_lang_cmake(lang)),
|
||||
format!(
|
||||
"project({} LANGUAGES {})",
|
||||
project_name,
|
||||
get_lang_cmake(lang)
|
||||
),
|
||||
"".to_string(),
|
||||
];
|
||||
|
||||
@@ -110,24 +114,27 @@ fn generate_cmakelists(
|
||||
let ext = get_lang_ext(lang);
|
||||
match project_type {
|
||||
ProjectType::Exe => {
|
||||
lines.push(format!(
|
||||
"add_executable({} src/main.{})",
|
||||
project_name, ext,
|
||||
));
|
||||
lines.push(format!("add_executable({} src/main.{})", project_name, ext,));
|
||||
}
|
||||
ProjectType::StaticLib => {
|
||||
lines.push(format!(
|
||||
"add_library({} STATIC src/main.{})",
|
||||
project_name, ext,
|
||||
));
|
||||
lines.push(format!("target_include_directories({} PUBLIC include)", project_name));
|
||||
lines.push(format!(
|
||||
"target_include_directories({} PUBLIC include)",
|
||||
project_name
|
||||
));
|
||||
}
|
||||
ProjectType::SharedLib => {
|
||||
lines.push(format!(
|
||||
"add_library({} SHARED src/main.{})",
|
||||
project_name, ext,
|
||||
));
|
||||
lines.push(format!("target_include_directories({} PUBLIC include)", project_name));
|
||||
lines.push(format!(
|
||||
"target_include_directories({} PUBLIC include)",
|
||||
project_name
|
||||
));
|
||||
lines.push(format!(
|
||||
"target_compile_definitions({} PUBLIC {}_EXPORTS)",
|
||||
project_name,
|
||||
@@ -137,31 +144,77 @@ fn generate_cmakelists(
|
||||
}
|
||||
|
||||
// 添加导出设置(仅库类型)
|
||||
if matches!(project_type, ProjectType::StaticLib | ProjectType::SharedLib) {
|
||||
if matches!(
|
||||
project_type,
|
||||
ProjectType::StaticLib | ProjectType::SharedLib
|
||||
) {
|
||||
lines.push("".to_string());
|
||||
lines.push("# Export targets".to_string());
|
||||
lines.push("include(GNUInstallDirs)".to_string());
|
||||
lines.push(format!(
|
||||
"install(TARGETS {} DESTINATION lib)",
|
||||
project_name
|
||||
));
|
||||
lines.push(
|
||||
"install(DIRECTORY include/ DESTINATION include)".to_string(),
|
||||
);
|
||||
lines.push(format!("install(TARGETS {} DESTINATION lib)", project_name));
|
||||
lines.push("install(DIRECTORY include/ DESTINATION include)".to_string());
|
||||
}
|
||||
|
||||
lines.join("\n")
|
||||
}
|
||||
|
||||
fn generate_source_file(lang: &Lang) -> String {
|
||||
match lang {
|
||||
Lang::C => {
|
||||
"#include <stdio.h>\n\nint main() {\n printf(\"Hello, World!\\n\");\n return 0;\n}"
|
||||
.to_string()
|
||||
fn generate_source_file(lang: &Lang, project_type: &ProjectType) -> String {
|
||||
match project_type {
|
||||
ProjectType::SharedLib => {
|
||||
match lang {
|
||||
Lang::C => {
|
||||
r#"#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
// Non-Windows platforms
|
||||
void __attribute__((constructor)) lib_init(void) {}
|
||||
void __attribute__((destructor)) lib_fini(void) {}
|
||||
#endif"#
|
||||
.to_string()
|
||||
}
|
||||
Lang::Cpp => {
|
||||
r#"#include <windows.h>
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}"#
|
||||
.to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
Lang::Cpp => {
|
||||
"#include <iostream>\n\nint main() {\n std::cout << \"Hello, World!\" << std::endl;\n return 0;\n}"
|
||||
.to_string()
|
||||
_ => {
|
||||
match lang {
|
||||
Lang::C => {
|
||||
"#include <stdio.h>\n\nint main() {\n printf(\"Hello, World!\\n\");\n return 0;\n}"
|
||||
.to_string()
|
||||
}
|
||||
Lang::Cpp => {
|
||||
"#include <iostream>\n\nint main() {\n std::cout << \"Hello, World!\" << std::endl;\n return 0;\n}"
|
||||
.to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -257,7 +310,10 @@ fn create_project(
|
||||
|
||||
// 创建目录结构
|
||||
fs::create_dir_all(output_dir.join("src"))?;
|
||||
if matches!(project_type, ProjectType::StaticLib | ProjectType::SharedLib) {
|
||||
if matches!(
|
||||
project_type,
|
||||
ProjectType::StaticLib | ProjectType::SharedLib
|
||||
) {
|
||||
fs::create_dir_all(output_dir.join("include"))?;
|
||||
}
|
||||
|
||||
@@ -272,12 +328,15 @@ fn create_project(
|
||||
let ext = get_lang_ext(lang);
|
||||
fs::write(
|
||||
output_dir.join("src").join(format!("main.{}", ext)),
|
||||
generate_source_file(lang),
|
||||
generate_source_file(lang, project_type),
|
||||
)
|
||||
.with_context(|| "写入源文件失败")?;
|
||||
|
||||
// 为库类型创建 README.md
|
||||
if matches!(project_type, ProjectType::StaticLib | ProjectType::SharedLib) {
|
||||
if matches!(
|
||||
project_type,
|
||||
ProjectType::StaticLib | ProjectType::SharedLib
|
||||
) {
|
||||
let readme_content = format!(
|
||||
"# {}\n\nA CMake library project.\n\n## Build\n\n```bash\nmkdir build && cd build\ncmake ..\nmake\n```\n\n## Install\n\n```bash\ncmake --install .\n```\n",
|
||||
project_name
|
||||
@@ -306,7 +365,14 @@ fn main() -> Result<()> {
|
||||
let (name, lang, project_type, cxx_standard) = interactive_mode()?;
|
||||
let folder_name = sanitize_folder_name(&name);
|
||||
let output_path = Path::new(".").join(&folder_name);
|
||||
create_project(&name, &lang, &project_type, &cxx_standard, &output_path, args.force)?;
|
||||
create_project(
|
||||
&name,
|
||||
&lang,
|
||||
&project_type,
|
||||
&cxx_standard,
|
||||
&output_path,
|
||||
args.force,
|
||||
)?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -323,7 +389,14 @@ fn main() -> Result<()> {
|
||||
Path::new(".").join(&folder_name)
|
||||
};
|
||||
|
||||
create_project(&name, &lang, &project_type, &cxx_standard, &output_path, args.force)?;
|
||||
create_project(
|
||||
&name,
|
||||
&lang,
|
||||
&project_type,
|
||||
&cxx_standard,
|
||||
&output_path,
|
||||
args.force,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user