diff --git a/src/__init__.py b/src/bellande_rust/__init__.py
similarity index 100%
rename from src/__init__.py
rename to src/bellande_rust/__init__.py
diff --git a/src/bellande_rust/bellande_rust_executable.py b/src/bellande_rust/bellande_rust_executable.py
new file mode 100644
index 0000000..8c97b65
--- /dev/null
+++ b/src/bellande_rust/bellande_rust_executable.py
@@ -0,0 +1,163 @@
+# Copyright (C) 2024 Bellande Architecture Mechanism Research Innovation Center, Ronaldson Bellande
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+#!/usr/bin/env python3
+
+import subprocess
+import os
+import shutil
+import argparse
+import toml
+
+def ensure_directory(path):
+ """Ensure a directory exists and create one if it does not"""
+ os.makedirs(path, exist_ok=True)
+
+def copy_source_files(src_dir, dest_dir):
+ """Maintained the structure of the src file; or assigned"""
+ if not os.path.exists(src_dir):
+ raise FileNotFoundError(f"Source directory '{src_dir}' not found")
+
+ dest_src_dir = os.path.join(dest_dir, 'src')
+ ensure_directory(dest_src_dir)
+
+ for root, dirs, files in os.walk(src_dir):
+ for file in files:
+ src_path = os.path.join(root, file)
+ rel_path = os.path.relpath(src_path, src_dir)
+ dest_path = os.path.join(dest_src_dir, rel_path)
+ ensure_directory(os.path.dirname(dest_path))
+ shutil.copy2(src_path, dest_path)
+
+def create_cargo_toml(project_dir, main_file, binary_name):
+ """Create a Cargo.toml file for a binary target."""
+ cargo_config = {
+ 'package': {
+ 'name': binary_name,
+ 'version': "0.1.0",
+ 'edition': "2021"
+ },
+ 'dependencies': {}
+ }
+
+ # If the main file isn't main.rs, we need to specify the path
+ if main_file != 'main.rs':
+ cargo_config['bin'] = [{
+ 'name': binary_name,
+ 'path': os.path.join("src", main_file)
+ }]
+
+ cargo_toml_path = os.path.join(project_dir, 'Cargo.toml')
+ with open(cargo_toml_path, 'w') as f:
+ toml.dump(cargo_config, f)
+
+def parse_dependencies(dep_file):
+ """Parse dependencies from the specified dependencies file."""
+ dependencies = {}
+ if os.path.exists(dep_file):
+ with open(dep_file, 'r') as file:
+ for line in file:
+ line = line.strip()
+ if line and not line.startswith('#'):
+ try:
+ name, version = line.split('=')
+ dependencies[name.strip()] = version.strip().strip('"')
+ except ValueError:
+ print(f"Warning: Skipping invalid dependency line: {line}")
+ return dependencies
+
+def update_cargo_toml_dependencies(project_dir, dependencies):
+ """Update the dependencies in Cargo.toml."""
+ cargo_toml_path = os.path.join(project_dir, 'Cargo.toml')
+ with open(cargo_toml_path, 'r') as f:
+ cargo_config = toml.load(f)
+
+ cargo_config['dependencies'] = dependencies
+
+ with open(cargo_toml_path, 'w') as f:
+ toml.dump(cargo_config, f)
+
+def build_project(project_dir, output_path, binary_name):
+ """Build the Rust project as an executable."""
+ cargo_command = ['cargo', 'build', '--release']
+ result = subprocess.run(cargo_command, cwd=project_dir, capture_output=True, text=True)
+
+ if result.returncode == 0:
+ # Determine the correct executable name based on platform
+ if os.name == 'nt': # Windows
+ exe_extension = '.exe'
+ else: # Unix-like systems
+ exe_extension = ''
+
+ # Copy the built executable to the specified output location
+ built_exe = os.path.join(project_dir, 'target', 'release', f"{binary_name}{exe_extension}")
+ ensure_directory(os.path.dirname(output_path))
+ shutil.copy2(built_exe, output_path)
+
+ # Make the output file executable on Unix-like systems
+ if os.name != 'nt':
+ os.chmod(output_path, 0o755)
+
+ return True
+ else:
+ print("Build failed. Cargo output:")
+ print(result.stdout)
+ print(result.stderr)
+ return False
+
+def main():
+ parser = argparse.ArgumentParser(description="Universal Rust Executable Builder")
+ parser.add_argument("-d", "--dep-file", required=True, help="Path to the dependencies file")
+ parser.add_argument("-s", "--src-dir", required=True, help="Source directory containing Rust files")
+ parser.add_argument("-m", "--main-file", required=True, help="Main Rust file name (e.g., main.rs)")
+ parser.add_argument("-o", "--output", required=True, help="Output path for the compiled executable")
+
+ args = parser.parse_args()
+
+ # Extract binary name from the file name (removing .rs extension)
+ binary_name = os.path.splitext(args.main_file)[0]
+
+ # Create unique build directory based on binary name
+ build_dir = f"build_{binary_name}"
+ ensure_directory(build_dir)
+
+ try:
+ copy_source_files(args.src_dir, build_dir)
+ create_cargo_toml(build_dir, args.main_file, binary_name)
+
+ # Parse and update dependencies
+ dependencies = parse_dependencies(args.dep_file)
+ update_cargo_toml_dependencies(build_dir, dependencies)
+
+ # Determine the correct output path based on platform
+ if os.name == 'nt': # Windows
+ output_path = f"{args.output}.exe"
+ else: # Unix-like systems
+ output_path = args.output
+
+ # Build the project
+ if build_project(build_dir, output_path, binary_name):
+ print(f"Successfully built and copied to {output_path}")
+ return 0
+ else:
+ print("Build failed")
+ return 1
+
+ finally:
+ # Clean up build directory
+ shutil.rmtree(build_dir, ignore_errors=True)
+
+if __name__ == "__main__":
+ exit(main())
diff --git a/src/bellande_rust_executable.py b/src/bellande_rust_executable.py
deleted file mode 100644
index 8c29b27..0000000
--- a/src/bellande_rust_executable.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# Copyright (C) 2024 Bellande Architecture Mechanism Research Innovation Center, Ronaldson Bellande
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see .
-
-#!/usr/bin/env python3
-
-import subprocess
-import os
-import shutil
-import argparse
-import toml
-import tempfile
-
-def parse_dependencies(dep_file):
- if not os.path.exists(dep_file):
- print(f"No {dep_file} file found.")
- return {}
- dependencies = {}
- with open(dep_file, 'r') as file:
- for line in file:
- parts = line.strip().split('=')
- if len(parts) == 2:
- dependencies[parts[0].strip()] = parts[1].strip().strip('"')
- return dependencies
-
-def create_cargo_project(rust_file, dependencies, output_file, suppress_warnings):
- with tempfile.TemporaryDirectory() as temp_dir:
- project_name = "temp_rust_project"
- subprocess.run(['cargo', 'new', '--bin', project_name], cwd=temp_dir, check=True)
- project_dir = os.path.join(temp_dir, project_name)
-
- shutil.copy(rust_file, os.path.join(project_dir, 'src', 'main.rs'))
-
- cargo_toml_path = os.path.join(project_dir, 'Cargo.toml')
- with open(cargo_toml_path, 'r') as f:
- cargo_toml = toml.load(f)
-
- cargo_toml['dependencies'] = dependencies
-
- with open(cargo_toml_path, 'w') as f:
- toml.dump(cargo_toml, f)
-
- print("Building Rust project...")
- cargo_command = ['cargo', 'build', '--release']
- if suppress_warnings:
- cargo_command.append('--quiet')
- result = subprocess.run(cargo_command, cwd=project_dir, capture_output=True, text=True)
- print(f"Cargo build output:\n{result.stdout}\n{result.stderr}")
-
- if result.returncode == 0:
- os.makedirs(os.path.dirname(output_file), exist_ok=True)
-
- binary_path = os.path.join(project_dir, 'target', 'release', project_name)
- shutil.copy(binary_path, output_file)
- print(f"Rust code compiled successfully. Output file: {output_file}")
- else:
- print(f"Cargo build failed with return code {result.returncode}")
-
-def main():
- parser = argparse.ArgumentParser(description="Compile Rust code with dependencies using Cargo")
- parser.add_argument("-d", "--dep-file", default="dependencies.txt", help="Path to the dependencies file (default: dependencies.txt)")
- parser.add_argument("-s", "--source", default="src/main.rs", help="Path to the Rust source file (default: src/main.rs)")
- parser.add_argument("-o", "--output", default="my_rust_executable", help="Name for the output executable (default: my_rust_executable)")
- parser.add_argument("--suppress-warnings", action="store_true", help="Suppress compilation warnings")
-
- args = parser.parse_args()
- print("Rust Build Script")
- print("----------------")
- print(f"Dependencies file: {args.dep_file}")
- print(f"Rust source file: {args.source}")
- print(f"Output executable: {args.output}")
-
- dependencies = parse_dependencies(args.dep_file)
- if not dependencies:
- print("No valid dependencies found. Exiting.")
- return
-
- create_cargo_project(args.source, dependencies, args.output, args.suppress_warnings)
-
-if __name__ == "__main__":
- main()