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.
This commit is contained in:
Etan Kissling 2024-03-01 16:15:23 +01:00 committed by GitHub
parent 84034c0379
commit a802e68c9f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 81 additions and 27 deletions

View File

@ -1,9 +1,12 @@
# beacon_chain
# Copyright (c) 2020-2024 Status Research & Development GmbH # Copyright (c) 2020-2024 Status Research & Development GmbH
# Licensed and distributed under either of # Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * 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). # * 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. # 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 # Generate a Makefile from the JSON file produce by the Nim compiler with
# "--compileOnly". Suitable for Make-controlled parallelisation, down to the GCC # "--compileOnly". Suitable for Make-controlled parallelisation, down to the GCC
# LTO level. # LTO level.
@ -12,7 +15,7 @@ import std/[json, os, strutils]
# Ripped off from Nim's `linkViaResponseFile()` in "compiler/extccomp.nim". # Ripped off from Nim's `linkViaResponseFile()` in "compiler/extccomp.nim".
# It lets us get around a command line length limit on Windows. # 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 # Extracting the linker.exe here is a bit hacky but the best solution
# given ``buildLib``'s design. # given ``buildLib``'s design.
var var
@ -51,8 +54,21 @@ proc main() =
quit(QuitFailure) quit(QuitFailure)
let let
data = json.parseFile(jsonPath) data =
makefile = open(makefilePath, fmWrite) 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: defer:
makefile.close() makefile.close()
@ -62,32 +78,70 @@ proc main() =
found: bool found: bool
cmd: string cmd: string
for compile in data["compile"]: try:
cmd = compile[1].getStr().replace('\\', '/') try:
objectPath = "" for compile in data["compile"]:
found = false cmd = compile[1].getStr().replace('\\', '/')
for token in split(cmd, Whitespace + {'\''}): objectPath = ""
if found and token.len > 0 and token.endsWith(".o"): found = false
objectPath = token for token in split(cmd, Whitespace + {'\''}):
break if found and token.len > 0 and token.endsWith(".o"):
if token == "-o": objectPath = token
found = true break
if found == false or objectPath == "": if token == "-o":
echo "Could not find the object file in this command: ", cmd 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) quit(QuitFailure)
makefile.writeLine("$#: $#" % [objectPath.replace('\\', '/'), compile[0].getStr().replace('\\', '/')])
makefile.writeLine("\t+ $#\n" % cmd)
var objects: seq[string] var objects: seq[string]
for obj in data["link"]: try:
objects.add(obj.getStr().replace('\\', '/')) for obj in data["link"]:
makefile.writeLine("OBJECTS := $#\n" % objects.join(" \\\n")) 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(".PHONY: build")
makefile.writeLine("build: $(OBJECTS)") makefile.writeLine("build: $(OBJECTS)")
makefile.writeLine("\t+ $#" % processLinkCmd(data["linkcmd"].getStr().replace('\\', '/'), makefilePath & ".linkerArgs")) let linkerArgs = makefilePath & ".linkerArgs"
if data.hasKey("extraCmds"): try:
for cmd in data["extraCmds"]: makefile.writeLine("\t+ $#" % processLinkCmd(
makefile.writeLine("\t+ $#" % cmd.getStr().replace('\\', '/')) 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() main()