main.
()
| 98 | |
| 99 | |
| 100 | def main(): |
| 101 | """main.""" |
| 102 | args = get_args() |
| 103 | |
| 104 | # Pipe dumpbin to extract all linkable symbols from libs. |
| 105 | # Good symbols are collected in candidates and also written to |
| 106 | # a temp file. |
| 107 | candidates = [] |
| 108 | tmpfile = tempfile.NamedTemporaryFile(mode="w", delete=False) |
| 109 | for lib_path in args.input: |
| 110 | proc = subprocess.Popen([DUMPBIN, "/nologo", "/linkermember:1", lib_path], |
| 111 | stdout=subprocess.PIPE) |
| 112 | for line in codecs.getreader("utf-8")(proc.stdout): |
| 113 | cols = line.split() |
| 114 | if len(cols) < 2: |
| 115 | continue |
| 116 | sym = cols[1] |
| 117 | tmpfile.file.write(sym + "\n") |
| 118 | candidates.append(sym) |
| 119 | exit_code = proc.wait() |
| 120 | if exit_code != 0: |
| 121 | print("{} failed, exit={}".format(DUMPBIN, exit_code)) |
| 122 | return exit_code |
| 123 | tmpfile.file.close() |
| 124 | |
| 125 | # Run the symbols through undname to get their undecorated name |
| 126 | # so we can filter on something readable. |
| 127 | with open(args.output, "w") as def_fp: |
| 128 | # track dupes |
| 129 | taken = set() |
| 130 | |
| 131 | # Header for the def file. |
| 132 | def_fp.write("LIBRARY " + args.target + "\n") |
| 133 | def_fp.write("EXPORTS\n") |
| 134 | if args.bitness == "64": |
| 135 | def_fp.write("\t??1OpDef@tensorflow@@UEAA@XZ\n") |
| 136 | else: |
| 137 | def_fp.write("\t??1OpDef@tensorflow@@UAE@XZ\n") |
| 138 | |
| 139 | # Each symbols returned by undname matches the same position in candidates. |
| 140 | # We compare on undname but use the decorated name from candidates. |
| 141 | dupes = 0 |
| 142 | proc = subprocess.Popen([UNDNAME, tmpfile.name], stdout=subprocess.PIPE) |
| 143 | for idx, line in enumerate(codecs.getreader("utf-8")(proc.stdout)): |
| 144 | decorated = candidates[idx] |
| 145 | if decorated in taken: |
| 146 | # Symbol is already in output, done. |
| 147 | dupes += 1 |
| 148 | continue |
| 149 | |
| 150 | if not INCLUDEPRE_RE.search(line): |
| 151 | if EXCLUDE_RE.search(line): |
| 152 | continue |
| 153 | if not INCLUDE_RE.search(line): |
| 154 | continue |
| 155 | |
| 156 | if "deleting destructor" in line: |
| 157 | # Some of the symbols convered by INCLUDEPRE_RE export deleting |