Andreas Wacknitz
2024-04-05 ac4c8f5b8ab57563cc350482b75a32a55871d58c
tools/userland-component
@@ -1,4 +1,4 @@
#!/usr/bin/python3.5
#!/usr/bin/python3.9
#
# This file and its contents are supplied under the terms of the
@@ -44,13 +44,14 @@
#       variable $(WS_RULES). Do the same for other variables.
def refactor000(mk):
    for i in iter(mk.includes):
        r = re.match(r"^\$\(WS_TOP\)\/(.*)\/(.*).mk", i.str[0])
        r = re.match(r"^\$\(WS_TOP\)\/(.*)\/(.*).mk", i.value())
        if r is not None:
            subdir = r.group(1)
            mkfile = r.group(2)
            print("000: Fix include " + i.str[0])
            print("000: Fix include " + i.value())
            i.set_value(os.path.join(MK.directory_variable(subdir), mkfile+".mk"))
            mk.contents[i.line()] = i.include_line()
    mk.update()
#-----------------------------------------------------------------------------
@@ -59,9 +60,10 @@
#           1. infer the build system and set the BUILD_STYLE.
#           2. set the BUILD_BITS from the existing targets.
#           3. erase default target and keep the custom ones.
#           4. fix known target typos
def refactor001(mk):
    kw = Keywords()
    if mk.has_variable('BUILD_STYLE'):
    if mk.has_variable('BUILD_STYLE') or mk.has_mk_include('common'):
        return
    # Build style
    build_style = None
@@ -84,38 +86,49 @@
    else:
        print("001: Setting make bits to '" + mk_bits + "'")
    # Check targets
    mk_bits_32_no_arch = False
    new_mk_bits = None
    new_targets = {}
    for t, u in iter(mk.targets.items()):
        # We do not know how to handle target with defined steps yet
        if len(u.str) > 1:
            continue
        # Amend typos
        if t == 'test' and u.value() == MK.value('NO_TEST'):
            print("001: Fix typo $(NO_TEST) -> $(NO_TESTS)")
            u.set_value(MK.value('NO_TESTS'))
        # Process target
        found = False
        for v in kw.targets[t]:
            v = MK.value(v.replace(MK.value("MK_BITS"), mk_bits))
            # If the target dependency is one of the default values
            if u.str[0] == v:
            if u.value() == v:
                found = True
                w = MK.target_value(t, mk_bits)
                #print(w)
                if v == w:
                    print("001: Use default target '"+t+"'")
                    u.str = None 
                else:
                    print("001: Define target '"+t+"': "+u.str[0])
                    print("001: Define target '"+t+"': "+u.value())
                    new_targets[t] = u
                break
        if not found:
            # Some Python/Perl makefiles actually use NO_ARCH target with MK_BITS=32
            if mk_bits == '32' and u.str[0] == MK.value(t.upper()+"_NO_ARCH"):
                if not mk_bits_32_no_arch:
                    print("001: Changing make bits from '32' to 'NO_ARCH'")
                    mk_bits_32_no_arch = True
                u.str = None
            # Some Python/Perl makefiles actually use NO_ARCH target with MK_BITS=32, or BITS was not set
            if mk_bits == '32' or mk_bits == '64':
                ok_bits = ( 'NO_ARCH', '64', '32_and_64', '64_and_32' )
                for b in ok_bits:
                    if u.value() == MK.target_value(t, b):
                        if not new_mk_bits:
                            new_mk_bits = b
                        elif b != new_mk_bits:
                            raise ValueError("001: Inconsistent target '"+t+"': "+u.value())
                        u.str = None
                        break
            else:
                raise ValueError("001: Inconsistent target '"+t+"': "+u.str[0])
    if mk_bits_32_no_arch:
        mk_bits = "NO_ARCH"
                raise ValueError("001: Unknown target '"+t+"' bitness: "+u.value())
    if new_mk_bits:
        print("001: Changing make bits from "+mk_bits+" to '"+new_mk_bits+"'")
        mk_bits = new_mk_bits
    # Collect items
    rem_lines = set()
    rem_includes = [ MK.makefile_path("prep"), MK.makefile_path("ips")]
@@ -127,7 +140,7 @@
            if i.value() == MK.makefile_path(build_style):
                i.set_value(MK.makefile_path("common"))
                include_common_mk = i
            elif re.match(r".*/shared-macros.mk$", i.str[0]):
            elif re.match(r".*/shared-macros.mk$", i.value()):
                include_shared_mk = i
            new_includes.append(i)
        else:
@@ -154,7 +167,7 @@
    # Write new targets
    for t  in ["build", "install", "test"]:
        if t in new_targets.keys():
            contents.append(Keywords.target_variable_assignment(t, new_targets[t].str[0]))
            contents.append(Keywords.target_variable_assignment(t, new_targets[t].value()))
            rem_lines.add(new_targets[t].line())
    # Add common include
    contents.append(include_common_mk.include_line())
@@ -178,6 +191,44 @@
    mk.update()
# Update rules
#-----------------------------------------------------------------------------
# U000: Update to default OpenSSL
#       If openssl is a dependency and the openssl package version is not set
#           1. update the dependency to the next openssl X.Y
#           2. add macros USE_OPENSSLXY to the makefile
def update000(mk):
    curr_version = '1.0'
    next_version = '1.1'
    curr_macro = 'USE_OPENSSL'+curr_version.replace('.','')
    next_macro = 'USE_OPENSSL'+next_version.replace('.','')
    curr_openssl_pkg = 'library/security/openssl'
    next_openssl_pkg = 'library/security/openssl-11'
    reqs = mk.required_packages()
    has_openssl_deps=False
    for p in reqs.split():
        if p == curr_openssl_pkg:
            has_openssl_deps=True
    if not has_openssl_deps:
        return
    # Check whether current version is enforced
    for line in iter(mk.contents):
        if re.match("^"+curr_macro+"[\s]*=[\s]*yes", line):
            return
    print("U000: update to next openssl")
    # Replace dependency
    for idx, line in enumerate(mk.contents):
        if re.match(r"REQUIRED_PACKAGES(.*)"+curr_openssl_pkg+"[\s]*$", line):
            mk.contents[idx] = line.replace(curr_openssl_pkg, next_openssl_pkg)
            break
    # Add macro before shared-macros
    include_shared_macros_mk = mk.get_mk_include('shared-macros')
    if not include_shared_macros_mk:
        raise ValueError('include shared_macros.mk not found')
    mk.set_variable(next_macro, 'yes', include_shared_macros_mk.line())
    mk.update()
#-----------------------------------------------------------------------------
# Update component makefile for revision or version bump 
def update_component(path, version, verbose):
@@ -186,6 +237,9 @@
    if version is None:
        return
    mk = MK(path)
    # Apply default update rules
    update000(mk)
    # Check current version
    if not mk.has_variable('COMPONENT_VERSION'):
        raise ValueError('COMPONENT_VERSION not found')
    newvers = str(version)