diff --git a/Makefile b/Makefile index 235aee34..d3501d08 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/klippy/mcu.py b/klippy/mcu.py index 78dfe9e7..136b3bc8 100644 --- a/klippy/mcu.py +++ b/klippy/mcu.py @@ -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)) diff --git a/klippy/msgproto.py b/klippy/msgproto.py index 40138346..736fe1b8 100644 --- a/klippy/msgproto.py +++ b/klippy/msgproto.py @@ -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: diff --git a/klippy/serialhdl.py b/klippy/serialhdl.py index e7e35bf8..08f7ef23 100644 --- a/klippy/serialhdl.py +++ b/klippy/serialhdl.py @@ -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 diff --git a/scripts/buildcommands.py b/scripts/buildcommands.py index 0abc0e33..b9d89e0e 100644 --- a/scripts/buildcommands.py +++ b/scripts/buildcommands.py @@ -4,8 +4,7 @@ # Copyright (C) 2016 Kevin O'Connor # # 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