initial commit
This commit is contained in:
246
libraries/FastLED/scripts/all_source_build.py.disabled
Normal file
246
libraries/FastLED/scripts/all_source_build.py.disabled
Normal file
@@ -0,0 +1,246 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
FastLED All Source Build Script
|
||||
|
||||
This script implements the unified source build system for FastLED by:
|
||||
1. Starting with ONE file for testing (allocator.cpp)
|
||||
2. Copying original .cpp content to .cpp.hpp
|
||||
3. Replacing .cpp with conditional wrapper code
|
||||
4. Creating src/fastled_compile.cpp to include .cpp.hpp files
|
||||
5. Adding FASTLED_ALL_SRC logic to compiler_control.h
|
||||
|
||||
CRITICAL: This script processes original .cpp content CORRECTLY:
|
||||
- Step 1: Copy original .cpp -> .cpp.hpp (preserves source)
|
||||
- Step 2: Replace .cpp with wrapper (conditional include)
|
||||
"""
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import glob
|
||||
from pathlib import Path
|
||||
from typing import List, Set
|
||||
|
||||
|
||||
def find_cpp_files(base_dirs: List[str]) -> List[Path]:
|
||||
"""Find all .cpp files in the specified directories and subdirectories."""
|
||||
cpp_files = []
|
||||
for base_dir in base_dirs:
|
||||
if not os.path.exists(base_dir):
|
||||
continue
|
||||
pattern = os.path.join(base_dir, "**", "*.cpp")
|
||||
cpp_files.extend(Path(f) for f in glob.glob(pattern, recursive=True))
|
||||
return sorted(cpp_files)
|
||||
|
||||
|
||||
def get_relative_include_path(file_path: Path, from_src: bool = True) -> str:
|
||||
"""Get the relative include path from src/ directory."""
|
||||
if from_src:
|
||||
# Remove 'src/' prefix if present
|
||||
parts = file_path.parts
|
||||
if parts[0] == 'src':
|
||||
return '/'.join(parts[1:])
|
||||
return str(file_path)
|
||||
return str(file_path)
|
||||
|
||||
|
||||
def create_cpp_wrapper(original_cpp: Path, hpp_file: Path) -> str:
|
||||
"""Create the wrapper .cpp file content with conditional includes."""
|
||||
relative_hpp_path = get_relative_include_path(hpp_file)
|
||||
|
||||
content = f'''#include "fl/compiler_control.h"
|
||||
|
||||
#if !FASTLED_ALL_SRC
|
||||
#include "{relative_hpp_path}"
|
||||
#endif
|
||||
'''
|
||||
return content
|
||||
|
||||
|
||||
def update_compiler_control_h(compiler_control_path: Path) -> None:
|
||||
"""Add FASTLED_ALL_SRC logic to compiler_control.h."""
|
||||
with open(compiler_control_path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# Check if FASTLED_ALL_SRC is already defined
|
||||
if 'FASTLED_ALL_SRC' in content:
|
||||
print(f"FASTLED_ALL_SRC already defined in {compiler_control_path}")
|
||||
return
|
||||
|
||||
# Add FASTLED_ALL_SRC logic at the end
|
||||
fastled_all_src_logic = '''
|
||||
|
||||
// All Source Build Control
|
||||
// When FASTLED_ALL_SRC is enabled, all source is compiled into a single translation unit
|
||||
// Debug/testing builds use individual compilation for better error isolation
|
||||
#ifndef FASTLED_ALL_SRC
|
||||
#if defined(DEBUG) || defined(FASTLED_TESTING)
|
||||
#define FASTLED_ALL_SRC 0
|
||||
#elif !defined(RELEASE) || (RELEASE == 0)
|
||||
#define FASTLED_ALL_SRC 1
|
||||
#else
|
||||
#define FASTLED_ALL_SRC 0
|
||||
#endif
|
||||
#endif
|
||||
'''
|
||||
|
||||
updated_content = content + fastled_all_src_logic
|
||||
|
||||
with open(compiler_control_path, 'w') as f:
|
||||
f.write(updated_content)
|
||||
|
||||
print(f"Updated {compiler_control_path} with FASTLED_ALL_SRC logic")
|
||||
|
||||
|
||||
def create_fastled_compile_cpp(cpp_hpp_files: List[Path], output_path: Path) -> None:
|
||||
"""Create src/fastled_compile.cpp with all .cpp.hpp includes."""
|
||||
includes = []
|
||||
for hpp_file in sorted(cpp_hpp_files):
|
||||
relative_path = get_relative_include_path(hpp_file)
|
||||
includes.append(f'#include "{relative_path}"')
|
||||
|
||||
content = f'''// FastLED All Source Build File
|
||||
// This file includes all .cpp.hpp files for unified compilation
|
||||
// Generated automatically by scripts/all_source_build.py
|
||||
|
||||
#include "fl/compiler_control.h"
|
||||
|
||||
#if FASTLED_ALL_SRC
|
||||
|
||||
{chr(10).join(includes)}
|
||||
|
||||
#endif // FASTLED_ALL_SRC
|
||||
'''
|
||||
|
||||
with open(output_path, 'w') as f:
|
||||
f.write(content)
|
||||
|
||||
print(f"Created {output_path} with {len(includes)} includes")
|
||||
|
||||
|
||||
def process_single_cpp_file(cpp_file: Path, dry_run: bool = False) -> Path:
|
||||
"""
|
||||
Process a single .cpp file, converting it to the new format.
|
||||
|
||||
CRITICAL LOGIC:
|
||||
1. Copy original .cpp content to .cpp.hpp (PRESERVES SOURCE)
|
||||
2. Replace .cpp with wrapper code (CONDITIONAL INCLUDE)
|
||||
|
||||
Returns the .cpp.hpp file path.
|
||||
"""
|
||||
hpp_file = cpp_file.with_suffix('.cpp.hpp')
|
||||
|
||||
print(f"Processing {cpp_file} -> {hpp_file}")
|
||||
|
||||
if not dry_run:
|
||||
# STEP 1: Copy original .cpp content to .cpp.hpp (PRESERVE ORIGINAL SOURCE)
|
||||
print(f" Step 1: Copying original content {cpp_file} -> {hpp_file}")
|
||||
shutil.copy2(cpp_file, hpp_file)
|
||||
|
||||
# STEP 2: Replace .cpp with wrapper code (CONDITIONAL INCLUDE)
|
||||
print(f" Step 2: Replacing {cpp_file} with wrapper code")
|
||||
wrapper_content = create_cpp_wrapper(cpp_file, hpp_file)
|
||||
with open(cpp_file, 'w') as f:
|
||||
f.write(wrapper_content)
|
||||
|
||||
return hpp_file
|
||||
|
||||
|
||||
def process_cpp_files(cpp_files: List[Path], dry_run: bool = False) -> List[Path]:
|
||||
"""Process all .cpp files, converting them to the new format."""
|
||||
processed_hpp_files = []
|
||||
|
||||
for cpp_file in cpp_files:
|
||||
hpp_file = process_single_cpp_file(cpp_file, dry_run)
|
||||
processed_hpp_files.append(hpp_file)
|
||||
|
||||
return processed_hpp_files
|
||||
|
||||
|
||||
def main():
|
||||
"""Main function to run the all source build transformation."""
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='FastLED All Source Build Script')
|
||||
parser.add_argument('--dry-run', action='store_true',
|
||||
help='Show what would be done without making changes')
|
||||
parser.add_argument('--src-dir', default='src',
|
||||
help='Source directory (default: src)')
|
||||
parser.add_argument('--single-file', action='store_true',
|
||||
help='Process only allocator.cpp for testing')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Define target directories
|
||||
target_dirs = [
|
||||
os.path.join(args.src_dir, 'fl'),
|
||||
os.path.join(args.src_dir, 'sensors'),
|
||||
os.path.join(args.src_dir, 'fx')
|
||||
]
|
||||
|
||||
# Check if directories exist
|
||||
for dir_path in target_dirs:
|
||||
if not os.path.exists(dir_path):
|
||||
print(f"Warning: Directory {dir_path} does not exist")
|
||||
|
||||
# Find all .cpp files
|
||||
all_cpp_files = find_cpp_files(target_dirs)
|
||||
|
||||
# If single-file mode, only process allocator.cpp
|
||||
if args.single_file:
|
||||
allocator_files = [f for f in all_cpp_files if f.name == 'allocator.cpp']
|
||||
if not allocator_files:
|
||||
print("ERROR: allocator.cpp not found!")
|
||||
return
|
||||
cpp_files = allocator_files
|
||||
print(f"SINGLE FILE MODE: Processing only {cpp_files[0]}")
|
||||
else:
|
||||
cpp_files = all_cpp_files
|
||||
print(f"Found {len(cpp_files)} .cpp files:")
|
||||
for cpp_file in cpp_files:
|
||||
print(f" {cpp_file}")
|
||||
|
||||
if not cpp_files:
|
||||
print("No .cpp files found!")
|
||||
return
|
||||
|
||||
if args.dry_run:
|
||||
print("\n--- DRY RUN MODE ---")
|
||||
print("The following actions would be performed:")
|
||||
|
||||
for cpp_file in cpp_files:
|
||||
hpp_file = cpp_file.with_suffix('.cpp.hpp')
|
||||
print(f" 1. Copy {cpp_file} -> {hpp_file} (preserve original)")
|
||||
print(f" 2. Replace {cpp_file} with conditional wrapper")
|
||||
|
||||
print(f" 3. Update {args.src_dir}/fl/compiler_control.h")
|
||||
print(f" 4. Create {args.src_dir}/fastled_compile.cpp")
|
||||
return
|
||||
|
||||
print(f"\nStarting all source build transformation...")
|
||||
|
||||
# Process .cpp files
|
||||
processed_hpp_files = process_cpp_files(cpp_files, dry_run=args.dry_run)
|
||||
|
||||
# Update compiler_control.h
|
||||
compiler_control_path = Path(args.src_dir) / 'fl' / 'compiler_control.h'
|
||||
if compiler_control_path.exists():
|
||||
update_compiler_control_h(compiler_control_path)
|
||||
else:
|
||||
print(f"Warning: {compiler_control_path} not found")
|
||||
|
||||
# Create fastled_compile.cpp
|
||||
fastled_compile_path = Path(args.src_dir) / 'fastled_compile.cpp'
|
||||
create_fastled_compile_cpp(processed_hpp_files, fastled_compile_path)
|
||||
|
||||
print(f"\nAll source build transformation complete!")
|
||||
print(f"Processed {len(cpp_files)} .cpp files")
|
||||
print(f"Created {len(processed_hpp_files)} .cpp.hpp files")
|
||||
|
||||
if args.single_file:
|
||||
print(f"\n*** SINGLE FILE MODE COMPLETE ***")
|
||||
print(f"Test with: bash test")
|
||||
print(f"If successful, run again without --single-file for full conversion")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user