Files
RTOS/scripts/setup_environment.sh
root ca13734bf0 Add full automotive RTOS project
Add kernel (Cortex-M0/M3/M4, Tricore, S32K, RISC-V ports), drivers,
middleware (CAN stack, diagnostics, safety), applications, board
support, build/test tooling, and documentation.
2026-08-23 03:35:29 -04:00

616 lines
19 KiB
Bash
Executable File

#!/bin/bash
#==============================================================================
# @file setup_environment.sh
# @brief Setup development environment for Automotive RTOS
#==============================================================================
set -e
# Script directory - handle spaces and special characters properly
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
# Color codes
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
#==============================================================================
# OS Detection
#==============================================================================
detect_os() {
case "$(uname -s)" in
Darwin*)
OS="macos"
OS_VERSION=$(sw_vers -productVersion 2>/dev/null || echo "unknown")
ARCH=$(uname -m)
;;
Linux*)
OS="linux"
if [ -f /etc/os-release ]; then
. /etc/os-release
DISTRO="$ID"
elif [ -f /etc/debian_version ]; then
DISTRO="debian"
elif [ -f /etc/redhat-release ]; then
DISTRO="redhat"
else
DISTRO="unknown"
fi
ARCH=$(uname -m)
;;
MINGW*|MSYS*|CYGWIN*)
OS="windows"
;;
*)
OS="unknown"
;;
esac
}
#==============================================================================
# Print Banner
#==============================================================================
print_banner() {
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE} Automotive RTOS Environment Setup${NC}"
echo -e "${BLUE}========================================${NC}"
echo -e " OS: ${CYAN}${OS}${NC}"
if [ "$OS" = "linux" ]; then
echo -e " Distro: ${CYAN}${DISTRO}${NC}"
fi
if [ "$OS" = "macos" ]; then
echo -e " Version: ${CYAN}${OS_VERSION}${NC}"
fi
echo -e " Arch: ${CYAN}${ARCH}${NC}"
echo ""
}
#==============================================================================
# Command Check
#==============================================================================
command_exists() {
command -v "$1" >/dev/null 2>&1
}
#==============================================================================
# Install Package - Cross-platform
#==============================================================================
install_package() {
local package=$1
echo -e "${YELLOW}Installing ${package}...${NC}"
case "$OS" in
macos)
if command_exists brew; then
brew install "$package" || {
echo -e "${YELLOW}Failed to install ${package} via brew${NC}"
return 1
}
else
echo -e "${RED}Homebrew not found. Please install Homebrew first:${NC}"
echo " /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""
return 1
fi
;;
linux)
case "$DISTRO" in
ubuntu|debian)
sudo apt-get update
sudo apt-get install -y "$package"
;;
fedora|centos|rhel)
sudo dnf install -y "$package" || sudo yum install -y "$package"
;;
arch)
sudo pacman -S --noconfirm "$package"
;;
*)
echo -e "${RED}Unsupported Linux distribution: ${DISTRO}${NC}"
return 1
;;
esac
;;
windows)
echo -e "${YELLOW}Please install ${package} manually on Windows${NC}"
echo " Visit: https://${package}.org/download/"
return 1
;;
*)
echo -e "${RED}Unsupported OS${NC}"
return 1
;;
esac
echo -e "${GREEN}${package} installed${NC}"
return 0
}
#==============================================================================
# Install ARM Toolchain
#==============================================================================
install_arm_toolchain() {
echo -e "${YELLOW}Installing ARM toolchain...${NC}"
# Check if already installed
if command_exists arm-none-eabi-gcc; then
echo -e "${GREEN}✓ ARM toolchain already installed: $(arm-none-eabi-gcc --version | head -n1)${NC}"
return 0
fi
case "$OS" in
macos)
if command_exists brew; then
echo -e "${YELLOW}Installing ARM toolchain via Homebrew...${NC}"
# Try the official tap first
brew tap ArmMbed/homebrew-formulae 2>/dev/null || true
brew install arm-none-eabi-gcc 2>/dev/null || {
echo -e "${YELLOW}Trying alternative installation method...${NC}"
# Alternative: download from ARM developer site
echo -e "${YELLOW}Please download ARM toolchain from:${NC}"
echo " https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads"
echo -e "${YELLOW}Choose the macOS (Apple Silicon or Intel) version${NC}"
echo -e "${YELLOW}After downloading, add to PATH:${NC}"
echo " export PATH=\"/path/to/arm-gnu-toolchain/bin:\$PATH\""
}
else
echo -e "${RED}Homebrew not found${NC}"
return 1
fi
;;
linux)
case "$DISTRO" in
ubuntu|debian)
sudo apt-get install -y gcc-arm-none-eabi binutils-arm-none-eabi
;;
fedora|centos|rhel)
sudo dnf install -y arm-none-eabi-gcc arm-none-eabi-binutils
;;
arch)
sudo pacman -S --noconfirm arm-none-eabi-gcc arm-none-eabi-binutils
;;
esac
;;
windows)
echo -e "${YELLOW}Download ARM toolchain from:${NC}"
echo " https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads"
;;
esac
# Verify installation
if command_exists arm-none-eabi-gcc; then
echo -e "${GREEN}✓ ARM toolchain installed: $(arm-none-eabi-gcc --version | head -n1)${NC}"
return 0
else
echo -e "${YELLOW}ARM toolchain not found in PATH${NC}"
echo -e "${YELLOW}Please add it manually or install from ARM developer site${NC}"
return 1
fi
}
#==============================================================================
# Install Build Tools
#==============================================================================
install_build_tools() {
echo -e "${YELLOW}Installing build tools...${NC}"
# CMake
if command_exists cmake; then
echo -e "${GREEN}✓ CMake already installed: $(cmake --version | head -n1)${NC}"
else
install_package cmake
fi
# Make
if command_exists make; then
echo -e "${GREEN}✓ Make already installed${NC}"
else
install_package make
fi
# Git
if command_exists git; then
echo -e "${GREEN}✓ Git already installed: $(git --version)${NC}"
else
install_package git
fi
}
#==============================================================================
# Install Debug Tools
#==============================================================================
install_debug_tools() {
echo -e "${YELLOW}Installing debug tools...${NC}"
case "$OS" in
macos)
# GDB for ARM
if command_exists arm-none-eabi-gdb; then
echo -e "${GREEN}✓ ARM GDB already installed${NC}"
elif command_exists gdb; then
echo -e "${GREEN}✓ GDB installed (may not support ARM targets)${NC}"
echo -e "${YELLOW} Consider installing arm-none-eabi-gdb via brew${NC}"
else
echo -e "${YELLOW}Installing GDB...${NC}"
brew install gdb 2>/dev/null || echo -e "${YELLOW} GDB installation skipped${NC}"
fi
# OpenOCD
if command_exists openocd; then
echo -e "${GREEN}✓ OpenOCD already installed${NC}"
else
echo -e "${YELLOW}Installing OpenOCD...${NC}"
brew install openocd 2>/dev/null || echo -e "${YELLOW} OpenOCD installation skipped${NC}"
fi
# STLink tools
if command_exists st-flash; then
echo -e "${GREEN}✓ STLink tools already installed${NC}"
else
echo -e "${YELLOW}Installing STLink tools...${NC}"
brew install stlink 2>/dev/null || echo -e "${YELLOW} STLink installation skipped${NC}"
fi
;;
linux)
# GDB multiarch
if command_exists gdb-multiarch; then
echo -e "${GREEN}✓ GDB multiarch already installed${NC}"
else
install_package gdb-multiarch
fi
# OpenOCD
if command_exists openocd; then
echo -e "${GREEN}✓ OpenOCD already installed${NC}"
else
install_package openocd
fi
# STLink tools
if command_exists st-flash; then
echo -e "${GREEN}✓ STLink tools already installed${NC}"
else
install_package stlink-tools
fi
;;
esac
}
#==============================================================================
# Install Analysis Tools
#==============================================================================
install_analysis_tools() {
echo -e "${YELLOW}Installing analysis tools...${NC}"
# Cppcheck
if command_exists cppcheck; then
echo -e "${GREEN}✓ Cppcheck already installed${NC}"
else
install_package cppcheck
fi
# Clang
if command_exists clang; then
echo -e "${GREEN}✓ Clang already installed${NC}"
else
install_package llvm
fi
# Valgrind (Linux only)
if [ "$OS" = "linux" ]; then
if command_exists valgrind; then
echo -e "${GREEN}✓ Valgrind already installed${NC}"
else
install_package valgrind
fi
fi
}
#==============================================================================
# Install Python Tools
#==============================================================================
install_python_tools() {
echo -e "${YELLOW}Installing Python tools...${NC}"
# Python3
if command_exists python3; then
echo -e "${GREEN}✓ Python3 already installed: $(python3 --version)${NC}"
else
install_package python3
fi
# Pip3
if command_exists pip3; then
echo -e "${GREEN}✓ Pip3 already installed${NC}"
else
install_package python3-pip
fi
# Python packages
echo -e "${YELLOW}Installing Python packages...${NC}"
pip3 install --user \
pyelftools \
pyserial \
numpy \
matplotlib \
pytest \
coverage \
gcovr 2>/dev/null || {
echo -e "${YELLOW}Some Python packages may need sudo${NC}"
echo -e "${YELLOW}Try: pip3 install --user <package>${NC}"
}
}
#==============================================================================
# Setup Project Directories
#==============================================================================
setup_project_dirs() {
echo -e "${YELLOW}Setting up project directories...${NC}"
mkdir -p "${PROJECT_ROOT}/build"
mkdir -p "${PROJECT_ROOT}/build/logs"
mkdir -p "${PROJECT_ROOT}/build/misra"
mkdir -p "${PROJECT_ROOT}/build/docs"
mkdir -p "${PROJECT_ROOT}/build/coverage"
mkdir -p "${PROJECT_ROOT}/build/tests"
echo -e "${GREEN}✓ Project directories created${NC}"
}
#==============================================================================
# Setup Git Hooks
#==============================================================================
setup_git_hooks() {
echo -e "${YELLOW}Setting up git hooks...${NC}"
if [ -d "${PROJECT_ROOT}/.git" ]; then
HOOKS_DIR="${PROJECT_ROOT}/.git/hooks"
mkdir -p "${HOOKS_DIR}"
# Pre-commit hook
cat > "${HOOKS_DIR}/pre-commit" << 'EOF'
#!/bin/bash
# Pre-commit hook for Automotive RTOS
echo "Running pre-commit checks..."
# Check for trailing whitespace
if git diff --cached --check; then
echo "✓ No whitespace issues"
else
echo "✗ Trailing whitespace found"
exit 1
fi
# Check for large files
large_files=$(git diff --cached --name-only | xargs -I{} du -k {} 2>/dev/null | awk '$1 > 1024 {print $2}')
if [ -n "$large_files" ]; then
echo "✗ Large files detected (>1MB):"
echo "$large_files"
exit 1
fi
echo "✓ Pre-commit checks passed"
EOF
chmod +x "${HOOKS_DIR}/pre-commit"
# Pre-push hook
cat > "${HOOKS_DIR}/pre-push" << 'EOF'
#!/bin/bash
# Pre-push hook for Automotive RTOS
echo "Running pre-push checks..."
# Run quick static analysis
if [ -f "scripts/static_analysis.sh" ]; then
bash scripts/static_analysis.sh --quick
fi
echo "✓ Pre-push checks passed"
EOF
chmod +x "${HOOKS_DIR}/pre-push"
echo -e "${GREEN}✓ Git hooks installed${NC}"
else
echo -e "${YELLOW}Not a git repository. Skipping git hooks.${NC}"
fi
}
#==============================================================================
# Setup VS Code Configuration
#==============================================================================
setup_vscode() {
echo -e "${YELLOW}Setting up VS Code configuration...${NC}"
VSCODE_DIR="${PROJECT_ROOT}/.vscode"
mkdir -p "${VSCODE_DIR}"
# Only create if files don't exist
if [ ! -f "${VSCODE_DIR}/settings.json" ]; then
cat > "${VSCODE_DIR}/settings.json" << 'EOF'
{
"editor.formatOnSave": true,
"editor.tabSize": 4,
"files.encoding": "utf8",
"C_Cpp.default.includePath": [
"${workspaceFolder}/kernel/include",
"${workspaceFolder}/drivers/include",
"${workspaceFolder}/middleware",
"${workspaceFolder}/config"
],
"C_Cpp.default.compilerPath": "/opt/homebrew/bin/arm-none-eabi-gcc"
}
EOF
echo -e "${GREEN}✓ VS Code settings created${NC}"
else
echo -e "${YELLOW}VS Code settings already exist. Skipping.${NC}"
fi
}
#==============================================================================
# Setup Environment Variables
#==============================================================================
setup_env_vars() {
echo -e "${YELLOW}Setting up environment variables...${NC}"
ENV_FILE="${PROJECT_ROOT}/.env"
# Detect toolchain path
if command_exists arm-none-eabi-gcc; then
TOOLCHAIN_PATH="$(dirname $(which arm-none-eabi-gcc))"
else
TOOLCHAIN_PATH="/opt/homebrew/bin"
fi
cat > "${ENV_FILE}" << EOF
# Automotive RTOS Environment Variables
# Generated on $(date)
export RTOS_ROOT="${PROJECT_ROOT}"
export RTOS_BUILD_DIR="\${RTOS_ROOT}/build"
export RTOS_TOOLCHAIN="${TOOLCHAIN_PATH}/arm-none-eabi-"
export RTOS_TARGET="stm32f407_discovery"
export RTOS_DEBUG_PORT="3333"
# Add toolchain to PATH if not already there
if [[ ":\$PATH:" != *":${TOOLCHAIN_PATH}:"* ]]; then
export PATH="${TOOLCHAIN_PATH}:\$PATH"
fi
EOF
# Add to shell profile if not already there
SHELL_PROFILE=""
case "$SHELL" in
*/bash)
SHELL_PROFILE="$HOME/.bash_profile"
[ -f "$HOME/.bashrc" ] && SHELL_PROFILE="$HOME/.bashrc"
;;
*/zsh)
SHELL_PROFILE="$HOME/.zshrc"
;;
esac
if [ -n "$SHELL_PROFILE" ] && [ -f "$SHELL_PROFILE" ]; then
if ! grep -q "RTOS_ROOT" "$SHELL_PROFILE"; then
echo "" >> "$SHELL_PROFILE"
echo "# Automotive RTOS Environment" >> "$SHELL_PROFILE"
echo "source ${ENV_FILE}" >> "$SHELL_PROFILE"
echo -e "${GREEN}✓ Added to ${SHELL_PROFILE}${NC}"
fi
fi
echo -e "${GREEN}✓ Environment variables configured${NC}"
echo -e "${YELLOW}To apply now, run: source ${ENV_FILE}${NC}"
}
#==============================================================================
# Main Setup Function
#==============================================================================
main() {
detect_os
print_banner
# Parse arguments
INSTALL_TOOLCHAIN=true
INSTALL_BUILD=true
INSTALL_DEBUG=true
INSTALL_ANALYSIS=true
INSTALL_PYTHON=true
while [[ $# -gt 0 ]]; do
case $1 in
--minimal)
INSTALL_DEBUG=false
INSTALL_ANALYSIS=false
INSTALL_PYTHON=false
shift
;;
--no-toolchain)
INSTALL_TOOLCHAIN=false
shift
;;
--no-debug)
INSTALL_DEBUG=false
shift
;;
--no-analysis)
INSTALL_ANALYSIS=false
shift
;;
--no-python)
INSTALL_PYTHON=false
shift
;;
-h|--help)
echo "Usage: $0 [OPTIONS]"
echo " --minimal Minimal installation"
echo " --no-toolchain Skip ARM toolchain"
echo " --no-debug Skip debug tools"
echo " --no-analysis Skip analysis tools"
echo " --no-python Skip Python tools"
exit 0
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done
# Install components
if [ "$INSTALL_TOOLCHAIN" = true ]; then
install_arm_toolchain || echo -e "${YELLOW}Toolchain installation incomplete${NC}"
fi
if [ "$INSTALL_BUILD" = true ]; then
install_build_tools
fi
if [ "$INSTALL_DEBUG" = true ]; then
install_debug_tools
fi
if [ "$INSTALL_ANALYSIS" = true ]; then
install_analysis_tools
fi
if [ "$INSTALL_PYTHON" = true ]; then
install_python_tools
fi
# Setup project
setup_project_dirs
setup_git_hooks
setup_vscode
setup_env_vars
# Print summary
echo ""
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN} Environment Setup Complete${NC}"
echo -e "${GREEN}========================================${NC}"
echo ""
echo -e "Next steps:"
echo -e " 1. Apply environment: ${CYAN}source ${PROJECT_ROOT}/.env${NC}"
echo -e " 2. Build project: ${CYAN}bash scripts/build_all.sh${NC}"
echo -e " 3. Run tests: ${CYAN}bash scripts/run_tests.sh${NC}"
echo ""
# Check if toolchain is working
if command_exists arm-none-eabi-gcc; then
echo -e "${GREEN}✓ ARM toolchain ready: $(arm-none-eabi-gcc --version | head -n1)${NC}"
else
echo -e "${YELLOW}⚠ ARM toolchain not found${NC}"
echo -e "${YELLOW} Download from: https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads${NC}"
echo -e "${YELLOW} For macOS Apple Silicon, choose: arm-gnu-toolchain-*-darwin-arm64-arm-none-eabi.tar.xz${NC}"
echo -e "${YELLOW} Extract and add to PATH${NC}"
fi
}
# Run main
main "$@"