From 19ce296eb213a8e0a98111d68cae21a59ab8cdde Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Thu, 15 Aug 2024 23:14:46 +1000 Subject: [PATCH 1/4] Perform test compiles during `qmk doctor`. --- lib/python/qmk/cli/doctor/check.py | 36 ++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/lib/python/qmk/cli/doctor/check.py b/lib/python/qmk/cli/doctor/check.py index d563811aba..a88a883603 100644 --- a/lib/python/qmk/cli/doctor/check.py +++ b/lib/python/qmk/cli/doctor/check.py @@ -4,6 +4,8 @@ from enum import Enum import re import shutil from subprocess import DEVNULL, TimeoutExpired +from tempfile import TemporaryDirectory +from pathlib import Path from milc import cli from qmk import submodules @@ -44,7 +46,22 @@ def _check_arm_gcc_version(): version_number = ESSENTIAL_BINARIES['arm-none-eabi-gcc']['output'].strip() cli.log.info('Found arm-none-eabi-gcc version %s', version_number) - return CheckStatus.OK # Right now all known arm versions are ok + # Right now all known arm versions are ok, so check that it can produce binaries + return _check_arm_gcc_installation() + + +def _check_arm_gcc_installation(): + """Returns OK if the arm-none-eabi-gcc is fully installed and can produce binaries. + """ + with TemporaryDirectory() as temp_dir: + temp_file = Path(temp_dir) / 'test.elf' + args = ['arm-none-eabi-gcc', '-mcpu=cortex-m0', '-mthumb', '-mno-thumb-interwork', '--specs=nosys.specs', '--specs=nano.specs', '-x', 'c', '-o', str(temp_file), '-'] + result = cli.run(args, stdin=None, stdout=DEVNULL, stderr=None, input='int main() { return 0; }') + if result.returncode != 0: + cli.log.error(f'Failed to compile a simple program with arm-none-eabi-gcc, return code {result.returncode}') + cli.log.error(f'Command: {" ".join(args)}') + return CheckStatus.ERROR + return CheckStatus.OK def _check_avr_gcc_version(): @@ -53,7 +70,22 @@ def _check_avr_gcc_version(): version_number = ESSENTIAL_BINARIES['avr-gcc']['output'].strip() cli.log.info('Found avr-gcc version %s', version_number) - return CheckStatus.OK + # Right now all known arm versions are ok, so check that it can produce binaries + return _check_avr_gcc_installation() + + +def _check_avr_gcc_installation(): + """Returns OK if the avr-gcc is fully installed and can produce binaries. + """ + with TemporaryDirectory() as temp_dir: + temp_file = Path(temp_dir) / 'test.elf' + args = ['avr-gcc', '-mmcu=atmega32u4', '-x', 'c', '-o', str(temp_file), '-'] + result = cli.run(args, stdin=None, stdout=None, stderr=None, input='int main() { return 0; }') + if result.returncode != 0: + cli.log.error(f'Failed to compile a simple program with avr-gcc, return code {result.returncode}') + cli.log.error(f'Command: {" ".join(args)}') + return CheckStatus.ERROR + return CheckStatus.OK def _check_avrdude_version(): From 80254c99ec6f080a36cc5c26ddcf1822ffca315f Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Thu, 15 Aug 2024 23:19:53 +1000 Subject: [PATCH 2/4] Consistency. --- lib/python/qmk/cli/doctor/check.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/qmk/cli/doctor/check.py b/lib/python/qmk/cli/doctor/check.py index a88a883603..ce72a78697 100644 --- a/lib/python/qmk/cli/doctor/check.py +++ b/lib/python/qmk/cli/doctor/check.py @@ -56,7 +56,7 @@ def _check_arm_gcc_installation(): with TemporaryDirectory() as temp_dir: temp_file = Path(temp_dir) / 'test.elf' args = ['arm-none-eabi-gcc', '-mcpu=cortex-m0', '-mthumb', '-mno-thumb-interwork', '--specs=nosys.specs', '--specs=nano.specs', '-x', 'c', '-o', str(temp_file), '-'] - result = cli.run(args, stdin=None, stdout=DEVNULL, stderr=None, input='int main() { return 0; }') + result = cli.run(args, stdin=None, stdout=None, stderr=None, input='int main() { return 0; }') if result.returncode != 0: cli.log.error(f'Failed to compile a simple program with arm-none-eabi-gcc, return code {result.returncode}') cli.log.error(f'Command: {" ".join(args)}') From c934d2b66c70f3cec6916007a5f2328891259906 Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Fri, 16 Aug 2024 08:40:00 +1000 Subject: [PATCH 3/4] Update lib/python/qmk/cli/doctor/check.py Co-authored-by: James Young <18669334+noroadsleft@users.noreply.github.com> --- lib/python/qmk/cli/doctor/check.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/qmk/cli/doctor/check.py b/lib/python/qmk/cli/doctor/check.py index ce72a78697..9bafce1e7c 100644 --- a/lib/python/qmk/cli/doctor/check.py +++ b/lib/python/qmk/cli/doctor/check.py @@ -70,7 +70,7 @@ def _check_avr_gcc_version(): version_number = ESSENTIAL_BINARIES['avr-gcc']['output'].strip() cli.log.info('Found avr-gcc version %s', version_number) - # Right now all known arm versions are ok, so check that it can produce binaries + # Right now all known avr versions are ok, so check that it can produce binaries return _check_avr_gcc_installation() From 9c396f7427718e5baedb9de6056e0e12124012b8 Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Fri, 16 Aug 2024 08:55:13 +1000 Subject: [PATCH 4/4] Explicitly include newlib.h, use some defines from it. Invoke some binutils to verify that's working too. --- lib/python/qmk/cli/doctor/check.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/lib/python/qmk/cli/doctor/check.py b/lib/python/qmk/cli/doctor/check.py index 9bafce1e7c..911bd93913 100644 --- a/lib/python/qmk/cli/doctor/check.py +++ b/lib/python/qmk/cli/doctor/check.py @@ -46,7 +46,7 @@ def _check_arm_gcc_version(): version_number = ESSENTIAL_BINARIES['arm-none-eabi-gcc']['output'].strip() cli.log.info('Found arm-none-eabi-gcc version %s', version_number) - # Right now all known arm versions are ok, so check that it can produce binaries + # Right now all known ARM versions are ok, so check that it can produce binaries return _check_arm_gcc_installation() @@ -55,12 +55,21 @@ def _check_arm_gcc_installation(): """ with TemporaryDirectory() as temp_dir: temp_file = Path(temp_dir) / 'test.elf' + args = ['arm-none-eabi-gcc', '-mcpu=cortex-m0', '-mthumb', '-mno-thumb-interwork', '--specs=nosys.specs', '--specs=nano.specs', '-x', 'c', '-o', str(temp_file), '-'] - result = cli.run(args, stdin=None, stdout=None, stderr=None, input='int main() { return 0; }') + result = cli.run(args, stdin=None, stdout=None, stderr=None, input='#include \nint main() { return __NEWLIB__ * __NEWLIB_MINOR__ * __NEWLIB_PATCHLEVEL__; }') if result.returncode != 0: cli.log.error(f'Failed to compile a simple program with arm-none-eabi-gcc, return code {result.returncode}') cli.log.error(f'Command: {" ".join(args)}') return CheckStatus.ERROR + + args = ['arm-none-eabi-size', str(temp_file)] + result = cli.run(args, stdin=None, stdout=None, stderr=None, input='int main() { return 0; }') + if result.returncode != 0: + cli.log.error(f'Failed to execute arm-none-eabi-size, perhaps corrupt arm-none-eabi-binutils, return code {result.returncode}') + cli.log.error(f'Command: {" ".join(args)}') + return CheckStatus.ERROR + return CheckStatus.OK @@ -70,7 +79,7 @@ def _check_avr_gcc_version(): version_number = ESSENTIAL_BINARIES['avr-gcc']['output'].strip() cli.log.info('Found avr-gcc version %s', version_number) - # Right now all known avr versions are ok, so check that it can produce binaries + # Right now all known AVR versions are ok, so check that it can produce binaries return _check_avr_gcc_installation() @@ -79,12 +88,21 @@ def _check_avr_gcc_installation(): """ with TemporaryDirectory() as temp_dir: temp_file = Path(temp_dir) / 'test.elf' + args = ['avr-gcc', '-mmcu=atmega32u4', '-x', 'c', '-o', str(temp_file), '-'] result = cli.run(args, stdin=None, stdout=None, stderr=None, input='int main() { return 0; }') if result.returncode != 0: cli.log.error(f'Failed to compile a simple program with avr-gcc, return code {result.returncode}') cli.log.error(f'Command: {" ".join(args)}') return CheckStatus.ERROR + + args = ['avr-size', str(temp_file)] + result = cli.run(args, stdin=None, stdout=None, stderr=None, input='int main() { return 0; }') + if result.returncode != 0: + cli.log.error(f'Failed to execute avr-size, perhaps corrupt avr-binutils, return code {result.returncode}') + cli.log.error(f'Command: {" ".join(args)}') + return CheckStatus.ERROR + return CheckStatus.OK