Skip to content

Commit 89cb6d3

Browse files
committed
Initial release 0.1.0
0 parents  commit 89cb6d3

File tree

5 files changed

+208
-0
lines changed

5 files changed

+208
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
target/*

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "cppargo"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]

README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Cppargo
2+
3+
`cppargo` is a tool to mimic the basic functionalities of the `cargo` utility
4+
for Rust projects but for C++ projects.
5+
6+
## Usage
7+
8+
### Create new project
9+
10+
In order to create a new project, use the command
11+
12+
```
13+
cppargo new {project_name}
14+
```
15+
16+
This will create a new directory `project_name` in the current working
17+
directory.
18+
19+
Inside of which it will also create a `src` with a mock `project_name.cpp`
20+
hello world program. This is the directory where all of the source files for
21+
the project.
22+
23+
It will also create a `target` directory where the excecutable files are to
24+
be stored and run from.
25+
26+
### Build projects
27+
28+
In order to build a project, use the command
29+
30+
```
31+
cppargo build
32+
```
33+
34+
Make sure to run this command within the project directory. As it will look
35+
for the `src` directory to compile all of the `.cpp` files insde it using `g++`
36+
to create the `project_name` file within the `target` directory.
37+
38+
### Run projects
39+
40+
In order to run a project, use the command
41+
42+
```
43+
cppargo run
44+
```
45+
46+
Within the project directory. This will first perform a `cppargo build` and
47+
then run the `target/project_name` file generated after a successful
48+
compilation.

src/main.rs

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
use std::{
2+
fs,
3+
process::Command,
4+
env,
5+
path::Path,
6+
};
7+
8+
fn new_project(name: &str) -> Result<(), &'static str> {
9+
let project_dir: &Path = Path::new(name);
10+
if project_dir.exists() {
11+
return Ok(())
12+
}
13+
14+
if fs::create_dir(project_dir).is_err() {
15+
return Err("Failed to create project directory.")
16+
};
17+
18+
if fs::create_dir(project_dir.join("src")).is_err() {
19+
return Err("Failed to create project source directory.")
20+
};
21+
22+
if fs::create_dir(project_dir.join("target")).is_err() {
23+
return Err("Failed to create project target directory.")
24+
};
25+
26+
let hello_world_program = concat!(
27+
"#include <iostream>\n",
28+
"\n",
29+
"int main() {\n",
30+
" std::cout << \"Hello World!\\n\";\n",
31+
" return 0;\n",
32+
"};"
33+
);
34+
35+
if fs::write(
36+
project_dir.join("src").join("main.cpp"), hello_world_program
37+
).is_err() {
38+
return Err("Failed to create project main.cpp file.")
39+
};
40+
41+
Ok(())
42+
}
43+
44+
fn build_project() -> Result<(), &'static str> {
45+
let project_dir = match env::current_dir() {
46+
Ok(path) => path,
47+
Err(_) => return Err("Couldn't get project directory.")
48+
};
49+
let project_src = project_dir.join("src");
50+
let project_target = project_dir.join("target");
51+
52+
if ! (project_src.exists() && project_target.exists()) {
53+
return Err("No src and target directories.")
54+
};
55+
56+
let src_files = match fs::read_dir(project_src) {
57+
Ok(files) => {
58+
files.filter_map(|f| f.ok())
59+
.map(|f| f.path())
60+
.filter(|f| f.extension().unwrap() == "cpp")
61+
},
62+
Err(_) => return Err("Couldn't read source directory.")
63+
};
64+
65+
let project_name = match project_dir.file_name() {
66+
Some(name) => name,
67+
None => return Err("Couldn't get project name.")
68+
};
69+
70+
let output_file = project_target.join(project_name);
71+
72+
let output_args = ["-o", output_file.to_str().unwrap()];
73+
74+
match Command::new("g++").args(output_args).args(src_files).spawn() {
75+
Ok(mut compiler) => {
76+
if compiler.wait().is_err() {
77+
return Err("Compilation failed.")
78+
};
79+
},
80+
Err(_) => return Err("Couldn't start compiler.")
81+
};
82+
83+
Ok(())
84+
}
85+
86+
fn run_project() -> Result<(), &'static str> {
87+
let project_dir = match env::current_dir() {
88+
Ok(path) => path,
89+
Err(_) => return Err("Couldn't access project directory.")
90+
};
91+
92+
let project_target = project_dir.join("target");
93+
94+
let project_name = match project_dir.file_name() {
95+
Some(name) => name,
96+
None => return Err("Couldn't get project name.")
97+
};
98+
99+
let project_excecutable = project_target.join(project_name);
100+
101+
let _ = match Command::new(project_excecutable).spawn() {
102+
Ok(mut child) => child.wait(),
103+
Err(_) => return Err("Couldn't excecute project file.")
104+
};
105+
106+
Ok(())
107+
}
108+
109+
fn main() {
110+
let mut args = env::args();
111+
args.next(); // Discard excecutable name
112+
113+
let command = args.next().expect("No command provided.");
114+
115+
if command == "new" {
116+
let project_name = args.next().expect("No project name provided.");
117+
println!("Creating new project {project_name}...");
118+
match new_project(&project_name) {
119+
Ok(_) => println!("Project {project_name} created succesfully!"),
120+
Err(err) => eprintln!("{err}")
121+
};
122+
} else if command == "build" {
123+
println!("Building project...");
124+
match build_project() {
125+
Ok(_) => println!("Project built succesfully!"),
126+
Err(err) => eprintln!("{err}")
127+
};
128+
} else if command == "run" {
129+
println!("Building project...");
130+
match build_project() {
131+
Ok(_) => println!("Project built succesfully!"),
132+
Err(err) => {
133+
eprintln!("{err}");
134+
return
135+
},
136+
};
137+
println!("Running project...");
138+
if let Err(err) = run_project() {
139+
eprintln!("{err}");
140+
};
141+
} else {
142+
eprintln!("Invalid command provided.");
143+
};
144+
}

0 commit comments

Comments
 (0)