Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle exceptions in generate_makefile tool #5985

Merged
merged 2 commits into from
Mar 1, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 83 additions & 29 deletions tools/generate_makefile.nim
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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
Expand Down Expand Up @@ -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()
Expand All @@ -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)

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)
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"))

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('\\', '/'))
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)")
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()
Loading