latest pushes

This commit is contained in:
Ronaldson Bellande 2024-10-02 12:46:57 -04:00
parent 8696d1b97c
commit 3bf70ffaea
3 changed files with 163 additions and 92 deletions

View File

@ -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 <https://www.gnu.org/licenses/>.
#!/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())

View File

@ -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 <https://www.gnu.org/licenses/>.
#!/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()