19
19
20
20
import re
21
21
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
23
23
from os import makedirs , write , remove
24
24
from tempfile import mkstemp
25
25
from shutil import rmtree
@@ -270,6 +270,41 @@ def compile_cpp(self, source, object, includes):
270
270
def correct_scatter_shebang (self , sc_fileref , cur_dir_name = None ):
271
271
"""Correct the shebang at the top of a scatter file.
272
272
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
+
273
308
Positional arguments:
274
309
sc_fileref -- FileRef object of the scatter file
275
310
@@ -285,21 +320,34 @@ def correct_scatter_shebang(self, sc_fileref, cur_dir_name=None):
285
320
"""
286
321
with open (sc_fileref .path , "r" ) as input :
287
322
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.
288
326
if (lines [0 ].startswith (self .SHEBANG ) or
289
- not lines [0 ].startswith ("#!" )):
327
+ not lines [0 ].startswith ("#!" )):
290
328
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 )
303
351
304
352
def get_link_command (
305
353
self ,
0 commit comments