--- /dev/null
+#
+# Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+class LdGenFailure(RuntimeError):
+ """
+ Parent class for any ldgen runtime failure which is due to input data
+ """
+ def __init__(self, message):
+ super(LdGenFailure, self).__init__(message)
-#!/usr/bin/env python
#
# Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
#
from sdkconfig import SDKConfig
from pyparsing import *
+from common import LdGenFailure
"""
Fragment file internal representation. Parses and stores instances of the fragment definitions
# Set any text beginnning with # as comment
parser.ignore("#" + restOfLine)
- self.fragments = parser.parseFile(fragment_file, parseAll=True)
+ try:
+ self.fragments = parser.parseFile(fragment_file, parseAll=True)
+ except ParseBaseException as e:
+ # the actual parse error is kind of useless for normal users, so just point to the location of
+ # the error
+ raise LdGenFailure("Parse error in linker fragment %s: error at line %d col %d (char %d)" % (
+ fragment_file.name, e.lineno, e.column, e.loc))
for fragment in self.fragments:
fragment.path = path
-#!/usr/bin/env python
#
# Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
#
from sdkconfig import SDKConfig
from fragments import FragmentFileModel, Sections, Scheme, Mapping, Fragment
from pyparsing import *
+from common import LdGenFailure
"""
Encapsulates a generated placement rule placed under a target
Exception for linker script generation failures such as undefined references/ failure to
evaluate conditions, duplicate mappings, etc.
"""
-class GenerationException(Exception):
+class GenerationException(LdGenFailure):
UNDEFINED_REFERENCE = "Undefined reference"
import os
import traceback
import sys
+import tempfile
from fragments import FragmentFileModel
from sdkconfig import SDKConfig
from generation import GenerationModel, TemplateModel, SectionsInfo
+from common import LdGenFailure
def main():
argparser.add_argument(
"--output", "-o",
help = "Output linker script",
- type = argparse.FileType("w"))
+ type = str)
argparser.add_argument(
"--config", "-c",
input_file = args.input
fragment_files = [] if not args.fragments else args.fragments
config_file = args.config
- output_file = args.output
+ output_path = args.output
sections_info_files = [] if not args.sections else args.sections
kconfig_file = args.kconfig
-
+
try:
sections_infos = SectionsInfo()
script_model = TemplateModel(input_file)
script_model.fill(mapping_rules, sdkconfig)
- script_model.write(output_file)
- except Exception as e:
- print("linker script generation failed for %s\nERROR: %s" % (input_file.name, e.message))
- # Delete the file so the entire build will fail; and not use an outdated script.
- os.remove(output_file.name)
- # Print traceback and exit
- traceback.print_exc()
+ with tempfile.TemporaryFile("w+") as output:
+ script_model.write(output)
+ output.seek(0)
+ with open(output_path, "w") as f: # only create output file after generation has suceeded
+ f.write(output.read())
+ except LdGenFailure as e:
+ print("linker script generation failed for %s\nERROR: %s" % (input_file.name, e))
sys.exit(1)
if __name__ == "__main__":
- main()
\ No newline at end of file
+ main()
-#!/usr/bin/env python
#
# Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
#
("&&", 2, opAssoc.LEFT),
("||", 2, opAssoc.LEFT)])
- return grammar
\ No newline at end of file
+ return grammar