Bug 1251870 - Disable indexing of objdir on Windows; r?ted
The Windows content indexing service has been known to scan the objdir.
This can add significant system overhead and slow down builds or
subsequent operations. The objdir is meant to be a short-lived black box
and there really isn't a major benefit to indexing it.
There is a file attribute on Windows that disables content indexing.
This commit adds a utility function for creating a directory and
optionally disabling indexing on it. We call it at the top of
`mach build` to ensure the objdir as content indexing disabled.
MozReview-Commit-ID: 68gxCxbkVAN
--- a/python/mozbuild/mozbuild/mach_commands.py
+++ b/python/mozbuild/mozbuild/mach_commands.py
@@ -300,25 +300,32 @@ class Build(MachCommandBase):
* faster - builds JavaScript, XUL, CSS, etc files.
"binaries" and "faster" almost fully complement each other. However,
there are build actions not captured by either. If things don't appear to
be rebuilding, perform a vanilla `mach build` to rebuild the world.
"""
import which
from mozbuild.controller.building import BuildMonitor
- from mozbuild.util import resolve_target_to_make
+ from mozbuild.util import (
+ mkdir,
+ resolve_target_to_make,
+ )
self.log_manager.register_structured_logger(logging.getLogger('mozbuild'))
warnings_path = self._get_state_filename('warnings.json')
monitor = self._spawn(BuildMonitor)
monitor.init(warnings_path)
ccache_start = monitor.ccache_stats()
+ # Disable indexing in objdir because it is not necessary and can slow
+ # down builds.
+ mkdir(self.topobjdir, not_indexed=True)
+
with BuildOutputManager(self.log_manager, monitor) as output:
monitor.start()
if directory is not None and not what:
print('Can only use -C/--directory with an explicit target '
'name.')
return 1
--- a/python/mozbuild/mozbuild/util.py
+++ b/python/mozbuild/mozbuild/util.py
@@ -4,16 +4,17 @@
# This file contains miscellaneous utility functions that don't belong anywhere
# in particular.
from __future__ import absolute_import, unicode_literals
import argparse
import collections
+import ctypes
import difflib
import errno
import functools
import hashlib
import itertools
import os
import re
import stat
@@ -31,16 +32,21 @@ from io import (
)
if sys.version_info[0] == 3:
str_type = str
else:
str_type = basestring
+if sys.platform == 'win32':
+ _kernel32 = ctypes.windll.kernel32
+ _FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x2000
+
+
def hash_file(path, hasher=None):
"""Hashes a file specified by the path given and returns the hex digest."""
# If the default hashing function changes, this may invalidate
# lots of cached data. Don't change it lightly.
h = hasher or hashlib.sha1()
with open(path, 'rb') as fh:
@@ -106,16 +112,38 @@ def ensureParentDir(path):
if d and not os.path.exists(path):
try:
os.makedirs(d)
except OSError, error:
if error.errno != errno.EEXIST:
raise
+def mkdir(path, not_indexed=False):
+ """Ensure a directory exists.
+
+ If ``not_indexed`` is True, an attribute is set that disables content
+ indexing on the directory.
+ """
+ try:
+ os.makedirs(path)
+ except OSError as e:
+ if e.errno != errno.EEXIST:
+ raise
+
+ if not_indexed:
+ if sys.platform == 'win32':
+ if isinstance(path, str_type):
+ fn = _kernel32.SetFileAttributesW
+ else:
+ fn = _kernel32.SetFileAttributesA
+
+ fn(path, _FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)
+
+
def simple_diff(filename, old_lines, new_lines):
"""Returns the diff between old_lines and new_lines, in unified diff form,
as a list of lines.
old_lines and new_lines are lists of non-newline terminated lines to
compare.
old_lines can be None, indicating a file creation.
new_lines can be None, indicating a file deletion.