def bootstrap_rustc(self, force=False): rust_dir = path.join(self.context.sharedir, "rust", self.rust_path()) if not force and path.exists( path.join(rust_dir, "rustc", "bin", "rustc")): print("Rust compiler already downloaded.", end=" ") print("Use |bootstrap-rust --force| to download again.") return if path.isdir(rust_dir): shutil.rmtree(rust_dir) os.makedirs(rust_dir) date = self.rust_path().split("/")[0] install_dir = path.join(self.context.sharedir, "rust", date) # The Rust compiler is hosted on the nightly server under the date with a name # rustc-nightly-HOST-TRIPLE.tar.gz. We just need to pull down and extract it, # giving a directory name that will be the same as the tarball name (rustc is # in that directory). rustc_url = ( "https://static-rust-lang-org.s3.amazonaws.com/dist/%s.tar.gz" % self.rust_path()) tgz_file = rust_dir + '-rustc.tar.gz' download_file("Rust compiler", rustc_url, tgz_file) print("Extracting Rust compiler...") extract(tgz_file, install_dir) # Each Rust stdlib has a name of the form `rust-std-nightly-TRIPLE.tar.gz`, with # a directory of the name `rust-std-TRIPLE` inside and then a `lib` directory. # This `lib` directory needs to be extracted and merged with the `rustc/lib` # directory from the host compiler above. # TODO: make it possible to request an additional cross-target to add to this # list. stdlibs = [host_triple(), "arm-linux-androideabi"] for target in stdlibs: std_url = ( "https://static-rust-lang-org.s3.amazonaws.com/dist/%s/rust-std-nightly-%s.tar.gz" % (date, target)) tgz_file = install_dir + ('rust-std-nightly-%s.tar.gz' % target) download_file("Host rust library for target %s" % target, std_url, tgz_file) print("Extracting Rust stdlib for target %s..." % target) extract(tgz_file, install_dir) shutil.copytree( path.join(install_dir, "rust-std-nightly-%s" % target, "rust-std-%s" % target, "lib", "rustlib", target), path.join(install_dir, "rustc-nightly-%s" % host_triple(), "rustc", "lib", "rustlib", target)) shutil.rmtree( path.join(install_dir, "rust-std-nightly-%s" % target)) print("Rust ready.")
def bootstrap_rustc(self, force=False): rust_dir = path.join( self.context.sharedir, "rust", self.rust_snapshot_path()) if not force and path.exists(path.join(rust_dir, "rustc", "bin", "rustc")): print("Snapshot Rust compiler already downloaded.", end=" ") print("Use |bootstrap-rust --force| to download again.") return if path.isdir(rust_dir): shutil.rmtree(rust_dir) os.makedirs(rust_dir) date = self.rust_snapshot_path().split("/")[0] install_dir = path.join(self.context.sharedir, "rust", date) # The Rust compiler is hosted on the nightly server under the date with a name # rustc-nightly-HOST-TRIPLE.tar.gz. We just need to pull down and extract it, # giving a directory name that will be the same as the tarball name (rustc is # in that directory). snapshot_url = ("https://static-rust-lang-org.s3.amazonaws.com/dist/%s.tar.gz" % self.rust_snapshot_path()) tgz_file = rust_dir + '-rustc.tar.gz' download_file("Rust compiler", snapshot_url, tgz_file) print("Extracting Rust compiler...") extract(tgz_file, install_dir) # Each Rust stdlib has a name of the form `rust-std-nightly-TRIPLE.tar.gz`, with # a directory of the name `rust-std-TRIPLE` inside and then a `lib` directory. # This `lib` directory needs to be extracted and merged with the `rustc/lib` # directory from the host compiler above. # TODO: make it possible to request an additional cross-target to add to this # list. stdlibs = [host_triple(), "arm-linux-androideabi"] for target in stdlibs: snapshot_url = ("https://static-rust-lang-org.s3.amazonaws.com/dist/%s/rust-std-nightly-%s.tar.gz" % (date, target)) tgz_file = install_dir + ('rust-std-nightly-%s.tar.gz' % target) download_file("Host rust library for target %s" % target, snapshot_url, tgz_file) print("Extracting Rust stdlib for target %s..." % target) extract(tgz_file, install_dir) shutil.copytree(path.join(install_dir, "rust-std-nightly-%s" % target, "rust-std-%s" % target, "lib", "rustlib", target), path.join(install_dir, "rustc-nightly-%s" % host_triple(), "rustc", "lib", "rustlib", target)) shutil.rmtree(path.join(install_dir, "rust-std-nightly-%s" % target)) print("Snapshot Rust ready.")
def bootstrap_rustc_docs(self, force=False): self.ensure_bootstrapped() rust_root = self.config["tools"]["rust-root"] docs_dir = path.join(rust_root, "doc") if not force and path.exists(docs_dir): print("Snapshot Rust docs already downloaded.", end=" ") print("Use |bootstrap-rust-docs --force| to download again.") return if path.isdir(docs_dir): shutil.rmtree(docs_dir) docs_name = self.rust_snapshot_path().replace("rustc-", "rust-docs-") snapshot_url = ("https://static-rust-lang-org.s3.amazonaws.com/dist/rust-docs-nightly-%s.tar.gz" % host_triple()) tgz_file = path.join(rust_root, 'doc.tar.gz') download_file("Rust docs", snapshot_url, tgz_file) print("Extracting Rust docs...") temp_dir = path.join(rust_root, "temp_docs") if path.isdir(temp_dir): shutil.rmtree(temp_dir) extract(tgz_file, temp_dir) shutil.move(path.join(temp_dir, docs_name.split("/")[1], "rust-docs", "share", "doc", "rust", "html"), docs_dir) shutil.rmtree(temp_dir) print("Rust docs ready.")
def bootstrap_rustc_docs(self, force=False): self.ensure_bootstrapped() rust_root = self.config["tools"]["rust-root"] docs_dir = path.join(rust_root, "doc") if not force and path.exists(docs_dir): print("Rust docs already downloaded.", end=" ") print("Use |bootstrap-rust-docs --force| to download again.") return if path.isdir(docs_dir): shutil.rmtree(docs_dir) docs_name = self.rust_path().replace("rustc-", "rust-docs-") docs_url = ( "https://static-rust-lang-org.s3.amazonaws.com/dist/rust-docs-nightly-%s.tar.gz" % host_triple()) tgz_file = path.join(rust_root, 'doc.tar.gz') download_file("Rust docs", docs_url, tgz_file) print("Extracting Rust docs...") temp_dir = path.join(rust_root, "temp_docs") if path.isdir(temp_dir): shutil.rmtree(temp_dir) extract(tgz_file, temp_dir) shutil.move( path.join(temp_dir, docs_name.split("/")[1], "rust-docs", "share", "doc", "rust", "html"), docs_dir) shutil.rmtree(temp_dir) print("Rust docs ready.")
def test_unit(self, test_name=None, package=None): if test_name is None: test_name = [] self.ensure_bootstrapped() if package: packages = {package} else: packages = set() test_patterns = [] for test in test_name: # add package if 'tests/unit/<package>' match = re.search("tests/unit/(\\w+)/?$", test) if match: packages.add(match.group(1)) # add package & test if '<package>/<test>', 'tests/unit/<package>/<test>.rs', or similar elif re.search("\\w/\\w", test): tokens = test.split("/") packages.add(tokens[-2]) test_prefix = tokens[-1] if test_prefix.endswith(".rs"): test_prefix = test_prefix[:-3] test_prefix += "::" test_patterns.append(test_prefix) # add test as-is otherwise else: test_patterns.append(test) if not packages: packages = set( os.listdir(path.join(self.context.topdir, "tests", "unit"))) args = ["cargo", "test"] for crate in packages: args += ["-p", "%s_tests" % crate] args += test_patterns features = self.servo_features() if features: args += ["--features", "%s" % ' '.join(features)] env = self.build_env() env["RUST_BACKTRACE"] = "1" if sys.platform in ("win32", "msys"): if "msvc" in host_triple(): # on MSVC, we need some DLLs in the path. They were copied # in to the servo.exe build dir, so just point PATH to that. env["PATH"] = "%s%s%s" % (path.dirname( self.get_binary_path(False, False)), os.pathsep, env["PATH"]) else: env["RUSTFLAGS"] = "-C link-args=-Wl,--subsystem,windows" result = call(args, env=env, cwd=self.servo_crate()) if result != 0: return result
def test_unit(self, test_name=None, package=None): if test_name is None: test_name = [] self.ensure_bootstrapped() if package: packages = {package} else: packages = set() test_patterns = [] for test in test_name: # add package if 'tests/unit/<package>' match = re.search("tests/unit/(\\w+)/?$", test) if match: packages.add(match.group(1)) # add package & test if '<package>/<test>', 'tests/unit/<package>/<test>.rs', or similar elif re.search("\\w/\\w", test): tokens = test.split("/") packages.add(tokens[-2]) test_prefix = tokens[-1] if test_prefix.endswith(".rs"): test_prefix = test_prefix[:-3] test_prefix += "::" test_patterns.append(test_prefix) # add test as-is otherwise else: test_patterns.append(test) if not packages: packages = set(os.listdir(path.join(self.context.topdir, "tests", "unit"))) packages.remove('stylo') args = ["cargo", "test"] for crate in packages: args += ["-p", "%s_tests" % crate] args += test_patterns features = self.servo_features() if features: args += ["--features", "%s" % ' '.join(features)] env = self.build_env() env["RUST_BACKTRACE"] = "1" if sys.platform in ("win32", "msys"): if "msvc" in host_triple(): # on MSVC, we need some DLLs in the path. They were copied # in to the servo.exe build dir, so just point PATH to that. env["PATH"] = "%s%s%s" % (path.dirname(self.get_binary_path(False, False)), os.pathsep, env["PATH"]) else: env["RUSTFLAGS"] = "-C link-args=-Wl,--subsystem,windows" result = call(args, env=env, cwd=self.servo_crate()) if result != 0: return result
def bootstrap_cargo(self, force=False): cargo_dir = path.join(self.context.topdir, "cargo") if not force and path.exists(path.join(cargo_dir, "bin", "cargo")): print("Cargo already downloaded.", end=" ") print("Use |bootstrap_cargo --force| to download again.") return if path.isdir(cargo_dir): shutil.rmtree(cargo_dir) os.mkdir(cargo_dir) tgz_file = "cargo-nightly-%s.tar.gz" % host_triple() nightly_url = "http://static.rust-lang.org/cargo-dist/%s" % tgz_file download("Cargo nightly", nightly_url, tgz_file) print("Extracting Cargo nightly...") nightly_dir = path.join(cargo_dir, path.basename(tgz_file).replace(".tar.gz", "")) extract(tgz_file, cargo_dir, movedir=nightly_dir) print("Cargo ready.")
def bootstrap_cargo(self, force=False): cargo_dir = path.join(self.context.topdir, "cargo") if not force and path.exists(path.join(cargo_dir, "bin", "cargo")): print("Cargo already downloaded.", end=" ") print("Use |bootstrap_cargo --force| to download again.") return if path.isdir(cargo_dir): shutil.rmtree(cargo_dir) os.mkdir(cargo_dir) tgz_file = "cargo-nightly-%s.tar.gz" % host_triple() # FIXME(#3582): use https. nightly_url = "http://static.rust-lang.org/cargo-dist/2014-10-21/%s" % tgz_file download("Cargo nightly", nightly_url, tgz_file) print("Extracting Cargo nightly...") nightly_dir = path.join(cargo_dir, path.basename(tgz_file).replace(".tar.gz", "")) extract(tgz_file, cargo_dir, movedir=nightly_dir) print("Cargo ready.")
def bootstrap_cargo(self, force=False): cargo_dir = path.join(self.context.sharedir, "cargo", self.cargo_build_id()) if not force and path.exists(path.join(cargo_dir, "bin", "cargo")): print("Cargo already downloaded.", end=" ") print("Use |bootstrap-cargo --force| to download again.") return if path.isdir(cargo_dir): shutil.rmtree(cargo_dir) os.makedirs(cargo_dir) tgz_file = "cargo-nightly-%s.tar.gz" % host_triple() nightly_url = "https://static-rust-lang-org.s3.amazonaws.com/cargo-dist/%s/%s" % \ (self.cargo_build_id(), tgz_file) download_file("Cargo nightly", nightly_url, tgz_file) print("Extracting Cargo nightly...") nightly_dir = path.join(cargo_dir, path.basename(tgz_file).replace(".tar.gz", "")) extract(tgz_file, cargo_dir, movedir=nightly_dir) print("Cargo ready.")
def bootstrap_rustc(self, force=False, target=[]): rust_dir = path.join( self.context.sharedir, "rust", self.rust_path()) date = self.rust_path().split("/")[0] install_dir = path.join(self.context.sharedir, "rust", date) if not force and path.exists(path.join(rust_dir, "rustc", "bin", "rustc" + BIN_SUFFIX)): print("Rust compiler already downloaded.", end=" ") print("Use |bootstrap-rust --force| to download again.") else: if path.isdir(rust_dir): shutil.rmtree(rust_dir) os.makedirs(rust_dir) # The Rust compiler is hosted on the nightly server under the date with a name # rustc-nightly-HOST-TRIPLE.tar.gz. We just need to pull down and extract it, # giving a directory name that will be the same as the tarball name (rustc is # in that directory). rustc_url = ("https://static-rust-lang-org.s3.amazonaws.com/dist/%s.tar.gz" % self.rust_path()) tgz_file = rust_dir + '-rustc.tar.gz' download_file("Rust compiler", rustc_url, tgz_file) print("Extracting Rust compiler...") extract(tgz_file, install_dir) print("Rust compiler ready.") # Each Rust stdlib has a name of the form `rust-std-nightly-TRIPLE.tar.gz`, with # a directory of the name `rust-std-TRIPLE` inside and then a `lib` directory. # This `lib` directory needs to be extracted and merged with the `rustc/lib` # directory from the host compiler above. lib_dir = path.join(install_dir, "rustc-nightly-{}".format(host_triple()), "rustc", "lib", "rustlib") # ensure that the libs for the host's target is downloaded host_target = host_triple() if host_target not in target: target.append(host_target) for target_triple in target: target_lib_dir = path.join(lib_dir, target_triple) if path.exists(target_lib_dir): # No need to check for force. If --force the directory is already deleted print("Rust lib for target {} already downloaded.".format(target_triple), end=" ") print("Use |bootstrap-rust --force| to download again.") continue std_url = ("https://static-rust-lang-org.s3.amazonaws.com/dist/%s/rust-std-nightly-%s.tar.gz" % (date, target_triple)) tgz_file = install_dir + ('rust-std-nightly-%s.tar.gz' % target_triple) download_file("Host rust library for target %s" % target_triple, std_url, tgz_file) print("Extracting Rust stdlib for target %s..." % target_triple) extract(tgz_file, install_dir) shutil.copytree(path.join(install_dir, "rust-std-nightly-%s" % target_triple, "rust-std-%s" % target_triple, "lib", "rustlib", target_triple), path.join(install_dir, "rustc-nightly-%s" % host_triple(), "rustc", "lib", "rustlib", target_triple)) shutil.rmtree(path.join(install_dir, "rust-std-nightly-%s" % target_triple)) print("Rust {} libs ready.".format(target_triple))
def bootstrap_rustc(self, force=False, target=[]): rust_dir = path.join(self.context.sharedir, "rust", self.rust_path()) date = self.rust_path().split("/")[0] install_dir = path.join(self.context.sharedir, "rust", date) if not force and path.exists( path.join(rust_dir, "rustc", "bin", "rustc" + BIN_SUFFIX)): print("Rust compiler already downloaded.", end=" ") print("Use |bootstrap-rust --force| to download again.") else: if path.isdir(rust_dir): shutil.rmtree(rust_dir) os.makedirs(rust_dir) # The Rust compiler is hosted on the nightly server under the date with a name # rustc-nightly-HOST-TRIPLE.tar.gz. We just need to pull down and extract it, # giving a directory name that will be the same as the tarball name (rustc is # in that directory). rustc_url = ( "https://static-rust-lang-org.s3.amazonaws.com/dist/%s.tar.gz" % self.rust_path()) tgz_file = rust_dir + '-rustc.tar.gz' download_file("Rust compiler", rustc_url, tgz_file) print("Extracting Rust compiler...") extract(tgz_file, install_dir) print("Rust compiler ready.") # Each Rust stdlib has a name of the form `rust-std-nightly-TRIPLE.tar.gz`, with # a directory of the name `rust-std-TRIPLE` inside and then a `lib` directory. # This `lib` directory needs to be extracted and merged with the `rustc/lib` # directory from the host compiler above. lib_dir = path.join(install_dir, "rustc-nightly-{}".format(host_triple()), "rustc", "lib", "rustlib") # ensure that the libs for the host's target is downloaded host_target = host_triple() if host_target not in target: target.append(host_target) for target_triple in target: target_lib_dir = path.join(lib_dir, target_triple) if path.exists(target_lib_dir): # No need to check for force. If --force the directory is already deleted print("Rust lib for target {} already downloaded.".format( target_triple), end=" ") print("Use |bootstrap-rust --force| to download again.") continue std_url = ( "https://static-rust-lang-org.s3.amazonaws.com/dist/%s/rust-std-nightly-%s.tar.gz" % (date, target_triple)) tgz_file = install_dir + ('rust-std-nightly-%s.tar.gz' % target_triple) download_file("Host rust library for target %s" % target_triple, std_url, tgz_file) print("Extracting Rust stdlib for target %s..." % target_triple) extract(tgz_file, install_dir) shutil.copytree( path.join(install_dir, "rust-std-nightly-%s" % target_triple, "rust-std-%s" % target_triple, "lib", "rustlib", target_triple), path.join(install_dir, "rustc-nightly-%s" % host_triple(), "rustc", "lib", "rustlib", target_triple)) shutil.rmtree( path.join(install_dir, "rust-std-nightly-%s" % target_triple)) print("Rust {} libs ready.".format(target_triple))
def bootstrap_rustc(self, force=False, target=[], stable=False): self.set_use_stable_rust(stable) version = self.rust_version() rust_path = self.rust_path() rust_dir = path.join(self.context.sharedir, "rust", rust_path) install_dir = path.join(self.context.sharedir, "rust", version) if not force and path.exists( path.join(rust_dir, "rustc", "bin", "rustc" + BIN_SUFFIX)): print("Rust compiler already downloaded.", end=" ") print("Use |bootstrap-rust --force| to download again.") else: if path.isdir(rust_dir): shutil.rmtree(rust_dir) os.makedirs(rust_dir) # The nightly Rust compiler is hosted on the nightly server under the date with a name # rustc-nightly-HOST-TRIPLE.tar.gz, whereas the stable compiler is named # rustc-VERSION-HOST-TRIPLE.tar.gz. We just need to pull down and extract it, # giving a directory name that will be the same as the tarball name (rustc is # in that directory). if stable: tarball = "rustc-%s-%s.tar.gz" % (version, host_triple()) else: tarball = "%s/rustc-nightly-%s.tar.gz" % (version, host_triple()) rustc_url = "https://static-rust-lang-org.s3.amazonaws.com/dist/" + tarball tgz_file = rust_dir + '-rustc.tar.gz' download_file("Rust compiler", rustc_url, tgz_file) print("Extracting Rust compiler...") extract(tgz_file, install_dir) print("Rust compiler ready.") # Each Rust stdlib has a name of the form `rust-std-nightly-TRIPLE.tar.gz` for the nightly # releases, or rust-std-VERSION-TRIPLE.tar.gz for stable releases, with # a directory of the name `rust-std-TRIPLE` inside and then a `lib` directory. # This `lib` directory needs to be extracted and merged with the `rustc/lib` # directory from the host compiler above. nightly_suffix = "" if stable else "-nightly" stable_version = "-{}".format(version) if stable else "" lib_dir = path.join( install_dir, "rustc{}{}-{}".format(nightly_suffix, stable_version, host_triple()), "rustc", "lib", "rustlib") # ensure that the libs for the host's target is downloaded host_target = host_triple() if host_target not in target: target.append(host_target) for target_triple in target: target_lib_dir = path.join(lib_dir, target_triple) if path.exists(target_lib_dir): # No need to check for force. If --force the directory is already deleted print("Rust lib for target {} already downloaded.".format( target_triple), end=" ") print("Use |bootstrap-rust --force| to download again.") continue if self.use_stable_rust(): std_url = ( "https://static-rust-lang-org.s3.amazonaws.com/dist/rust-std-%s-%s.tar.gz" % (version, target_triple)) tgz_file = install_dir + ('rust-std-%s-%s.tar.gz' % (version, target_triple)) else: std_url = ( "https://static-rust-lang-org.s3.amazonaws.com/dist/%s/rust-std-nightly-%s.tar.gz" % (version, target_triple)) tgz_file = install_dir + ('rust-std-nightly-%s.tar.gz' % target_triple) download_file("Host rust library for target %s" % target_triple, std_url, tgz_file) print("Extracting Rust stdlib for target %s..." % target_triple) extract(tgz_file, install_dir) shutil.copytree( path.join( install_dir, "rust-std%s%s-%s" % (nightly_suffix, stable_version, target_triple), "rust-std-%s" % target_triple, "lib", "rustlib", target_triple), path.join( install_dir, "rustc%s%s-%s" % (nightly_suffix, stable_version, host_triple()), "rustc", "lib", "rustlib", target_triple)) shutil.rmtree( path.join( install_dir, "rust-std%s%s-%s" % (nightly_suffix, stable_version, target_triple))) print("Rust {} libs ready.".format(target_triple))
def build(self, target=None, release=False, dev=False, jobs=None, features=None, android=None, verbose=False, debug_mozjs=False, params=None): if android is None: android = self.config["build"]["android"] features = features or self.servo_features() opts = params or [] base_path = self.get_target_dir() release_path = path.join(base_path, "release", "servo") dev_path = path.join(base_path, "debug", "servo") release_exists = path.exists(release_path) dev_exists = path.exists(dev_path) if not (release or dev): if self.config["build"]["mode"] == "dev": dev = True elif self.config["build"]["mode"] == "release": release = True elif release_exists and not dev_exists: release = True elif dev_exists and not release_exists: dev = True else: print("Please specify either --dev (-d) for a development") print(" build, or --release (-r) for an optimized build.") sys.exit(1) if release and dev: print("Please specify either --dev or --release.") sys.exit(1) if target and android: print("Please specify either --target or --android.") sys.exit(1) if release: opts += ["--release"] servo_path = release_path else: servo_path = dev_path if jobs is not None: opts += ["-j", jobs] if verbose: opts += ["-v"] if android: target = self.config["android"]["target"] if target: opts += ["--target", target] self.ensure_bootstrapped(target=target) if debug_mozjs: features += ["script/debugmozjs"] if features: opts += ["--features", "%s" % ' '.join(features)] build_start = time() env = self.build_env(target=target, is_build=True) # TODO: If this ends up making it, we should probably add a # --release-with-debug-assertions option or similar, so it's easier to # build locally. if env.get("SERVO_ENABLE_DEBUG_ASSERTIONS", None): env["RUSTFLAGS"] = "-C debug_assertions" if android: # Build OpenSSL for android make_cmd = ["make"] if jobs is not None: make_cmd += ["-j" + jobs] android_dir = self.android_build_dir(dev) openssl_dir = path.join(android_dir, "native", "openssl") if not path.exists(openssl_dir): os.makedirs(openssl_dir) shutil.copy( path.join(self.android_support_dir(), "openssl.makefile"), openssl_dir) shutil.copy(path.join(self.android_support_dir(), "openssl.sh"), openssl_dir) with cd(openssl_dir): status = call(make_cmd + ["-f", "openssl.makefile"], env=env, verbose=verbose) if status: return status openssl_dir = path.join(openssl_dir, "openssl-1.0.1t") env['OPENSSL_LIB_DIR'] = openssl_dir env['OPENSSL_INCLUDE_DIR'] = path.join(openssl_dir, "include") env['OPENSSL_STATIC'] = 'TRUE' cargo_binary = "cargo" + BIN_SUFFIX if sys.platform in ("win32", "msys"): if "msvc" not in host_triple(): env[b'RUSTFLAGS'] = b'-C link-args=-Wl,--subsystem,windows' status = call([cargo_binary, "build"] + opts, env=env, cwd=self.servo_crate(), verbose=verbose) elapsed = time() - build_start # Do some additional things if the build succeeded if status == 0: if sys.platform in ("win32", "msys"): servo_exe_dir = path.join(base_path, "debug" if dev else "release") # On windows, copy in our manifest shutil.copy( path.join(self.get_top_dir(), "components", "servo", "servo.exe.manifest"), servo_exe_dir) if "msvc" in (target or host_triple()): msvc_x64 = "64" if "x86_64" in (target or host_triple()) else "" # on msvc builds, use editbin to change the subsystem to windows, but only # on release builds -- on debug builds, it hides log output if not dev: call([ "editbin", "/nologo", "/subsystem:windows", path.join(servo_exe_dir, "servo.exe") ], verbose=verbose) # on msvc, we need to copy in some DLLs in to the servo.exe dir for ssl_lib in ["ssleay32md.dll", "libeay32md.dll"]: shutil.copy( path.join(env['OPENSSL_LIB_DIR'], "../bin" + msvc_x64, ssl_lib), servo_exe_dir) elif sys.platform == "darwin": # On the Mac, set a lovely icon. This makes it easier to pick out the Servo binary in tools # like Instruments.app. try: import Cocoa icon_path = path.join(self.get_top_dir(), "resources", "servo.png") icon = Cocoa.NSImage.alloc().initWithContentsOfFile_( icon_path) if icon is not None: Cocoa.NSWorkspace.sharedWorkspace( ).setIcon_forFile_options_(icon, servo_path, 0) except ImportError: pass # Generate Desktop Notification if elapsed-time > some threshold value notify_build_done(elapsed, status == 0) print("Build %s in %s" % ("Completed" if status == 0 else "FAILED", format_duration(elapsed))) return status
def bootstrap_rustc(self, force=False, target=[], stable=False): self.set_use_stable_rust(stable) version = self.rust_version() rust_path = self.rust_path() rust_dir = path.join(self.context.sharedir, "rust", rust_path) install_dir = path.join(self.context.sharedir, "rust", version) if not force and path.exists(path.join(rust_dir, "rustc", "bin", "rustc" + BIN_SUFFIX)): print("Rust compiler already downloaded.", end=" ") print("Use |bootstrap-rust --force| to download again.") else: if path.isdir(rust_dir): shutil.rmtree(rust_dir) os.makedirs(rust_dir) # The nightly Rust compiler is hosted on the nightly server under the date with a name # rustc-nightly-HOST-TRIPLE.tar.gz, whereas the stable compiler is named # rustc-VERSION-HOST-TRIPLE.tar.gz. We just need to pull down and extract it, # giving a directory name that will be the same as the tarball name (rustc is # in that directory). if stable: tarball = "rustc-%s-%s.tar.gz" % (version, host_triple()) else: tarball = "%s/rustc-nightly-%s.tar.gz" % (version, host_triple()) rustc_url = "https://static-rust-lang-org.s3.amazonaws.com/dist/" + tarball tgz_file = rust_dir + '-rustc.tar.gz' download_file("Rust compiler", rustc_url, tgz_file) print("Extracting Rust compiler...") extract(tgz_file, install_dir) print("Rust compiler ready.") # Each Rust stdlib has a name of the form `rust-std-nightly-TRIPLE.tar.gz` for the nightly # releases, or rust-std-VERSION-TRIPLE.tar.gz for stable releases, with # a directory of the name `rust-std-TRIPLE` inside and then a `lib` directory. # This `lib` directory needs to be extracted and merged with the `rustc/lib` # directory from the host compiler above. nightly_suffix = "" if stable else "-nightly" stable_version = "-{}".format(version) if stable else "" lib_dir = path.join(install_dir, "rustc{}{}-{}".format(nightly_suffix, stable_version, host_triple()), "rustc", "lib", "rustlib") # ensure that the libs for the host's target is downloaded host_target = host_triple() if host_target not in target: target.append(host_target) for target_triple in target: target_lib_dir = path.join(lib_dir, target_triple) if path.exists(target_lib_dir): # No need to check for force. If --force the directory is already deleted print("Rust lib for target {} already downloaded.".format(target_triple), end=" ") print("Use |bootstrap-rust --force| to download again.") continue if self.use_stable_rust(): std_url = ("https://static-rust-lang-org.s3.amazonaws.com/dist/rust-std-%s-%s.tar.gz" % (version, target_triple)) tgz_file = install_dir + ('rust-std-%s-%s.tar.gz' % (version, target_triple)) else: std_url = ("https://static-rust-lang-org.s3.amazonaws.com/dist/%s/rust-std-nightly-%s.tar.gz" % (version, target_triple)) tgz_file = install_dir + ('rust-std-nightly-%s.tar.gz' % target_triple) download_file("Host rust library for target %s" % target_triple, std_url, tgz_file) print("Extracting Rust stdlib for target %s..." % target_triple) extract(tgz_file, install_dir) shutil.copytree(path.join(install_dir, "rust-std%s%s-%s" % (nightly_suffix, stable_version, target_triple), "rust-std-%s" % target_triple, "lib", "rustlib", target_triple), path.join(install_dir, "rustc%s%s-%s" % (nightly_suffix, stable_version, host_triple()), "rustc", "lib", "rustlib", target_triple)) shutil.rmtree(path.join(install_dir, "rust-std%s%s-%s" % (nightly_suffix, stable_version, target_triple))) print("Rust {} libs ready.".format(target_triple))
def build(self, target=None, release=False, dev=False, jobs=None, features=None, android=None, verbose=False, debug_mozjs=False, params=None): if android is None: android = self.config["build"]["android"] features = features or self.servo_features() opts = params or [] base_path = self.get_target_dir() release_path = path.join(base_path, "release", "servo") dev_path = path.join(base_path, "debug", "servo") release_exists = path.exists(release_path) dev_exists = path.exists(dev_path) if not (release or dev): if self.config["build"]["mode"] == "dev": dev = True elif self.config["build"]["mode"] == "release": release = True elif release_exists and not dev_exists: release = True elif dev_exists and not release_exists: dev = True else: print("Please specify either --dev (-d) for a development") print(" build, or --release (-r) for an optimized build.") sys.exit(1) if release and dev: print("Please specify either --dev or --release.") sys.exit(1) if target and android: print("Please specify either --target or --android.") sys.exit(1) if release: opts += ["--release"] servo_path = release_path else: servo_path = dev_path if jobs is not None: opts += ["-j", jobs] if verbose: opts += ["-v"] if android: target = self.config["android"]["target"] if target: opts += ["--target", target] self.ensure_bootstrapped(target=target) if debug_mozjs: features += ["script/debugmozjs"] if features: opts += ["--features", "%s" % ' '.join(features)] build_start = time() env = self.build_env(target=target, is_build=True) if android: # Build OpenSSL for android make_cmd = ["make"] if jobs is not None: make_cmd += ["-j" + jobs] android_dir = self.android_build_dir(dev) openssl_dir = path.join(android_dir, "native", "openssl") if not path.exists(openssl_dir): os.makedirs(openssl_dir) shutil.copy(path.join(self.android_support_dir(), "openssl.makefile"), openssl_dir) shutil.copy(path.join(self.android_support_dir(), "openssl.sh"), openssl_dir) with cd(openssl_dir): status = call( make_cmd + ["-f", "openssl.makefile"], env=env, verbose=verbose) if status: return status openssl_dir = path.join(openssl_dir, "openssl-1.0.1t") env['OPENSSL_LIB_DIR'] = openssl_dir env['OPENSSL_INCLUDE_DIR'] = path.join(openssl_dir, "include") env['OPENSSL_STATIC'] = 'TRUE' cargo_binary = "cargo" + BIN_SUFFIX if sys.platform in ("win32", "msys"): if "msvc" not in host_triple(): env[b'RUSTFLAGS'] = b'-C link-args=-Wl,--subsystem,windows' status = call( [cargo_binary, "build"] + opts, env=env, cwd=self.servo_crate(), verbose=verbose) elapsed = time() - build_start # Do some additional things if the build succeeded if status == 0: if sys.platform in ("win32", "msys"): servo_exe_dir = path.join(base_path, "debug" if dev else "release") # On windows, copy in our manifest shutil.copy(path.join(self.get_top_dir(), "components", "servo", "servo.exe.manifest"), servo_exe_dir) if "msvc" in host_triple(): # on msvc builds, use editbin to change the subsystem to windows call(["editbin", "/nologo", "/subsystem:windows", path.join(servo_exe_dir, "servo.exe")], verbose=verbose) # on msvc, we need to copy in some DLLs in to the servo.exe dir for ssl_lib in ["ssleay32md.dll", "libeay32md.dll"]: shutil.copy(path.join(os.getenv('OPENSSL_LIB_DIR'), "../bin64", ssl_lib), servo_exe_dir) for ffmpeg_lib in ["avutil-55.dll", "avformat-57.dll", "avcodec-57.dll", "swresample-2.dll"]: shutil.copy(path.join(os.getenv('FFMPEG_LIB_DIR'), "../bin", ffmpeg_lib), servo_exe_dir) elif sys.platform == "darwin": # On the Mac, set a lovely icon. This makes it easier to pick out the Servo binary in tools # like Instruments.app. try: import Cocoa icon_path = path.join(self.get_top_dir(), "resources", "servo.png") icon = Cocoa.NSImage.alloc().initWithContentsOfFile_(icon_path) if icon is not None: Cocoa.NSWorkspace.sharedWorkspace().setIcon_forFile_options_(icon, servo_path, 0) except ImportError: pass # Generate Desktop Notification if elapsed-time > some threshold value notify_build_done(elapsed, status == 0) print("Build %s in %s" % ("Completed" if status == 0 else "FAILED", format_duration(elapsed))) return status
def build(self, target=None, release=False, dev=False, jobs=None, features=None, android=None, verbose=False, debug_mozjs=False, params=None, with_debug_assertions=False): if android is None: android = self.config["build"]["android"] features = features or self.servo_features() opts = params or [] base_path = self.get_target_dir() release_path = path.join(base_path, "release", "servo") dev_path = path.join(base_path, "debug", "servo") release_exists = path.exists(release_path) dev_exists = path.exists(dev_path) if not (release or dev): if self.config["build"]["mode"] == "dev": dev = True elif self.config["build"]["mode"] == "release": release = True elif release_exists and not dev_exists: release = True elif dev_exists and not release_exists: dev = True else: print("Please specify either --dev (-d) for a development") print(" build, or --release (-r) for an optimized build.") sys.exit(1) if release and dev: print("Please specify either --dev or --release.") sys.exit(1) if target and android: print("Please specify either --target or --android.") sys.exit(1) if release: opts += ["--release"] servo_path = release_path else: servo_path = dev_path if jobs is not None: opts += ["-j", jobs] if verbose: opts += ["-v"] if android: target = self.config["android"]["target"] if target: opts += ["--target", target] self.ensure_bootstrapped(target=target) if debug_mozjs: features += ["debugmozjs"] if features: opts += ["--features", "%s" % ' '.join(features)] build_start = time() env = self.build_env(target=target, is_build=True) if with_debug_assertions: env["RUSTFLAGS"] = "-C debug_assertions" if android: # Build OpenSSL for android make_cmd = ["make"] if jobs is not None: make_cmd += ["-j" + jobs] android_dir = self.android_build_dir(dev) openssl_dir = path.join(android_dir, "native", "openssl") if not path.exists(openssl_dir): os.makedirs(openssl_dir) shutil.copy(path.join(self.android_support_dir(), "openssl.makefile"), openssl_dir) shutil.copy(path.join(self.android_support_dir(), "openssl.sh"), openssl_dir) env["ANDROID_NDK_ROOT"] = env["ANDROID_NDK"] with cd(openssl_dir): status = call( make_cmd + ["-f", "openssl.makefile"], env=env, verbose=verbose) if status: return status openssl_dir = path.join(openssl_dir, "openssl-1.0.1t") env['OPENSSL_LIB_DIR'] = openssl_dir env['OPENSSL_INCLUDE_DIR'] = path.join(openssl_dir, "include") env['OPENSSL_STATIC'] = 'TRUE' # Android builds also require having the gcc bits on the PATH and various INCLUDE # path munging if you do not want to install a standalone NDK. See: # https://dxr.mozilla.org/mozilla-central/source/build/autoconf/android.m4#139-161 os_type = platform.system().lower() if os_type not in ["linux", "darwin"]: raise Exception("Android cross builds are only supported on Linux and macOS.") cpu_type = platform.machine().lower() host_suffix = "unknown" if cpu_type in ["i386", "i486", "i686", "i768", "x86"]: host_suffix = "x86" elif cpu_type in ["x86_64", "x86-64", "x64", "amd64"]: host_suffix = "x86_64" host = os_type + "-" + host_suffix env['PATH'] = path.join( env['ANDROID_NDK'], "toolchains", "arm-linux-androideabi-4.9", "prebuilt", host, "bin" ) + ':' + env['PATH'] env['ANDROID_SYSROOT'] = path.join(env['ANDROID_NDK'], "platforms", "android-18", "arch-arm") support_include = path.join(env['ANDROID_NDK'], "sources", "android", "support", "include") cxx_include = path.join( env['ANDROID_NDK'], "sources", "cxx-stl", "llvm-libc++", "libcxx", "include") cxxabi_include = path.join( env['ANDROID_NDK'], "sources", "cxx-stl", "llvm-libc++abi", "libcxxabi", "include") env['CFLAGS'] = ' '.join([ "--sysroot", env['ANDROID_SYSROOT'], "-I" + support_include]) env['CXXFLAGS'] = ' '.join([ "--sysroot", env['ANDROID_SYSROOT'], "-I" + support_include, "-I" + cxx_include, "-I" + cxxabi_include]) cargo_binary = "cargo" + BIN_SUFFIX if sys.platform in ("win32", "msys"): if "msvc" not in host_triple(): env[b'RUSTFLAGS'] = b'-C link-args=-Wl,--subsystem,windows' status = call( [cargo_binary, "build"] + opts, env=env, cwd=self.servo_crate(), verbose=verbose) elapsed = time() - build_start # Do some additional things if the build succeeded if status == 0: if sys.platform in ("win32", "msys"): servo_exe_dir = path.join(base_path, "debug" if dev else "release") # On windows, copy in our manifest shutil.copy(path.join(self.get_top_dir(), "components", "servo", "servo.exe.manifest"), servo_exe_dir) if "msvc" in (target or host_triple()): msvc_x64 = "64" if "x86_64" in (target or host_triple()) else "" # on msvc builds, use editbin to change the subsystem to windows, but only # on release builds -- on debug builds, it hides log output if not dev: call(["editbin", "/nologo", "/subsystem:windows", path.join(servo_exe_dir, "servo.exe")], verbose=verbose) # on msvc, we need to copy in some DLLs in to the servo.exe dir for ssl_lib in ["ssleay32md.dll", "libeay32md.dll"]: shutil.copy(path.join(env['OPENSSL_LIB_DIR'], "../bin" + msvc_x64, ssl_lib), servo_exe_dir) elif sys.platform == "darwin": # On the Mac, set a lovely icon. This makes it easier to pick out the Servo binary in tools # like Instruments.app. try: import Cocoa icon_path = path.join(self.get_top_dir(), "resources", "servo.png") icon = Cocoa.NSImage.alloc().initWithContentsOfFile_(icon_path) if icon is not None: Cocoa.NSWorkspace.sharedWorkspace().setIcon_forFile_options_(icon, servo_path, 0) except ImportError: pass # Generate Desktop Notification if elapsed-time > some threshold value notify_build_done(elapsed, status == 0) print("Build %s in %s" % ("Completed" if status == 0 else "FAILED", format_duration(elapsed))) return status
def build(self, target=None, release=False, dev=False, jobs=None, features=None, android=None, verbose=False, debug_mozjs=False, params=None, with_debug_assertions=False): if android is None: android = self.config["build"]["android"] features = features or self.servo_features() opts = params or [] base_path = self.get_target_dir() release_path = path.join(base_path, "release", "servo") dev_path = path.join(base_path, "debug", "servo") release_exists = path.exists(release_path) dev_exists = path.exists(dev_path) if not (release or dev): if self.config["build"]["mode"] == "dev": dev = True elif self.config["build"]["mode"] == "release": release = True elif release_exists and not dev_exists: release = True elif dev_exists and not release_exists: dev = True else: print("Please specify either --dev (-d) for a development") print(" build, or --release (-r) for an optimized build.") sys.exit(1) if release and dev: print("Please specify either --dev or --release.") sys.exit(1) if target and android: print("Please specify either --target or --android.") sys.exit(1) if release: opts += ["--release"] servo_path = release_path else: servo_path = dev_path if jobs is not None: opts += ["-j", jobs] if verbose: opts += ["-v"] if android: target = self.config["android"]["target"] if target: opts += ["--target", target] self.ensure_bootstrapped(target=target) if debug_mozjs: features += ["debugmozjs"] if features: opts += ["--features", "%s" % ' '.join(features)] build_start = time() env = self.build_env(target=target, is_build=True) if with_debug_assertions: env["RUSTFLAGS"] = "-C debug_assertions" if android: # Build OpenSSL for android make_cmd = ["make"] if jobs is not None: make_cmd += ["-j" + jobs] android_dir = self.android_build_dir(dev) openssl_dir = path.join(android_dir, "native", "openssl") if not path.exists(openssl_dir): os.makedirs(openssl_dir) shutil.copy( path.join(self.android_support_dir(), "openssl.makefile"), openssl_dir) shutil.copy(path.join(self.android_support_dir(), "openssl.sh"), openssl_dir) env["ANDROID_NDK_ROOT"] = env["ANDROID_NDK"] with cd(openssl_dir): status = call(make_cmd + ["-f", "openssl.makefile"], env=env, verbose=verbose) if status: return status openssl_dir = path.join(openssl_dir, "openssl-1.0.1t") env['OPENSSL_LIB_DIR'] = openssl_dir env['OPENSSL_INCLUDE_DIR'] = path.join(openssl_dir, "include") env['OPENSSL_STATIC'] = 'TRUE' # Android builds also require having the gcc bits on the PATH and various INCLUDE # path munging if you do not want to install a standalone NDK. See: # https://dxr.mozilla.org/mozilla-central/source/build/autoconf/android.m4#139-161 os_type = platform.system().lower() if os_type not in ["linux", "darwin"]: raise Exception( "Android cross builds are only supported on Linux and macOS." ) cpu_type = platform.machine().lower() host_suffix = "unknown" if cpu_type in ["i386", "i486", "i686", "i768", "x86"]: host_suffix = "x86" elif cpu_type in ["x86_64", "x86-64", "x64", "amd64"]: host_suffix = "x86_64" host = os_type + "-" + host_suffix env['PATH'] = path.join(env['ANDROID_NDK'], "toolchains", "arm-linux-androideabi-4.9", "prebuilt", host, "bin") + ':' + env['PATH'] env['ANDROID_SYSROOT'] = path.join(env['ANDROID_NDK'], "platforms", "android-18", "arch-arm") support_include = path.join(env['ANDROID_NDK'], "sources", "android", "support", "include") cxx_include = path.join(env['ANDROID_NDK'], "sources", "cxx-stl", "llvm-libc++", "libcxx", "include") cxxabi_include = path.join(env['ANDROID_NDK'], "sources", "cxx-stl", "llvm-libc++abi", "libcxxabi", "include") env['CFLAGS'] = ' '.join( ["--sysroot", env['ANDROID_SYSROOT'], "-I" + support_include]) env['CXXFLAGS'] = ' '.join([ "--sysroot", env['ANDROID_SYSROOT'], "-I" + support_include, "-I" + cxx_include, "-I" + cxxabi_include ]) cargo_binary = "cargo" + BIN_SUFFIX if sys.platform in ("win32", "msys"): if "msvc" not in host_triple(): env[b'RUSTFLAGS'] = b'-C link-args=-Wl,--subsystem,windows' status = call([cargo_binary, "build"] + opts, env=env, cwd=self.servo_crate(), verbose=verbose) elapsed = time() - build_start # Do some additional things if the build succeeded if status == 0: if sys.platform in ("win32", "msys"): servo_exe_dir = path.join(base_path, "debug" if dev else "release") # On windows, copy in our manifest shutil.copy( path.join(self.get_top_dir(), "components", "servo", "servo.exe.manifest"), servo_exe_dir) if "msvc" in (target or host_triple()): msvc_x64 = "64" if "x86_64" in (target or host_triple()) else "" # on msvc builds, use editbin to change the subsystem to windows, but only # on release builds -- on debug builds, it hides log output if not dev: call([ "editbin", "/nologo", "/subsystem:windows", path.join(servo_exe_dir, "servo.exe") ], verbose=verbose) # on msvc, we need to copy in some DLLs in to the servo.exe dir for ssl_lib in ["ssleay32md.dll", "libeay32md.dll"]: shutil.copy( path.join(env['OPENSSL_LIB_DIR'], "../bin" + msvc_x64, ssl_lib), servo_exe_dir) elif sys.platform == "darwin": # On the Mac, set a lovely icon. This makes it easier to pick out the Servo binary in tools # like Instruments.app. try: import Cocoa icon_path = path.join(self.get_top_dir(), "resources", "servo.png") icon = Cocoa.NSImage.alloc().initWithContentsOfFile_( icon_path) if icon is not None: Cocoa.NSWorkspace.sharedWorkspace( ).setIcon_forFile_options_(icon, servo_path, 0) except ImportError: pass # Generate Desktop Notification if elapsed-time > some threshold value notify_build_done(elapsed, status == 0) print("Build %s in %s" % ("Completed" if status == 0 else "FAILED", format_duration(elapsed))) return status
def test_unit(self, test_name=None, package=None, bench=False, nocapture=False): if test_name is None: test_name = [] self.ensure_bootstrapped() if package: packages = {package} else: packages = set() test_patterns = [] for test in test_name: # add package if 'tests/unit/<package>' match = re.search("tests/unit/(\\w+)/?$", test) if match: packages.add(match.group(1)) # add package & test if '<package>/<test>', 'tests/unit/<package>/<test>.rs', or similar elif re.search("\\w/\\w", test): tokens = test.split("/") packages.add(tokens[-2]) test_prefix = tokens[-1] if test_prefix.endswith(".rs"): test_prefix = test_prefix[:-3] test_prefix += "::" test_patterns.append(test_prefix) # add test as-is otherwise else: test_patterns.append(test) if not packages: packages = set( os.listdir(path.join(self.context.topdir, "tests", "unit"))) packages.discard('stylo') has_style = True try: packages.remove('style') except KeyError: has_style = False env = self.build_env() env["RUST_BACKTRACE"] = "1" if sys.platform in ("win32", "msys"): if "msvc" in host_triple(): # on MSVC, we need some DLLs in the path. They were copied # in to the servo.exe build dir, so just point PATH to that. env["PATH"] = "%s%s%s" % (path.dirname( self.get_binary_path(False, False)), os.pathsep, env["PATH"]) else: env["RUSTFLAGS"] = "-C link-args=-Wl,--subsystem,windows" features = self.servo_features() if len(packages) > 0: args = ["cargo", "bench" if bench else "test"] for crate in packages: args += ["-p", "%s_tests" % crate] args += test_patterns if features: args += ["--features", "%s" % ' '.join(features)] if nocapture: args += ["--", "--nocapture"] err = call(args, env=env, cwd=self.servo_crate()) if err is not 0: return err # Run style tests with the testing feature if has_style: args = [ "cargo", "bench" if bench else "test", "-p", "style_tests", "--features" ] if features: args += ["%s" % ' '.join(features + ["testing"])] else: args += ["testing"] args += test_patterns if nocapture: args += ["--", "--nocapture"] return call(args, env=env, cwd=self.servo_crate())