tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

get_vs.py (4310B)


      1 #!/usr/bin/env python3
      2 # This Source Code Form is subject to the terms of the Mozilla Public
      3 # License, v. 2.0. If a copy of the MPL was not distributed with this
      4 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
      5 
      6 import argparse
      7 import os
      8 import shutil
      9 import ssl
     10 from pathlib import Path
     11 from tempfile import TemporaryDirectory
     12 from urllib import request
     13 
     14 import certifi
     15 import yaml
     16 from buildconfig import topsrcdir
     17 from vsdownload import downloadPackages, extractPackages
     18 
     19 # Hack to hook certifi
     20 _urlopen = request.urlopen
     21 
     22 
     23 def urlopen(url, data=None):
     24    return _urlopen(
     25        url, data, context=ssl.create_default_context(cafile=certifi.where())
     26    )
     27 
     28 
     29 request.urlopen = urlopen
     30 
     31 
     32 if __name__ == "__main__":
     33    parser = argparse.ArgumentParser(
     34        description="Download and build a Visual Studio artifact"
     35    )
     36    parser.add_argument("manifest", help="YAML manifest of the contents to download")
     37    parser.add_argument("outdir", help="Output directory")
     38    args = parser.parse_args()
     39 
     40    out_dir = Path(args.outdir)
     41    with open(Path(topsrcdir) / args.manifest) as f:
     42        selected = yaml.safe_load(f.read())
     43    with TemporaryDirectory(prefix="get_vs", dir=".") as tmpdir:
     44        tmpdir = Path(tmpdir)
     45        dl_cache = tmpdir / "cache"
     46        downloadPackages(selected, dl_cache)
     47        unpacked = tmpdir / "unpack"
     48        extractPackages(selected, dl_cache, unpacked)
     49        vfs = {}
     50        # Fill the output directory with all the paths in lowercase form for
     51        # cross-compiles.
     52        for subpath in ("VC", "Windows Kits/10", "DIA SDK"):
     53            dest = subpath
     54            # When running on Windows, SDK files are extracted under Windows Kits,
     55            # but on other platforms, they end up in Program Files/Windows Kits.
     56            program_files_subpath = unpacked / "Program Files" / subpath
     57            if program_files_subpath.exists():
     58                subpath = program_files_subpath
     59            else:
     60                subpath = unpacked / subpath
     61            dest = Path(dest)
     62            for root, dirs, files in os.walk(subpath):
     63                relpath = Path(root).relative_to(subpath)
     64                for f in files:
     65                    path = Path(root) / f
     66                    mode = os.stat(path).st_mode
     67                    with open(path, "rb") as fh:
     68                        lower_f = f.lower()
     69                        # Ideally, we'd use the overlay for .libs too but as of
     70                        # writing it's still impractical to use, so lowercase
     71                        # them for now, that'll be enough.
     72                        if lower_f.endswith(".lib"):
     73                            f = lower_f
     74                        name = str(dest / relpath / f)
     75                        # Set executable flag on .exe files, the Firefox build
     76                        # system wants it.
     77                        if lower_f.endswith(".exe"):
     78                            mode |= (mode & 0o444) >> 2
     79                        print("Adding", name)
     80                        out_file = out_dir / name
     81                        out_file.parent.mkdir(parents=True, exist_ok=True)
     82                        with out_file.open("wb") as out_fh:
     83                            shutil.copyfileobj(fh, out_fh)
     84                        os.chmod(out_file, mode)
     85                        if lower_f.endswith((".h", ".idl")):
     86                            vfs.setdefault(str(dest / relpath), []).append(f)
     87        # Create an overlay file for use with clang's -ivfsoverlay flag.
     88        overlay = {
     89            "version": 0,
     90            "case-sensitive": False,
     91            "root-relative": "overlay-dir",
     92            "overlay-relative": True,
     93            "roots": [
     94                {
     95                    "name": p,
     96                    "type": "directory",
     97                    "contents": [
     98                        {
     99                            "name": f,
    100                            "type": "file",
    101                            "external-contents": f"{p}/{f}",
    102                        }
    103                        for f in files
    104                    ],
    105                }
    106                for p, files in vfs.items()
    107            ],
    108        }
    109        overlay_yaml = out_dir / "overlay.yaml"
    110        with overlay_yaml.open("w") as fh:
    111            fh.write(yaml.dump(overlay))