From a802e68c9f125bba4ba361421e5b62ce73077b93 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Fri, 1 Mar 2024 16:15:23 +0100 Subject: [PATCH] handle exceptions in `generate_makefile` tool (#5985) Update `generate_makefile` to produce sensible error message in all exceptional situations, instead of just some of them. These may surface as one of the first things to someone getting started with the repo. --- tools/generate_makefile.nim | 108 +++++++++++++++++++++++++++--------- 1 file changed, 81 insertions(+), 27 deletions(-) diff --git a/tools/generate_makefile.nim b/tools/generate_makefile.nim index 30f16875f..15dbe4b7a 100644 --- a/tools/generate_makefile.nim +++ b/tools/generate_makefile.nim @@ -1,9 +1,12 @@ +# beacon_chain # Copyright (c) 2020-2024 Status Research & Development GmbH # Licensed and distributed under either of # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). # at your option. This file may not be copied, modified, or distributed except according to those terms. +{.push raises: [].} + # Generate a Makefile from the JSON file produce by the Nim compiler with # "--compileOnly". Suitable for Make-controlled parallelisation, down to the GCC # LTO level. @@ -12,7 +15,7 @@ import std/[json, os, strutils] # Ripped off from Nim's `linkViaResponseFile()` in "compiler/extccomp.nim". # It lets us get around a command line length limit on Windows. -proc processLinkCmd(cmd, linkerArgs: string): string = +proc processLinkCmd(cmd, linkerArgs: string): string {.raises: [IOError].} = # Extracting the linker.exe here is a bit hacky but the best solution # given ``buildLib``'s design. var @@ -51,8 +54,21 @@ proc main() = quit(QuitFailure) let - data = json.parseFile(jsonPath) - makefile = open(makefilePath, fmWrite) + data = + try: + json.parseFile(jsonPath) + except IOError as exc: + echo "Failed to parse file: ", jsonPath, " - [IOError]: ", exc.msg + quit(QuitFailure) + except Exception as exc: + echo "Failed to parse file: ", jsonPath, " - [Exception]: ", exc.msg + quit(QuitFailure) + makefile = + try: + open(makefilePath, fmWrite) + except IOError as exc: + echo "Failed to open file: ", makefilePath, " - [IOError]: ", exc.msg + quit(QuitFailure) defer: makefile.close() @@ -62,32 +78,70 @@ proc main() = found: bool cmd: string - for compile in data["compile"]: - cmd = compile[1].getStr().replace('\\', '/') - objectPath = "" - found = false - for token in split(cmd, Whitespace + {'\''}): - if found and token.len > 0 and token.endsWith(".o"): - objectPath = token - break - if token == "-o": - found = true - if found == false or objectPath == "": - echo "Could not find the object file in this command: ", cmd + try: + try: + for compile in data["compile"]: + cmd = compile[1].getStr().replace('\\', '/') + objectPath = "" + found = false + for token in split(cmd, Whitespace + {'\''}): + if found and token.len > 0 and token.endsWith(".o"): + objectPath = token + break + if token == "-o": + found = true + if found == false or objectPath == "": + echo "Could not find the object file in this command: ", cmd + quit(QuitFailure) + try: + makefile.writeLine("$#: $#" % [ + objectPath.replace('\\', '/'), + compile[0].getStr().replace('\\', '/')]) + makefile.writeLine("\t+ $#\n" % cmd) + except ValueError: + # https://github.com/nim-lang/Nim/pull/23356 + raiseAssert "Arguments match the format string" + except KeyError: + echo "File lacks `compile` key: ", jsonPath quit(QuitFailure) - makefile.writeLine("$#: $#" % [objectPath.replace('\\', '/'), compile[0].getStr().replace('\\', '/')]) - makefile.writeLine("\t+ $#\n" % cmd) - var objects: seq[string] - for obj in data["link"]: - objects.add(obj.getStr().replace('\\', '/')) - makefile.writeLine("OBJECTS := $#\n" % objects.join(" \\\n")) + var objects: seq[string] + try: + for obj in data["link"]: + objects.add(obj.getStr().replace('\\', '/')) + except KeyError: + echo "File lacks `link` key: ", jsonPath + quit(QuitFailure) + try: + makefile.writeLine("OBJECTS := $#\n" % objects.join(" \\\n")) + except ValueError: + # https://github.com/nim-lang/Nim/pull/23356 + raiseAssert "Arguments match the format string" - makefile.writeLine(".PHONY: build") - makefile.writeLine("build: $(OBJECTS)") - makefile.writeLine("\t+ $#" % processLinkCmd(data["linkcmd"].getStr().replace('\\', '/'), makefilePath & ".linkerArgs")) - if data.hasKey("extraCmds"): - for cmd in data["extraCmds"]: - makefile.writeLine("\t+ $#" % cmd.getStr().replace('\\', '/')) + makefile.writeLine(".PHONY: build") + makefile.writeLine("build: $(OBJECTS)") + let linkerArgs = makefilePath & ".linkerArgs" + try: + makefile.writeLine("\t+ $#" % processLinkCmd( + data["linkcmd"].getStr().replace('\\', '/'), linkerArgs)) + except IOError as exc: + echo "Failed to write file: ", linkerArgs, " - [IOError]: ", exc.msg + quit(QuitFailure) + except ValueError: + # https://github.com/nim-lang/Nim/pull/23356 + raiseAssert "Arguments match the format string" + if data.hasKey("extraCmds"): + try: + for cmd in data["extraCmds"]: + try: + makefile.writeLine("\t+ $#" % cmd.getStr().replace('\\', '/')) + except ValueError: + # https://github.com/nim-lang/Nim/pull/23356 + raiseAssert "Arguments match the format string" + except KeyError: + raiseAssert "just checked" + except IOError as exc: + echo "Failed to write file: ", makefilePath, " - [IOError]: ", exc.msg + quit(QuitFailure) main()