| 
 | 1 | +#!/usr/bin/env python  | 
 | 2 | + | 
 | 3 | +# Copyright (c) 2017      IBM Corporation. All rights reserved.  | 
 | 4 | +# $COPYRIGHT$  | 
 | 5 | +#  | 
 | 6 | + | 
 | 7 | +import glob, os, re, shutil  | 
 | 8 | + | 
 | 9 | +projects= { 'opal' : [ "$(top_builddir)/opal/lib@[email protected]"],   | 
 | 10 | +           'orte' : [ "$(top_builddir)/orte/lib@[email protected]"],   | 
 | 11 | +           'ompi' : [ "$(top_builddir)/ompi/lib@[email protected]"],   | 
 | 12 | +           'oshmem' : ["$(top_builddir)/oshmem/liboshmem.la"],  | 
 | 13 | +          }  | 
 | 14 | + | 
 | 15 | +no_anchor_file = []  | 
 | 16 | +missing_files = []  | 
 | 17 | +skipped_files = []  | 
 | 18 | +partly_files = []  | 
 | 19 | +updated_files = []  | 
 | 20 | + | 
 | 21 | +#  | 
 | 22 | +# Check of all of the libadd fields are accounted for in the LIBADD  | 
 | 23 | +# Return a list indicating which are missing (positional)  | 
 | 24 | +#  | 
 | 25 | +def check_libadd(content, libadd_field, project):  | 
 | 26 | +    global projects  | 
 | 27 | + | 
 | 28 | +    libadd_list = projects[project]  | 
 | 29 | +    libadd_missing = [True] * len(libadd_list)  | 
 | 30 | + | 
 | 31 | +    on_libadd = False  | 
 | 32 | +    for line in content:  | 
 | 33 | +        # First libadd line  | 
 | 34 | +        if re.search( r"^\s*"+libadd_field, line):  | 
 | 35 | +            # If line continuation, then keep searching after this point  | 
 | 36 | +            if line[-2] == '\\':  | 
 | 37 | +                on_libadd = True  | 
 | 38 | + | 
 | 39 | +            for idx, lib in enumerate(libadd_list):  | 
 | 40 | +                if True == libadd_missing[idx]:  | 
 | 41 | +                    if 0 <= line.find(lib):  | 
 | 42 | +                        libadd_missing[idx] = False  | 
 | 43 | + | 
 | 44 | +        # Line continuation  | 
 | 45 | +        elif True == on_libadd:  | 
 | 46 | +            for idx, lib in enumerate(libadd_list):  | 
 | 47 | +                if True == libadd_missing[idx]:  | 
 | 48 | +                    if 0 <= line.find(lib):  | 
 | 49 | +                        libadd_missing[idx] = False  | 
 | 50 | + | 
 | 51 | +            # No more line continuations, so stop processing  | 
 | 52 | +            if line[-2] != '\\':  | 
 | 53 | +                on_libadd = False  | 
 | 54 | +                break  | 
 | 55 | +              | 
 | 56 | +    return libadd_missing  | 
 | 57 | + | 
 | 58 | +#  | 
 | 59 | +# Update all of the Makefile.am's with the proper LIBADD additions  | 
 | 60 | +#  | 
 | 61 | +def update_makefile_ams():  | 
 | 62 | +    global projects  | 
 | 63 | +    global no_anchor_file  | 
 | 64 | +    global missing_files  | 
 | 65 | +    global skipped_files  | 
 | 66 | +    global partly_files  | 
 | 67 | +    global updated_files  | 
 | 68 | + | 
 | 69 | +    for project, libadd_list in projects.items():  | 
 | 70 | +        libadd_str = " \\\n\t".join(libadd_list)  | 
 | 71 | +          | 
 | 72 | +        print("="*40)  | 
 | 73 | +        print("Project: "+project)  | 
 | 74 | +        print("LIBADD:\n"+libadd_str)  | 
 | 75 | +        print("="*40)  | 
 | 76 | +          | 
 | 77 | +        #  | 
 | 78 | +        # Walk the directory structure  | 
 | 79 | +        #  | 
 | 80 | +        for root, dirs, files in os.walk(project+"/mca"):  | 
 | 81 | +            parts = root.split("/")  | 
 | 82 | +            if len(parts) != 4:  | 
 | 83 | +                continue  | 
 | 84 | +            if parts[-1] == ".libs" or parts[-1] == ".deps" or parts[-1] == "base":  | 
 | 85 | +                continue  | 
 | 86 | +            if parts[2] == "common":  | 
 | 87 | +                continue  | 
 | 88 | + | 
 | 89 | +            print("Processing: "+root)  | 
 | 90 | + | 
 | 91 | +            #  | 
 | 92 | +            # Find Makefile.am  | 
 | 93 | +            #  | 
 | 94 | +            make_filename = os.path.join(root, "Makefile.am")  | 
 | 95 | +            if False == os.path.isfile( make_filename ):  | 
 | 96 | +                missing_files.append("Missing: "+make_filename)  | 
 | 97 | +                print("  ---> Error: "+make_filename+" is not present in this directory")  | 
 | 98 | +                continue  | 
 | 99 | + | 
 | 100 | +            #  | 
 | 101 | +            # Stearching for: mca_FRAMEWORK_COMPONENT_la_{LIBADD|LDFLAGS}  | 
 | 102 | +            # First scan file to see if it has an LIBADD / LDFLAGS  | 
 | 103 | +            #  | 
 | 104 | +            libadd_field  = "mca_"+parts[2]+"_"+parts[3]+"_la_LIBADD"  | 
 | 105 | +            ldflags_field = "mca_"+parts[2]+"_"+parts[3]+"_la_LDFLAGS"  | 
 | 106 | +            has_ldflags = False  | 
 | 107 | +            has_libadd  = False  | 
 | 108 | +              | 
 | 109 | +            r_fd = open(make_filename, 'r')  | 
 | 110 | +            orig_content = r_fd.readlines()  | 
 | 111 | +            r_fd.close()  | 
 | 112 | +            libadd_missing = []  | 
 | 113 | +              | 
 | 114 | +            for line in orig_content:  | 
 | 115 | +                if re.search( r"^\s*"+ldflags_field, line):  | 
 | 116 | +                    has_ldflags = True  | 
 | 117 | +                elif re.search( r"^\s*"+libadd_field, line):  | 
 | 118 | +                    has_libadd = True  | 
 | 119 | + | 
 | 120 | +            if True == has_libadd:  | 
 | 121 | +                libadd_missing = check_libadd(orig_content, libadd_field, project)  | 
 | 122 | + | 
 | 123 | +            #  | 
 | 124 | +            # Sanity Check: Was there an anchor field.  | 
 | 125 | +            # If not skip, we might need to manually update or it might be a  | 
 | 126 | +            # static component.  | 
 | 127 | +            #  | 
 | 128 | +            if False == has_ldflags and False == has_libadd:  | 
 | 129 | +                no_anchor_file.append("No anchor ("+ldflags_field+"): "+make_filename)  | 
 | 130 | +                print("  ---> Error: Makefile.am does not contain necessary anchor")  | 
 | 131 | +                continue  | 
 | 132 | + | 
 | 133 | +            #  | 
 | 134 | +            # Sanity Check: This file does not need to be updated.  | 
 | 135 | +            #  | 
 | 136 | +            if True == has_libadd and all(False == v for v in libadd_missing):  | 
 | 137 | +                skipped_files.append("Skip: "+make_filename)  | 
 | 138 | +                print("       Skip: Already updated Makefile.am")  | 
 | 139 | +                continue  | 
 | 140 | + | 
 | 141 | +            #  | 
 | 142 | +            # Now go though and create a new version of the Makefile.am  | 
 | 143 | +            #  | 
 | 144 | +            r_fd = open(make_filename, 'r')  | 
 | 145 | +            w_fd = open(make_filename+".mod", 'w')  | 
 | 146 | + | 
 | 147 | +            num_libadds=0  | 
 | 148 | +            for line in r_fd:  | 
 | 149 | +                # LDFLAGS anchor  | 
 | 150 | +                if re.search( r"^\s*"+ldflags_field, line):  | 
 | 151 | +                    w_fd.write(line)  | 
 | 152 | +                    # If there is no LIBADD, then put it after the LDFLAGS  | 
 | 153 | +                    if False == has_libadd:  | 
 | 154 | +                        w_fd.write(libadd_field+" = "+libadd_str+"\n")  | 
 | 155 | +                # Existing LIBADD field to extend  | 
 | 156 | +                elif 0 == num_libadds and re.search( r"^\s*"+libadd_field, line):  | 
 | 157 | +                    parts = line.partition("=")  | 
 | 158 | +                    num_libadds += 1  | 
 | 159 | +                    if parts[0][-1] == '+':  | 
 | 160 | +                        w_fd.write(libadd_field+" += ")  | 
 | 161 | +                    else:  | 
 | 162 | +                        w_fd.write(libadd_field+" = ")  | 
 | 163 | + | 
 | 164 | +                    # If all libs are missing, then add the full string  | 
 | 165 | +                    # Otherwise only add the missing items  | 
 | 166 | +                    if all(True == v for v in libadd_missing):  | 
 | 167 | +                        w_fd.write(libadd_str+" \\\n")  | 
 | 168 | +                    else:  | 
 | 169 | +                        partly_files.append("Partly updated: "+make_filename)  | 
 | 170 | +                        for idx, lib in enumerate(libadd_list):  | 
 | 171 | +                            if True == libadd_missing[idx]:  | 
 | 172 | +                                w_fd.write(lib+" \\\n")  | 
 | 173 | + | 
 | 174 | +                    # Original content (unless it's just a line continuation)  | 
 | 175 | +                    if None == re.search( r"^\s*\\$", parts[2].lstrip() ):  | 
 | 176 | +                        w_fd.write("\t"+parts[2].lstrip())  | 
 | 177 | + | 
 | 178 | +                # Non matching line, just echo  | 
 | 179 | +                else:  | 
 | 180 | +                    w_fd.write(line)  | 
 | 181 | + | 
 | 182 | +            r_fd.close()  | 
 | 183 | +            w_fd.close()  | 
 | 184 | + | 
 | 185 | +            #  | 
 | 186 | +            # Replace the original with the updated version  | 
 | 187 | +            #  | 
 | 188 | +            shutil.move(make_filename+".mod", make_filename)  | 
 | 189 | +            updated_files.append(make_filename)  | 
 | 190 | + | 
 | 191 | +          | 
 | 192 | +if __name__ == "__main__":  | 
 | 193 | + | 
 | 194 | +    update_makefile_ams()  | 
 | 195 | + | 
 | 196 | +    print("")  | 
 | 197 | + | 
 | 198 | +    print("="*40);  | 
 | 199 | +    print("{:>3} : Files skipped".format(len(skipped_files)))  | 
 | 200 | +    print("="*40);  | 
 | 201 | + | 
 | 202 | +    print("="*40);  | 
 | 203 | +    print("{:>3} : Files updated, but had some libs already in place.".format(str(len(partly_files))))  | 
 | 204 | +    print("="*40);  | 
 | 205 | +    for fn in partly_files:  | 
 | 206 | +        print(fn)  | 
 | 207 | +          | 
 | 208 | +    print("="*40);  | 
 | 209 | +    print("{:>3} : Files fully updated".format(str(len(updated_files))))  | 
 | 210 | +    print("="*40);  | 
 | 211 | +    for fn in updated_files:  | 
 | 212 | +        print(fn)  | 
 | 213 | + | 
 | 214 | +    print("="*40);  | 
 | 215 | +    print("{:>3} : Missing Makefile.am".format(str(len(missing_files))))  | 
 | 216 | +    print("="*40);  | 
 | 217 | +    for err in missing_files:  | 
 | 218 | +        print(err)  | 
 | 219 | + | 
 | 220 | +    print("="*40);  | 
 | 221 | +    print("{:>3} : Missing Anchor for parsing (might be static-only components)".format(str(len(no_anchor_file))))  | 
 | 222 | +    print("="*40);  | 
 | 223 | +    for err in no_anchor_file:  | 
 | 224 | +        print(err)  | 
 | 225 | + | 
0 commit comments