#!/usr/bin/env python3

# Copyright 2021 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Build firmware with clang instead of gcc."""
import logging
import os
import subprocess
import sys


# Add to this list as compilation errors are fixed for boards.
BOARDS_THAT_COMPILE_SUCCESSFULLY_WITH_CLANG = [
    'dartmonkey',
    'bloonchipper',
    'nucleo-f412zg',
    'nucleo-h743zi',
]


def build(board_name: str) -> None:
    """Build with clang for specified board."""
    logging.debug('Building board: "%s"', board_name)

    cmd = [
        'make',
        'BOARD=' + board_name,
        '-j',
    ]

    logging.debug('Running command: "%s"', ' '.join(cmd))
    subprocess.run(cmd, env=dict(os.environ, CC='clang'), check=True)


def main() -> int:
    logging.basicConfig(level='DEBUG')
    for board in BOARDS_THAT_COMPILE_SUCCESSFULLY_WITH_CLANG:
        build(board)

    return 0


if __name__ == '__main__':
    sys.exit(main())

@@ -242,55 +242,162 @@
 ort 
-logging%0Aimport os%0Aimport subprocess%0Aimport sys%0A
+argparse%0Aimport concurrent%0Aimport logging%0Aimport multiprocessing%0Aimport os%0Aimport subprocess%0Aimport sys%0A%0Afrom concurrent.futures import ThreadPoolExecutor
 %0A%0A# 
@@ -965,126 +965,1215 @@
     
-logging.basicConfig(level='DEBUG')%0A    for board in BOARDS_THAT_COMPILE_SUCCESSFULLY_WITH_CLANG:%0A        build(board)%0A
+parser = argparse.ArgumentParser()%0A%0A    log_level_choices = %5B'DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'%5D%0A    parser.add_argument(%0A        '--log_level', '-l',%0A        choices=log_level_choices,%0A        default='DEBUG'%0A    )%0A%0A    parser.add_argument(%0A        '--num_threads', '-j',%0A        type=int,%0A        default=multiprocessing.cpu_count()%0A    )%0A%0A    args = parser.parse_args()%0A    logging.basicConfig(level=args.log_level)%0A%0A    logging.debug('Building with %25d threads', args.num_threads)%0A%0A    failed_boards = %5B%5D%0A    with ThreadPoolExecutor(max_workers=args.num_threads) as executor:%0A        future_to_board = %7B%0A            executor.submit(build, board): board%0A            for board in BOARDS_THAT_COMPILE_SUCCESSFULLY_WITH_CLANG%0A        %7D%0A        for future in concurrent.futures.as_completed(future_to_board):%0A            board = future_to_board%5Bfuture%5D%0A            try:%0A                future.result()%0A            except Exception:%0A                failed_boards.append(board)%0A%0A    if len(failed_boards) %3E 0:%0A        logging.error('The following boards failed to compile:%5Cn%25s',%0A                      '%5Cn'.join(failed_boards))%0A        return 1%0A%0A    logging.info('All boards compiled successfully!')
 %0A   

Add parallelism