]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
binman: Use target-specific tools when cross-compiling
authorAlper Nebi Yasak <alpernebiyasak@gmail.com>
Sun, 6 Sep 2020 11:46:05 +0000 (14:46 +0300)
committerSimon Glass <sjg@chromium.org>
Tue, 22 Sep 2020 18:54:13 +0000 (12:54 -0600)
Currently, binman always runs the compile tools like cc, objcopy, strip,
etc. using their literal name. Instead, this patch makes it use the
target-specific versions by default, derived from the tool-specific
environment variables (CC, OBJCOPY, STRIP, etc.) or from the
CROSS_COMPILE environment variable.

For example, the u-boot-elf etype directly uses 'strip'. Trying to run
the tests with 'CROSS_COMPILE=i686-linux-gnu- binman test' on an arm64
host results in the '097_elf_strip.dts' test to fail as the arm64
version of 'strip' can't understand the format of the x86 ELF file.

This also adjusts some command.Output() calls that caused test errors or
failures to use the target versions of the tools they call. After this,
patch, an arm64 host can run all tests with no errors or failures using
a correct CROSS_COMPILE value.

Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
tools/binman/elf.py
tools/binman/elf_test.py
tools/dtoc/fdt_util.py
tools/patman/tools.py

index f88031c2bf97c19874eb2a7ae596c7ba3cfe04ba..5e566e56cbf856dd99fcf30454c88e7059e1e395 100644 (file)
@@ -234,8 +234,10 @@ SECTIONS
     #   text section at the start
     # -m32: Build for 32-bit x86
     # -T...: Specifies the link script, which sets the start address
-    stdout = command.Output('cc', '-static', '-nostdlib', '-Wl,--build-id=none',
-                            '-m32','-T', lds_file, '-o', elf_fname, s_file)
+    cc, args = tools.GetTargetCompileTool('cc')
+    args += ['-static', '-nostdlib', '-Wl,--build-id=none', '-m32', '-T',
+            lds_file, '-o', elf_fname, s_file]
+    stdout = command.Output(cc, *args)
     shutil.rmtree(outdir)
 
 def DecodeElf(data, location):
index 37e1b423cf61cd9743ee1f8474c842fdcaf651ff..e3d218a89e92ee414fd4fa8af41e0c23e6087c31 100644 (file)
@@ -186,7 +186,9 @@ class TestElf(unittest.TestCase):
         # Make an Elf file and then convert it to a fkat binary file. This
         # should produce the original data.
         elf.MakeElf(elf_fname, expected_text, expected_data)
-        stdout = command.Output('objcopy', '-O', 'binary', elf_fname, bin_fname)
+        objcopy, args = tools.GetTargetCompileTool('objcopy')
+        args += ['-O', 'binary', elf_fname, bin_fname]
+        stdout = command.Output(objcopy, *args)
         with open(bin_fname, 'rb') as fd:
             data = fd.read()
         self.assertEqual(expected_text + expected_data, data)
index b0407937723e836b7a4f5fa04a8e32a9da77239e..37e96b98642d6900f5de75724031533d7dfa1d19 100644 (file)
@@ -68,22 +68,23 @@ def EnsureCompiled(fname, tmpdir=None, capture_stderr=False):
 
     search_paths = [os.path.join(os.getcwd(), 'include')]
     root, _ = os.path.splitext(fname)
-    args = ['-E', '-P', '-x', 'assembler-with-cpp', '-D__ASSEMBLY__']
+    cc, args = tools.GetTargetCompileTool('cc')
+    args += ['-E', '-P', '-x', 'assembler-with-cpp', '-D__ASSEMBLY__']
     args += ['-Ulinux']
     for path in search_paths:
         args.extend(['-I', path])
     args += ['-o', dts_input, fname]
-    command.Run('cc', *args)
+    command.Run(cc, *args)
 
     # If we don't have a directory, put it in the tools tempdir
     search_list = []
     for path in search_paths:
         search_list.extend(['-i', path])
-    args = ['-I', 'dts', '-o', dtb_output, '-O', 'dtb',
+    dtc, args = tools.GetTargetCompileTool('dtc')
+    args += ['-I', 'dts', '-o', dtb_output, '-O', 'dtb',
             '-W', 'no-unit_address_vs_reg']
     args.extend(search_list)
     args.append(dts_input)
-    dtc = os.environ.get('DTC') or 'dtc'
     command.Run(dtc, *args, capture_stderr=capture_stderr)
     return dtb_output
 
index d41115a22c4615d330de394c917fd63076bc98ad..66f6ab7af0636bc6baac4177887169e234a27313 100644 (file)
@@ -188,6 +188,77 @@ def PathHasFile(path_spec, fname):
             return True
     return False
 
+def GetTargetCompileTool(name, cross_compile=None):
+    """Get the target-specific version for a compile tool
+
+    This first checks the environment variables that specify which
+    version of the tool should be used (e.g. ${CC}). If those aren't
+    specified, it checks the CROSS_COMPILE variable as a prefix for the
+    tool with some substitutions (e.g. "${CROSS_COMPILE}gcc" for cc).
+
+    The following table lists the target-specific versions of the tools
+    this function resolves to:
+
+        Compile Tool  | First choice   | Second choice
+        --------------+----------------+----------------------------
+        as            |  ${AS}         | ${CROSS_COMPILE}as
+        ld            |  ${LD}         | ${CROSS_COMPILE}ld.bfd
+                      |                |   or ${CROSS_COMPILE}ld
+        cc            |  ${CC}         | ${CROSS_COMPILE}gcc
+        cpp           |  ${CPP}        | ${CROSS_COMPILE}gcc -E
+        c++           |  ${CXX}        | ${CROSS_COMPILE}g++
+        ar            |  ${AR}         | ${CROSS_COMPILE}ar
+        nm            |  ${NM}         | ${CROSS_COMPILE}nm
+        ldr           |  ${LDR}        | ${CROSS_COMPILE}ldr
+        strip         |  ${STRIP}      | ${CROSS_COMPILE}strip
+        objcopy       |  ${OBJCOPY}    | ${CROSS_COMPILE}objcopy
+        objdump       |  ${OBJDUMP}    | ${CROSS_COMPILE}objdump
+        dtc           |  ${DTC}        | (no CROSS_COMPILE version)
+
+    Args:
+        name: Command name to run
+
+    Returns:
+        target_name: Exact command name to run instead
+        extra_args: List of extra arguments to pass
+    """
+    env = dict(os.environ)
+
+    target_name = None
+    extra_args = []
+    if name in ('as', 'ld', 'cc', 'cpp', 'ar', 'nm', 'ldr', 'strip',
+                'objcopy', 'objdump', 'dtc'):
+        target_name, *extra_args = env.get(name.upper(), '').split(' ')
+    elif name == 'c++':
+        target_name, *extra_args = env.get('CXX', '').split(' ')
+
+    if target_name:
+        return target_name, extra_args
+
+    if cross_compile is None:
+        cross_compile = env.get('CROSS_COMPILE', '')
+    if not cross_compile:
+        return name, []
+
+    if name in ('as', 'ar', 'nm', 'ldr', 'strip', 'objcopy', 'objdump'):
+        target_name = cross_compile + name
+    elif name == 'ld':
+        try:
+            if Run(cross_compile + 'ld.bfd', '-v'):
+                target_name = cross_compile + 'ld.bfd'
+        except:
+            target_name = cross_compile + 'ld'
+    elif name == 'cc':
+        target_name = cross_compile + 'gcc'
+    elif name == 'cpp':
+        target_name = cross_compile + 'gcc'
+        extra_args = ['-E']
+    elif name == 'c++':
+        target_name = cross_compile + 'g++'
+    else:
+        target_name = name
+    return target_name, extra_args
+
 def Run(name, *args, **kwargs):
     """Run a tool with some arguments
 
@@ -198,16 +269,22 @@ def Run(name, *args, **kwargs):
     Args:
         name: Command name to run
         args: Arguments to the tool
+        for_target: False to run the command as-is, without resolving it
+                   to the version for the compile target
 
     Returns:
         CommandResult object
     """
     try:
         binary = kwargs.get('binary')
+        for_target = kwargs.get('for_target', True)
         env = None
         if tool_search_paths:
             env = dict(os.environ)
             env['PATH'] = ':'.join(tool_search_paths) + ':' + env['PATH']
+        if for_target:
+            name, extra_args = GetTargetCompileTool(name)
+            args = tuple(extra_args) + args
         all_args = (name,) + args
         result = command.RunPipe([all_args], capture=True, capture_stderr=True,
                                  env=env, raise_on_error=False, binary=binary)