build: Add gcc and binutils version to mcu data dictionary

Store the gcc and binutils versions used in the compilation of the
firmware in the firmware data dictionary.  Forward that information to
the log so it is available during debugging.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2017-12-21 18:18:18 -05:00
parent 522093ef00
commit d778ae1846
5 changed files with 51 additions and 12 deletions

View File

@ -80,7 +80,7 @@ $(OUT)%.o.ctr: $(OUT)%.o
$(OUT)compile_time_request.o: $(patsubst %.c, $(OUT)src/%.o.ctr,$(src-y)) ./scripts/buildcommands.py
@echo " Building $@"
$(Q)cat $(patsubst %.c, $(OUT)src/%.o.ctr,$(src-y)) > $(OUT)klipper.compile_time_request
$(Q)$(PYTHON) ./scripts/buildcommands.py -d $(OUT)klipper.dict $(OUT)klipper.compile_time_request $(OUT)compile_time_request.c
$(Q)$(PYTHON) ./scripts/buildcommands.py -d $(OUT)klipper.dict -t "$(CC);$(AS);$(LD);$(OBJCOPY);$(OBJDUMP);$(STRIP)" $(OUT)klipper.compile_time_request $(OUT)compile_time_request.c
$(Q)$(CC) $(CFLAGS) -c $(OUT)compile_time_request.c -o $@
$(OUT)klipper.elf: $(patsubst %.c, $(OUT)src/%.o,$(src-y)) $(OUT)compile_time_request.o

View File

@ -574,9 +574,9 @@ class MCU:
msgparser = self._serial.msgparser
info = [
"Configured MCU '%s' (%d moves)" % (self._name, move_count),
"Loaded MCU '%s' %d commands (%s)" % (
"Loaded MCU '%s' %d commands (%s / %s)" % (
self._name, len(msgparser.messages_by_id),
msgparser.version),
msgparser.version, msgparser.build_versions),
"MCU '%s' config: %s" % (self._name, " ".join(
["%s=%s" % (k, v) for k, v in msgparser.config.items()]))]
self._printer.bglogger.set_rollover_info(self._name, "\n".join(info))

View File

@ -188,7 +188,7 @@ class MessageParser:
self.messages_by_name = {}
self.static_strings = {}
self.config = {}
self.version = ""
self.version = self.build_versions = ""
self.raw_identify_data = ""
self._init_messages(DefaultMessages, DefaultMessages.keys())
def check_packet(self, s):
@ -318,6 +318,7 @@ class MessageParser:
self.static_strings = { int(k): v for k, v in static_strings.items() }
self.config.update(data.get('config', {}))
self.version = data.get('version', '')
self.build_versions = data.get('build_versions', '')
except error as e:
raise
except Exception as e:

View File

@ -84,8 +84,9 @@ class SerialReader:
msgparser.process_identify(identify_data)
self.msgparser = msgparser
self.register_callback(self.handle_unknown, '#unknown')
logging.info("Loaded %d commands (%s)",
len(msgparser.messages_by_id), msgparser.version)
logging.info("Loaded %d commands (%s / %s)",
len(msgparser.messages_by_id),
msgparser.version, msgparser.build_versions)
logging.info("MCU config: %s", " ".join(
["%s=%s" % (k, v) for k, v in msgparser.config.items()]))
# Setup baud adjust

View File

@ -4,8 +4,7 @@
# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import sys, os, subprocess, optparse, logging, shlex, socket, time
import sys, os, subprocess, optparse, logging, shlex, socket, time, traceback
import json, zlib
sys.path.append('./klippy')
import msgproto
@ -182,7 +181,7 @@ const uint8_t command_index_size PROGMEM = ARRAY_SIZE(command_index);
######################################################################
def build_identify(cmd_by_id, msg_to_id, responses, static_strings
, constants, version):
, constants, version, toolstr):
#commands, messages, static_strings
messages = dict((msgid, msg) for msg, msgid in msg_to_id.items())
data = {}
@ -193,6 +192,7 @@ def build_identify(cmd_by_id, msg_to_id, responses, static_strings
for i in range(len(static_strings)) }
data['config'] = constants
data['version'] = version
data['build_versions'] = toolstr
# Format compressed info into C code
data = json.dumps(data)
@ -203,6 +203,9 @@ def build_identify(cmd_by_id, msg_to_id, responses, static_strings
out.append('\n ')
out.append(" 0x%02x," % (ord(zdata[i]),))
fmt = """
// version: %s
// build_versions: %s
const uint8_t command_identify_data[] PROGMEM = {%s
};
@ -210,7 +213,7 @@ const uint8_t command_identify_data[] PROGMEM = {%s
const uint32_t command_identify_size PROGMEM
= ARRAY_SIZE(command_identify_data);
"""
return data, fmt % (''.join(out), len(zdata), len(data))
return data, fmt % (version, toolstr, ''.join(out), len(zdata), len(data))
######################################################################
@ -254,6 +257,36 @@ def build_version(extra):
version = "%s-%s-%s%s" % (version, btime, hostname, extra)
return version
# Run "tool --version" for each specified tool and extract versions
def tool_versions(tools):
tools = [t.strip() for t in tools.split(';')]
versions = ['', '']
success = 0
for tool in tools:
# Extract first line from "tool --version" output
verstr = check_output("%s --version" % (tool,)).split('\n')[0]
# Check if this tool looks like a binutils program
isbinutils = 0
if verstr.startswith('GNU '):
isbinutils = 1
verstr = verstr[4:]
# Extract version information and exclude program name
if ' ' not in verstr:
continue
prog, ver = verstr.split(' ', 1)
if not prog or not ver:
continue
# Check for any version conflicts
if versions[isbinutils] and versions[isbinutils] != ver:
logging.debug("Mixed version %s vs %s" % (
repr(versions[isbinutils]), repr(ver)))
versions[isbinutils] = "mixed"
continue
versions[isbinutils] = ver
success += 1
cleanbuild = versions[0] and versions[1] and success == len(tools)
return cleanbuild, "gcc: %s binutils: %s" % (versions[0], versions[1])
######################################################################
# Main code
@ -266,6 +299,8 @@ def main():
help="extra version string to append to version")
opts.add_option("-d", dest="write_dictionary",
help="file to write mcu protocol dictionary")
opts.add_option("-t", "--tools", dest="tools", default="",
help="list of build programs to extract version from")
opts.add_option("-v", action="store_true", dest="verbose",
help="enable debug messages")
@ -349,12 +384,14 @@ def main():
cmdcode = build_commands(cmd_by_id, messages_by_name, all_param_types)
paramcode = build_param_types(all_param_types)
# Create identify information
cleanbuild, toolstr = tool_versions(options.tools)
version = build_version(options.extra)
sys.stdout.write("Version: %s\n" % (version,))
responses = [msg_to_id[msg] for msgname, msg in messages_by_name.items()
if msgname not in commands]
datadict, icode = build_identify(cmd_by_id, msg_to_id, responses
, static_strings, constants, version)
datadict, icode = build_identify(
cmd_by_id, msg_to_id, responses,
static_strings, constants, version, toolstr)
# Write output
f = open(outcfile, 'wb')
f.write(FILEHEADER + call_lists_code + static_strings_code