Skip to content

Commit 764cdcf

Browse files
authored
Merge pull request #11777 from mark-edgeworth/fix-scatter-include-path
IOTBTOOL-377: Fix scatter file include path online
2 parents bf4d51e + e7964ca commit 764cdcf

File tree

1 file changed

+62
-14
lines changed

1 file changed

+62
-14
lines changed

tools/toolchains/arm.py

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
import re
2121
from copy import copy
22-
from os.path import join, dirname, splitext, basename, exists, isfile, relpath
22+
from os.path import join, dirname, splitext, basename, exists, isfile, relpath, sep
2323
from os import makedirs, write, remove
2424
from tempfile import mkstemp
2525
from shutil import rmtree
@@ -270,6 +270,41 @@ def compile_cpp(self, source, object, includes):
270270
def correct_scatter_shebang(self, sc_fileref, cur_dir_name=None):
271271
"""Correct the shebang at the top of a scatter file.
272272
273+
The shebang line is the line at the top of the file starting with '#!'. If this line is present
274+
then the linker will execute the command on that line on the content of the scatter file prior
275+
to consuming the content into the link. Typically the shebang line will contain an instruction
276+
to run the C-preprocessor (either 'armcc -E' or 'armclang -E') which allows for macro expansion,
277+
inclusion of headers etc. Other options are passed to the preprocessor to specify aspects of the
278+
system such as the processor architecture and cpu type.
279+
280+
The build system (at this point) will have constructed what it considers to be a correct shebang
281+
line for this build. If this differs from the line in the scatter file then the scatter file
282+
will be rewritten by this function to contain the build-system-generated shebang line. Note
283+
that the rewritten file will be placed in the BUILD output directory.
284+
285+
Include processing
286+
287+
If the scatter file runs the preprocessor, and contains #include statements then the pre-processor
288+
include path specifies where the #include files are to be found. Typically, #include files
289+
are specified with a path relative to the location of the original scatter file. When the
290+
preprocessor runs, the system automatically passes the location of the scatter file into the
291+
include path through an implicit '-I' option to the preprocessor, and this works fine in the
292+
offline build system.
293+
Unfortunately this approach does not work in the online build, because the preprocessor
294+
command runs in a chroot. The true (non-chroot) path to the file as known by the build system
295+
looks something like this:
296+
/tmp/chroots/ch-eefd72fb-2bcb-4e99-9043-573d016618bb/extras/mbed-os.lib/...
297+
whereas the path known by the preprocessor will be:
298+
/extras/mbed-os.lib/...
299+
Consequently, the chroot path has to be explicitly passed to the preprocessor through an
300+
explicit -I/path/to/chroot/file option in the shebang line.
301+
302+
*** THERE IS AN ASSUMPTION THAT THE CHROOT PATH IS THE REAL FILE PATH WITH THE FIRST
303+
*** THREE ELEMENTS REMOVED. THIS ONLY HOLDS TRUE UNTIL THE ONLINE BUILD SYSTEM CHANGES
304+
305+
If the include path manipulation as described above does change, then any scatter file
306+
containing a #include statement is likely to fail on the online compiler.
307+
273308
Positional arguments:
274309
sc_fileref -- FileRef object of the scatter file
275310
@@ -285,21 +320,34 @@ def correct_scatter_shebang(self, sc_fileref, cur_dir_name=None):
285320
"""
286321
with open(sc_fileref.path, "r") as input:
287322
lines = input.readlines()
323+
324+
# If the existing scatter file has no shebang line, or the line that it does have
325+
# matches the desired line then the existing scatter file is used directly without rewriting.
288326
if (lines[0].startswith(self.SHEBANG) or
289-
not lines[0].startswith("#!")):
327+
not lines[0].startswith("#!")):
290328
return sc_fileref
291-
else:
292-
new_scatter = join(self.build_dir, ".link_script.sct")
293-
if cur_dir_name is None:
294-
cur_dir_name = dirname(sc_fileref.path)
295-
self.SHEBANG += " -I %s" % cur_dir_name
296-
if self.need_update(new_scatter, [sc_fileref.path]):
297-
with open(new_scatter, "w") as out:
298-
out.write(self.SHEBANG)
299-
out.write("\n")
300-
out.write("".join(lines[1:]))
301-
302-
return FileRef(".link_script.sct", new_scatter)
329+
330+
new_scatter = join(self.build_dir, ".link_script.sct")
331+
if cur_dir_name is None:
332+
cur_dir_name = dirname(sc_fileref.path)
333+
334+
# For a chrooted system, adjust the path to the scatter file to be a valid
335+
# chroot location by removing the first three elements of the path.
336+
if cur_dir_name.startswith("/tmp/chroots"):
337+
cur_dir_name = sep + join(*(cur_dir_name.split(sep)[4:]))
338+
339+
# Add the relocated scatter file path to the include path.
340+
self.SHEBANG += " -I%s" % cur_dir_name
341+
342+
# Only rewrite if doing a full build...
343+
if self.need_update(new_scatter, [sc_fileref.path]):
344+
with open(new_scatter, "w") as out:
345+
# Write the new shebang line...
346+
out.write(self.SHEBANG + "\n")
347+
# ...followed by the unmolested remaining content from the original scatter file.
348+
out.write("".join(lines[1:]))
349+
350+
return FileRef(".link_script.sct", new_scatter)
303351

304352
def get_link_command(
305353
self,

0 commit comments

Comments
 (0)