All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Philippe Mathieu-Daudé" <philmd@linaro.org>,
	"Gerd Hoffmann" <kraxel@redhat.com>
Subject: [PULL 1/5] edk2: update build script
Date: Tue, 12 Sep 2023 13:23:55 +0200	[thread overview]
Message-ID: <20230912112406.571966-2-kraxel@redhat.com> (raw)
In-Reply-To: <20230912112406.571966-1-kraxel@redhat.com>

Sync with latest version from gitlab.com/kraxel/edk2-build-config

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 roms/edk2-build.py | 202 ++++++++++++++++++++++++++++-----------------
 1 file changed, 128 insertions(+), 74 deletions(-)

diff --git a/roms/edk2-build.py b/roms/edk2-build.py
index 870893f7c8e3..e564765aaa71 100755
--- a/roms/edk2-build.py
+++ b/roms/edk2-build.py
@@ -6,6 +6,7 @@
 """
 import os
 import sys
+import time
 import shutil
 import argparse
 import subprocess
@@ -45,19 +46,28 @@ def get_coredir(cfg):
         return os.path.abspath(cfg['global']['core'])
     return os.getcwd()
 
-def get_version(cfg):
+def get_toolchain(cfg, build):
+    if cfg.has_option(build, 'tool'):
+        return cfg[build]['tool']
+    if cfg.has_option('global', 'tool'):
+        return cfg['global']['tool']
+    return 'GCC5'
+
+def get_version(cfg, silent = False):
     coredir = get_coredir(cfg)
     if version_override:
         version = version_override
-        print('')
-        print(f'### version [override]: {version}')
+        if not silent:
+            print('')
+            print(f'### version [override]: {version}')
         return version
     if os.environ.get('RPM_PACKAGE_NAME'):
         version = os.environ.get('RPM_PACKAGE_NAME')
         version += '-' + os.environ.get('RPM_PACKAGE_VERSION')
         version += '-' + os.environ.get('RPM_PACKAGE_RELEASE')
-        print('')
-        print(f'### version [rpmbuild]: {version}')
+        if not silent:
+            print('')
+            print(f'### version [rpmbuild]: {version}')
         return version
     if os.path.exists(coredir + '/.git'):
         cmdline = [ 'git', 'describe', '--tags', '--abbrev=8',
@@ -66,16 +76,17 @@ def get_version(cfg):
                                 stdout = subprocess.PIPE,
                                 check = True)
         version = result.stdout.decode().strip()
-        print('')
-        print(f'### version [git]: {version}')
+        if not silent:
+            print('')
+            print(f'### version [git]: {version}')
         return version
     return None
 
 def pcd_string(name, value):
     return f'{name}=L{value}\\0'
 
-def pcd_version(cfg):
-    version = get_version(cfg)
+def pcd_version(cfg, silent = False):
+    version = get_version(cfg, silent)
     if version is None:
         return []
     return [ '--pcd', pcd_string('PcdFirmwareVersionString', version) ]
@@ -85,49 +96,58 @@ def pcd_release_date():
         return []
     return [ '--pcd', pcd_string('PcdFirmwareReleaseDateString', release_date) ]
 
-def build_message(line, line2 = None):
+def build_message(line, line2 = None, silent = False):
     if os.environ.get('TERM') in [ 'xterm', 'xterm-256color' ]:
         # setxterm  title
         start  = '\x1b]2;'
         end    = '\x07'
         print(f'{start}{rebase_prefix}{line}{end}', end = '')
 
-    print('')
-    print('###')
-    print(f'### {rebase_prefix}{line}')
-    if line2:
-        print(f'### {line2}')
-    print('###', flush = True)
+    if silent:
+        print(f'### {rebase_prefix}{line}', flush = True)
+    else:
+        print('')
+        print('###')
+        print(f'### {rebase_prefix}{line}')
+        if line2:
+            print(f'### {line2}')
+        print('###', flush = True)
 
-def build_run(cmdline, name, section, silent = False):
-    print(cmdline, flush = True)
+def build_run(cmdline, name, section, silent = False, nologs = False):
     if silent:
-        print('### building in silent mode ...', flush = True)
+        logfile = f'{section}.log'
+        if nologs:
+            print(f'### building in silent mode [no log] ...', flush = True)
+        else:
+            print(f'### building in silent mode [{logfile}] ...', flush = True)
+        start = time.time()
         result = subprocess.run(cmdline, check = False,
                                 stdout = subprocess.PIPE,
                                 stderr = subprocess.STDOUT)
-
-        logfile = f'{section}.log'
-        print(f'### writing log to {logfile} ...')
-        with open(logfile, 'wb') as f:
-            f.write(result.stdout)
+        if not nologs:
+            with open(logfile, 'wb') as f:
+                f.write(result.stdout)
 
         if result.returncode:
             print('### BUILD FAILURE')
+            print('### cmdline')
+            print(cmdline)
             print('### output')
             print(result.stdout.decode())
             print(f'### exit code: {result.returncode}')
         else:
-            print('### OK')
+            secs = int(time.time() - start)
+            print(f'### OK ({int(secs/60)}:{secs%60:02d})')
     else:
+        print(cmdline, flush = True)
         result = subprocess.run(cmdline, check = False)
     if result.returncode:
         print(f'ERROR: {cmdline[0]} exited with {result.returncode}'
               f' while building {name}')
         sys.exit(result.returncode)
 
-def build_copy(plat, tgt, dstdir, copy):
-    srcdir = f'Build/{plat}/{tgt}_GCC5'
+def build_copy(plat, tgt, toolchain, dstdir, copy):
+    srcdir = f'Build/{plat}/{tgt}_{toolchain}'
     names = copy.split()
     srcfile = names[0]
     if len(names) > 1:
@@ -156,66 +176,68 @@ def pad_file(dstdir, pad):
     subprocess.run(cmdline, check = True)
 
 # pylint: disable=too-many-branches
-def build_one(cfg, build, jobs = None, silent = False):
+def build_one(cfg, build, jobs = None, silent = False, nologs = False):
+    b = cfg[build]
+
     cmdline  = [ 'build' ]
-    cmdline += [ '-t', 'GCC5' ]
-    cmdline += [ '-p', cfg[build]['conf'] ]
+    cmdline += [ '-t', get_toolchain(cfg, build) ]
+    cmdline += [ '-p', b['conf'] ]
 
-    if (cfg[build]['conf'].startswith('OvmfPkg/') or
-        cfg[build]['conf'].startswith('ArmVirtPkg/')):
-        cmdline += pcd_version(cfg)
+    if (b['conf'].startswith('OvmfPkg/') or
+        b['conf'].startswith('ArmVirtPkg/')):
+        cmdline += pcd_version(cfg, silent)
         cmdline += pcd_release_date()
 
     if jobs:
         cmdline += [ '-n', jobs ]
-    for arch in cfg[build]['arch'].split():
+    for arch in b['arch'].split():
         cmdline += [ '-a', arch ]
-    if 'opts' in cfg[build]:
-        for name in cfg[build]['opts'].split():
+    if 'opts' in b:
+        for name in b['opts'].split():
             section = 'opts.' + name
             for opt in cfg[section]:
                 cmdline += [ '-D', opt + '=' + cfg[section][opt] ]
-    if 'pcds' in cfg[build]:
-        for name in cfg[build]['pcds'].split():
+    if 'pcds' in b:
+        for name in b['pcds'].split():
             section = 'pcds.' + name
             for pcd in cfg[section]:
                 cmdline += [ '--pcd', pcd + '=' + cfg[section][pcd] ]
-    if 'tgts' in cfg[build]:
-        tgts = cfg[build]['tgts'].split()
+    if 'tgts' in b:
+        tgts = b['tgts'].split()
     else:
         tgts = [ 'DEBUG' ]
     for tgt in tgts:
         desc = None
-        if 'desc' in cfg[build]:
-            desc = cfg[build]['desc']
-        build_message(f'building: {cfg[build]["conf"]} ({cfg[build]["arch"]}, {tgt})',
-                      f'description: {desc}')
+        if 'desc' in b:
+            desc = b['desc']
+        build_message(f'building: {b["conf"]} ({b["arch"]}, {tgt})',
+                      f'description: {desc}',
+                      silent = silent)
         build_run(cmdline + [ '-b', tgt ],
-                  cfg[build]['conf'],
+                  b['conf'],
                   build + '.' + tgt,
-                  silent)
+                  silent,
+                  nologs)
 
-        if 'plat' in cfg[build]:
+        if 'plat' in b:
             # copy files
-            for cpy in cfg[build]:
+            for cpy in b:
                 if not cpy.startswith('cpy'):
                     continue
-                build_copy(cfg[build]['plat'],
-                           tgt,
-                           cfg[build]['dest'],
-                           cfg[build][cpy])
+                build_copy(b['plat'], tgt,
+                           get_toolchain(cfg, build),
+                           b['dest'], b[cpy])
             # pad builds
-            for pad in cfg[build]:
+            for pad in b:
                 if not pad.startswith('pad'):
                     continue
-                pad_file(cfg[build]['dest'],
-                         cfg[build][pad])
+                pad_file(b['dest'], b[pad])
 
-def build_basetools(silent = False):
-    build_message('building: BaseTools')
+def build_basetools(silent = False, nologs = False):
+    build_message('building: BaseTools', silent = silent)
     basedir = os.environ['EDK_TOOLS_PATH']
     cmdline = [ 'make', '-C', basedir ]
-    build_run(cmdline, 'BaseTools', 'build.basetools', silent)
+    build_run(cmdline, 'BaseTools', 'build.basetools', silent, nologs)
 
 def binary_exists(name):
     for pdir in os.environ['PATH'].split(':'):
@@ -223,7 +245,7 @@ def binary_exists(name):
             return True
     return False
 
-def prepare_env(cfg):
+def prepare_env(cfg, silent = False):
     """ mimic Conf/BuildEnv.sh """
     workspace = os.getcwd()
     packages = [ workspace, ]
@@ -253,7 +275,7 @@ def prepare_env(cfg):
     toolsdef = coredir + '/Conf/tools_def.txt'
     if not os.path.exists(toolsdef):
         os.makedirs(os.path.dirname(toolsdef), exist_ok = True)
-        build_message('running BaseTools/BuildEnv')
+        build_message('running BaseTools/BuildEnv', silent = silent)
         cmdline = [ 'bash', 'BaseTools/BuildEnv' ]
         subprocess.run(cmdline, cwd = coredir, check = True)
 
@@ -267,20 +289,32 @@ def prepare_env(cfg):
     os.environ['PYTHONHASHSEED'] = '1'
 
     # for cross builds
-    if binary_exists('arm-linux-gnu-gcc'):
+    if binary_exists('arm-linux-gnueabi-gcc'):
+        # ubuntu
+        os.environ['GCC5_ARM_PREFIX'] = 'arm-linux-gnueabi-'
+        os.environ['GCC_ARM_PREFIX'] = 'arm-linux-gnueabi-'
+    elif binary_exists('arm-linux-gnu-gcc'):
+        # fedora
         os.environ['GCC5_ARM_PREFIX'] = 'arm-linux-gnu-'
+        os.environ['GCC_ARM_PREFIX'] = 'arm-linux-gnu-'
     if binary_exists('loongarch64-linux-gnu-gcc'):
         os.environ['GCC5_LOONGARCH64_PREFIX'] = 'loongarch64-linux-gnu-'
+        os.environ['GCC_LOONGARCH64_PREFIX'] = 'loongarch64-linux-gnu-'
 
     hostarch = os.uname().machine
     if binary_exists('aarch64-linux-gnu-gcc') and hostarch != 'aarch64':
         os.environ['GCC5_AARCH64_PREFIX'] = 'aarch64-linux-gnu-'
+        os.environ['GCC_AARCH64_PREFIX'] = 'aarch64-linux-gnu-'
     if binary_exists('riscv64-linux-gnu-gcc') and hostarch != 'riscv64':
         os.environ['GCC5_RISCV64_PREFIX'] = 'riscv64-linux-gnu-'
+        os.environ['GCC_RISCV64_PREFIX'] = 'riscv64-linux-gnu-'
     if binary_exists('x86_64-linux-gnu-gcc') and hostarch != 'x86_64':
         os.environ['GCC5_IA32_PREFIX'] = 'x86_64-linux-gnu-'
         os.environ['GCC5_X64_PREFIX'] = 'x86_64-linux-gnu-'
         os.environ['GCC5_BIN'] = 'x86_64-linux-gnu-'
+        os.environ['GCC_IA32_PREFIX'] = 'x86_64-linux-gnu-'
+        os.environ['GCC_X64_PREFIX'] = 'x86_64-linux-gnu-'
+        os.environ['GCC_BIN'] = 'x86_64-linux-gnu-'
 
 def build_list(cfg):
     for build in cfg.sections():
@@ -303,10 +337,12 @@ def main():
     parser.add_argument('-j', '--jobs', dest = 'jobs', type = str,
                         help = 'allow up to JOBS parallel build jobs',
                         metavar = 'JOBS')
-    parser.add_argument('-m', '--match', dest = 'match', type = str,
+    parser.add_argument('-m', '--match', dest = 'match',
+                        type = str, action = 'append',
                         help = 'only run builds matching INCLUDE (substring)',
                         metavar = 'INCLUDE')
-    parser.add_argument('-x', '--exclude', dest = 'exclude', type = str,
+    parser.add_argument('-x', '--exclude', dest = 'exclude',
+                        type = str, action = 'append',
                         help = 'skip builds matching EXCLUDE (substring)',
                         metavar = 'EXCLUDE')
     parser.add_argument('-l', '--list', dest = 'list',
@@ -316,6 +352,9 @@ def main():
                         action = 'store_true', default = False,
                         help = 'write build output to logfiles, '
                         'write to console only on errors')
+    parser.add_argument('--no-logs', dest = 'nologs',
+                        action = 'store_true', default = False,
+                        help = 'do not write build log files (with --silent)')
     parser.add_argument('--core', dest = 'core', type = str, metavar = 'DIR',
                         help = 'location of the core edk2 repository '
                         '(i.e. where BuildTools are located)')
@@ -323,6 +362,9 @@ def main():
                         type = str, action = 'append', metavar = 'DIR',
                         help = 'location(s) of additional packages '
                         '(can be specified multiple times)')
+    parser.add_argument('-t', '--toolchain', dest = 'toolchain',
+                        type = str, metavar = 'NAME',
+                        help = 'tool chain to be used to build edk2')
     parser.add_argument('--version-override', dest = 'version_override',
                         type = str, metavar = 'VERSION',
                         help = 'set firmware build version')
@@ -335,7 +377,7 @@ def main():
         os.chdir(options.directory)
 
     if not os.path.exists(options.configfile):
-        print('config file "{options.configfile}" not found')
+        print(f'config file "{options.configfile}" not found')
         return 1
 
     cfg = configparser.ConfigParser()
@@ -344,7 +386,7 @@ def main():
 
     if options.list:
         build_list(cfg)
-        return
+        return 0
 
     if not cfg.has_section('global'):
         cfg.add_section('global')
@@ -352,6 +394,8 @@ def main():
         cfg.set('global', 'core', options.core)
     if options.pkgs:
         cfg.set('global', 'pkgs', ' '.join(options.pkgs))
+    if options.toolchain:
+        cfg.set('global', 'tool', options.toolchain)
 
     global version_override
     global release_date
@@ -361,18 +405,28 @@ def main():
     if options.release_date:
         release_date = options.release_date
 
-    prepare_env(cfg)
-    build_basetools(options.silent)
+    prepare_env(cfg, options.silent)
+    build_basetools(options.silent, options.nologs)
     for build in cfg.sections():
         if not build.startswith('build.'):
             continue
-        if options.match and options.match not in build:
-            print(f'# skipping "{build}" (not matching "{options.match}")')
-            continue
-        if options.exclude and options.exclude in build:
-            print(f'# skipping "{build}" (matching "{options.exclude}")')
-            continue
-        build_one(cfg, build, options.jobs, options.silent)
+        if options.match:
+            matching = False
+            for item in options.match:
+                if item in build:
+                    matching = True
+            if not matching:
+                print(f'# skipping "{build}" (not matching "{"|".join(options.match)}")')
+                continue
+        if options.exclude:
+            exclude = False
+            for item in options.exclude:
+                if item in build:
+                    print(f'# skipping "{build}" (matching "{item}")')
+                    exclude = True
+            if exclude:
+                continue
+        build_one(cfg, build, options.jobs, options.silent, options.nologs)
 
     return 0
 
-- 
2.41.0



  reply	other threads:[~2023-09-12 11:24 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-12 11:23 [PULL 0/5] Firmware/edk2 20230912 patches Gerd Hoffmann
2023-09-12 11:23 ` Gerd Hoffmann [this message]
2023-09-12 11:23 ` [PULL 2/5] edk2: update build config Gerd Hoffmann
2023-09-12 11:23 ` [PULL 3/5] edk2: update submodule to edk2-stable202308 Gerd Hoffmann
2023-09-12 11:23 ` [PULL 4/5] edk2: workaround edk-stable202308 bug Gerd Hoffmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230912112406.571966-2-kraxel@redhat.com \
    --to=kraxel@redhat.com \
    --cc=philmd@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.