| Commit message (Collapse) | Author | Age | Files | Lines |
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
1. Add support for -isysroot and -arch.
2. Fix a really nasty corner case:
- CompressFiles::Compress uses os.makedirs to create a directory (foo)
for one compilation unit
- Another compilation unit does the equivalent of '#include
"foo/../bar.h"'
- The compilation unit uses no other file in foo
- We conclude that we don't have to create a dummy
foo/forcing_technique_271828
|
| |
|
| |
Fixes issue 113
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
include_server --no_force_dirs inhibits forcing_technique
The "forcing_technique" trick which handles the (rare) case of files
included as e.g. <foo/../file.h> causes a performance degradation:
The forcing files accumulate over the life of the include_server, making
distcc send more and more (useless) files as the build progresses.
While the forcing files are zero-length, the transmission filenames
themselves introduce a significant overhead for builds with many files
and directories.
This patch implements the include_server arg --no_force_dirs, which if
set switches off the "forcing_technique" scheme.
|
| |
|
|
|
|
| |
Generalize the dcc_{r,x}_argv routines so they can be used to
transfer arbitrary array-of-strings tokens (useful for protocol
hacking experiments; no functional change).
|
| |
|
|
|
| |
handle header file names containing commas.
|
| |
|
|
| |
<http://code.google.com/p/distcc/issues/detail?id=99>: include_server crash: local variable resolved referenced before assignment.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
2010-08-18 Simon Baldwin <simonb@google.com>
* include_server/compiler_defaults.py (_SystemSearchdirsGCC):
Add a 'sysroot' parameter. Add --sysroot, if needed, to the gcc
invocation that identifies search directories and default paths.
Add debugging output.
(SetSystemDirsDefaults): Add 'sysroot' parameter. Add another
dictionary level to system_dirs_default for sysroot values.
Add debugging output.
* include_server/parse_command.py (ParseCommandArgs): Identify
and handle arguments of the form '--opt=value'. Pass any
--sysroot value to compiler_defaults.SetSystemDirsDefaults, use
it in compiler_defaults.system_dirs_default lookups.
(CPP_OPTIONS_APPEARING_AS_ASSIGNMENTS): New.
* include_server/parse_command_test.py (Mock_SetSystemDirsDefaults):
Add sysroot parameter, verify it on function calls.
(ParseCommandUnitTest): Add --sysroot to mock gcc invocations.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This was a bug where the include server was crashing in certain cases
(when the argument to a macro ended in a backslash) due to an escaping
problem in the use of Python's re.sub() function. The fix was to
replace all occurrences of backslash in the replacement string
with double-backslash, which re.sub() will then translate back to
a single backslash. (I also changed the code to not bother using
re.compile() since we only use the regexp once.)
Also, fix a bug where we were not allowing backslashes in filenames.
I added regression tests for both of these bugs
(and I verified that they were true regression tests).
Reviewed by Craig Silverstein.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
was failing on systems where /tmp was a symlink.
This failure indicated a real bug: on such systems,
distcc was not correctly handling -I<dir> where
<dir> is a subdirectory of a system include directory,
e.g. -I/usr/include/foo.
The code was calling _RealPrefix(client_root + system_dir)
but was implicitly assuming that the answer would always
start with client_root. That is, it was implicitly assuming
that client_root did not contain any symlinks.
I changed the code to use
_RealPrefixWithinClientRoot(client_root, system_dir)
so that it would find the appropriate prefix of system_dir
rather than looking at the prefixes of client_root.
|
| |
|
|
|
| |
from "gcc -v", ignore Apple-modified MacOS gcc's "framework" directories.
|
| |
|
|
|
|
| |
The top-level Makefile sets CFLAGS="$(CFLAGS) $(PYTHON_CFLAGS)"
before invoking setup.py, so there's no need for it to set PYTHON_CFLAGS.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
-Wwrite-strings when compiling the python extension module,
due to lack of const correctness in the Python 2.2
"Python.h" header file.
This problem was introduced by the fix for distcc issue 26
<http://code.google.com/p/distcc/issues/detail?id=26>.
The solution was to explicitly disable these warnings
with -Wno-write-strings.
2. Centralize the use of gcc-specific compilation options
in conditional code in configure.ac that is only executed
if we're using gcc. Previously include_server/setup.py
was hard-coding gcc-specific options, regardless of
whether we're using gcc.
3. Don't use -Wuninitialized if CFLAGS doesn't contain "-O*",
because -Wuninitialized only works if optimization is enabled.
This avoids a gcc warning (and hence an error with -Werror)
about -Wuninitialized not having any effect
when distcc is configured with "CFLAGS=-g ./configure".
4. Add a new configure option "--disable-Werror".
For the 3.0 release of distcc, some people porting distcc
resorted to patching distcc to remove the -Werror option.
-Werror is useful, so I want to keep it enabled by default,
but I'd prefer that people are able to port distcc easily,
hence the configure option.
This addresses distcc issue 20
<http://code.google.com/p/distcc/issues/detail?id=20>.
Reviewers: Craig Silverstein
|
| |
|
|
|
|
|
| |
<http://code.google.com/p/distcc/issues/detail?id=27>,
which was a build problem on "Gentoo, x86-64, gcc-4.1.2,
glibc-2.6.1, python-2.5.2".
|
| |
|
|
|
| |
previous change which deleted the test that used it.
|
| |
|
|
|
| |
so it wasn't testing anything useful.
|
| |
|
|
|
|
|
| |
add a new "--scan-includes" option to distcc which shows
which headers distcc would send to the remote machine in
pump mode, without actually compiling anything.
|
| |
|
|
|
|
|
|
|
|
|
| |
that broke pump mode when one of the default system include directories
was a subdirectory of another, as turns out to be the case for GNU C++.
The CPlusPlus_SystemIncludeDirectories_Case, which was failing before this
change, now passes. (TODO: re-enable it.)
Reviewers: Craig Silverstein
|
| |
|
|
|
|
|
| |
It turns out that our own test infrastructure (test/testdistcc.py)
sets TMPDIR before invoking distccd, so this needs to be reasonably
high, otherwise 'make distcheck' will fail.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
gvn --project https://distcc.googlecode.com/svn/trunk review klarlund/d3b3
Fix Issue 7: Compiling with -I/usr/include/FOO or ... in pump mode
Problem:
Default system include directories are the directories on the default include
search path, such as /usr/include, that is determined by the compiler. Distcc
will not send default system include directories to the distcc compilation
servers. Nevertheless, distcc on the server blindly rewrites -I options such
as -I/usr/include/foo to -I/tmp/distccNNN/usr/include/foo.
This doesn't work, since the files in /usr/include/foo are not sent to the
distccd server.
Solution:
The present solution keeps the rewriting on the server, because we would like
to not manage starting the compiler, parsing its output, and storing the
default system paths on the server
Instead, we use the existing mechanism for defining relative symbolic links
under the server root. We escape from the root by using a sufficient number
of '../'s.
All this is tremendously complicated by:
-- The possibility that other links encountered may point into the system
default dirs in which case the usual mirroring of the reachable places
should not take place, because the routing of such links will go through
the link created for the system directory.
-- The fact that determination of default-system-dirness is lazy: a
deeply-seated link in a default system dir may become obsolete if it is
later determined that a higher directory than the parent directory of the
link is in fact also a default system dir. In that case, a new symlink,
sitting in a place higher than the previous one will need to be created.
Tests:
make check
benchmarks: samba (still 3X faster than with distcc), linux 2.6 kernel, and
a couple of others
TODO: better testing
TODO:
> In compiler_defaults.py, _MakeLinkFromMirrorToRealLocation:
> Maybe comment each of the 'if' cases with an example of how this case
> might be triggered. eg the real_prefix == rooted_system_dir is
> triggered when we see /usr/include/foo, and the later see
> /usr/include.
|
| |
|
|
|
|
|
|
|
| |
This change is mostly reverted -- some variable renamings are not
changed back. A subsequent CL proposes a less arbitrary way to solve
the problem of -I<some_dir_in_default_place_where_compiler_looks>,
which involves sending no system default header files at all.
Tests: make pump-check and make include-server-check
|
| |
|
|
|
| |
variable wasn't set.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
assumptions of distcc-pump added to man/distcc.1 as well. The BUGS section
of distcc.1 has been updated.
A spelling error correction is made to man/distcc.1.
The pump.in script is changed so that it does not introduce other certain
defaults than those mentioned in the manual (which are those of the of include
server).
Finally, I changed the order of the options in the include server source code to
be alphabetical in accordance with include_server(1) man page.
Reviewers: fergus, csilvers.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I renamed the option to path_observation_re. Now by prefixing
INCLUDE_SERVER_ARGS='-d1 --path_observation_re="/usr/.*"'
to say make include-server-maintainer-check, one gets a message each time the
include server finds a path whose realpath name matches the regular expression.
That results in messages like:
WARNING include server: For translation unit 'src/testtmp.c', lookup of file
'bits/stdio_lim.h' resolved to '/usr/include/bits/stdio_lim.h' whose realpath is
'/usr/include/bits/stdio_lim.h'.
To make the interpretation of quoted arguments within INCLUDE_SERVER_ARGS
correct, I added 'eval' to the command that cranks up the include server. I
remembered to put extra quoted quotes inside the parameters that should be
considered a token after the double interpretation that eval implies.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
During compilation of the Linux kernel messages like:
absolute filepath blabla.h was IGNORED (correctness of build may be affected)
are issued. They are wrong. The problem is that -include or -imacro or even
source file names with absolute filepaths trigger a complaint from the caching
mechanism usually used for relative file names.
We correct this problem.
We also substitute fp_map for includepath_map, which is the now preferred term.
REVIEWER: csilvers@google.com
TESTS:
make pump-maintainer-check
make include-server-maintainer-check
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add a new piece of command line parse information: send_systemdirs. This
boolean is normally false. It is true if there is a -isystem option with a
default system directory (one known to the compiler).
With send_systemdirs true, the compiler headers of system headers are sent to
the servers and mounted under the server root. The isystem option is as usual
rewritten to be relative to the root. Without this flag setting, distcc quickly
decides that pump mode is not viable because remote compilations fail.
Also, fixed the comment:
# TODO(klarlund): Make mechanism for handling -U, -undef options, along with
# default symbols.
(-D options are handled.)
---------------
TESTS: make pump-maintainer-check
make include-server-maintainer-check
make 'linux kernel' in a directory made by the benchmark script (as shown below)
DISTCC_EMAILLOG_WHOM_TO_BLAME=klarlund@google.com DISTCC_ENABLE_DISCREPANCY_EMAIL=1 INCLUDE_SERVER_ARGS='-d1 -t --email --unsafe_absolute_includes --send_systemdirs --stat_reset_triggers=include/linux/*' DISTCC_HOSTS="--randomize `/home/klarlund/svn-distcc/distcc/lsdistcc -P3 -k100 -d`" PATH=/home/klarlund/svn-distcc/distcc:$PATH ./masquerade pump make -j120
REVIVIEWER: csilvers@google.com
TRIVIA: the about 1000 files in the kernel build involve on average 400
headers. The build time on a quad-cpu machine drops from about 1m40 s to 1m20s.
With pump-mode, the machine is underutilized judging from the total sys + user
time, which is around only 2m20s.
NOTE: this is a successor to 'g6n8', which simply introduced a command line
option to force sending of system files. A bug in gvn did not allow me to
resuse that change list.
|
| |
|
|
|
|
|
|
| |
(typically the only change is in the FSF street address). Add Google
copyright line in some places it was missing. Add GPLv2 notice to
avahi patches.
OKed by fergus
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Testing of distcc-pump mode on the Linux kernel showed that the computed include
closure was sometimes wrong: header files were missing.
Further testing showed that sometimes apparently not even the compilation unit
made it across to the server or rather, the c-file in its real location would
come across, but the path designating it would not.
Take as an example: compilation unit is designated by the path ../bar/baz.c and
the current directory is /foo but no files in /foo are in actuality referenced
during include processing. Then the compilation server will get
/PREFIX/bar/baz.h -- the image of the real file -- but /PREFIX/foo, the image of
the current directory, will not even be created!
So, this CL corrects an oversight in the way that the include processor
explores files: although it does take into account the chasing of symbolic links,
no provisions are in place to properly model '..' for climbing up directories.
Specifically, to climb up a directory, it must exist! Usually, the directory in
fact would exist on the server, because it would be replicated thanks to the
header files it contains. But there is no guarentee.
We solve this problem by forcing the creation of dummy .c files the first time a
path is explored. Because paths are being investigated backwards (from the end),
forcing results in extra files only at the "deep" levels. Since files are
usually clustered together in directories, the addition of a dummy file per deep
directory should be inconsequential for performance.
TBD: integration level tests that this really work. I will either include that
later or in a separate CL.
Tested:
make pump-maintainer-check
build the Linux 2.6 kernel in true pump-mode (with extra patch, to be
described separately that sends compiler system files to the server) [all
files but a few towards the end suffer from absolute includes are
preprocessed and compiled on the compile servers!]
The command I used is:
DISTCC_EMAILLOG_WHOM_TO_BLAME=klarlund@google.com DISTCC_ENABLE_DISCREPANCY_EMAIL=1 INCLUDE_SERVER_ARGS='-d1 -t --email --stat_reset_triggers=include/linux/compile.h' DISTCC_HOSTS="--randomize `/home/klarlund/svn-distcc/distcc/lsdistcc -P3 -k100 -d`" PATH=/home/klarlund/svn-distcc/distcc:$PATH ./masquerade pump make -j120
I had to delete /usr/bin/distcc for this work, because of the PATH acrobatics
that the kernel makefiles apparently exercise. Otherwise, /usr/bin/distcc
would sometimes get called.
Reviewed:
fergus@google.com, csilvers@google.com
|
| |
|
|
|
|
|
| |
The test was implicitly assuming that /tmp == realpath(/tmp).
But in MacOS X, /tmp is a symbolic link to /private/tmp.
Reviewers: Craig Silverstein, Nils Klarlund
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
pump-mode.
An occurrence of say
#include "/usr/include/acl.h"
will normally force the include processor to abort (even when this include is
platform-specific and #ifdef'ed away), because there are no guarantees that the
file /usr/include/acl.h exists on the host. With this option, these includes
will be ignored.
A message like:
WARNING include server: absolute filepath '/usr/include/acl.h' was IGNORED (correctness of build may be affected)
will be printed.
The normal message raised when this option is off, the default, has been
modified. It now mentions the option.
An include server manual page is to follow, which explains the consequences in
detail of using this option.
Testing: this makes the samba-2.2.7 benchmark build without hiccups using distcc
pump. Without the change many compilations fail because the include server
bails out and because another unrelated bug in the include server makes it later
dish up with include closures that are too small.
Revievers: csilvers@google.com, fergus@google.com
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This required the following changes:
- Compute the default search paths for each language lazily,
when the language is first encountered, rather than
computing it for 'c' and 'c++'.
- Make the tests of Objective C and Objective C++
conditional on the relevant compiler being installed.
Tested by "make check" on two systems:
- One with Objective C installed, but not Objective C++.
- One with neither installed.
I didn't test on a system with Objective C++ installed,
because I didn't have one easily available.
Reviewers: Craig Silverstein, Nils Klarlund.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Set first parameter of gc.set_threshold to 10000 instead of default 700.
See comments in program text.
Notes
-----
I used a little script to find the include server timings as a function of this
parameter.
This script executes:
"DISTCC_PUMP_INSTALLATION=/tmp/distcc3.0 INCLUDE_SERVER_ARGS='-t --gc_threshold=700' \
/usr/bin/time -p make-dbg -j120 -r -experimental-ld -g0 gws:gws"
with various values of gc_threshold.
The measurement were done on a four processor system (dual Opterons), loaded
with an nxserver process. Files were served through Fuse.
gc include server user + sys time
setting
700 155.1s 154.0s 164.7s 186.1s 154.3s Mean: 162.8
10000 123.8s 125.4s 120.6s 120.4s 121.0s Mean: 122.2
100000 123.4s 123.3s 122.2s 123.3s 116.5s Mean: 121.7
700 166.5s 156.4s 150.8s 153.4s 155.4s Mean: 156.5
10000 120.7s 142.1s 118.3s 117.7s 119.2s Mean: 123.6
100000 140.3s 117.1s 149.7s 116.7s 141.6s Mean: 123.6
The corresponding elapsed times:
371.0s 363.3s 361.9s 370.8s 369.0s Mean: 367.2
341.8s 346.1s 336.3s 338.3s 340.5s Mean: 340.6
345.9s 338.5s 342.9s 374.4s 340.0s Mean: 348.3
377.4s 379.9s 387.1s 377.4s 373.2s Mean: 379.0
332.1s 337.7s 336.5s 332.2s 314.7s Mean: 330.6
341.1s 334.6s 357.8s 338.5s 352.4s Mean: 344.9
Note that the saving in include server time is around 35s, but the savings in
elapsed time is around 44s. These numbers are uncertain. Even so, they strongly
indicate that the include server is a signifcant bottleneck.
BTW, for comparison with plain distcc:
821.4s 822.0s 842.4s 821.5s 852.0s Mean: 831.9
878.7s 857.2s 860.3s 880.1s 856.0s Mean: 866.5
Thus, pump-mode 2.5X is faster than plain distcc (with the set_threshold =
10000 of this CL).
Revievers: fergus@google.com, csilvers@google.com
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
file names.
The symbol 'TESTING' is potentially unevaluated according to the
overapproximation semantics of the include server. So if this symbol is used in
a file name and if 'TESTING' really means 'testing' according to the OS and if
in fact 'testing' does exist as file, then there is trouble.
Revievewers: csilvers@google.com
Testing:
make include-server-maintainer-check (on Linux)
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
"Assume that:
(1) 'gcc' is a link to 'distcc' earlier on PATH than the real gcc.
(2) gcc is invoked; in fact that invokes distcc, which will rewrite
the PATH in src/climasq.c before invoking 'gcc' again.
That will make calls by distcc such as 'gcc -E' for preprocessing work
OK, but the include processor will in fact be calling the 'distcc' as
'gcc' again! But because the input argument is an I/O redirection,
distcc will then correctly call 'gcc'. In args.c it fails to recognize
an input file."
|
| |
|
|
|
|
|
|
|
|
|
|
| |
aggressively: in particular, we were clearing $PATH, which is needed
to find gcc when it's in an unusual location. Now we clear everything
but $PATH.
Tested by running 'make include-server-maintainer-check' on solaris
x86, which has gcc outside the standard path, and on linux (ubuntu),
which does not.
Reviewed by fergus@google.com
|
| |
|
|
| |
Reviewed by klarlund@google.com and fergus@google.com
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Tests:
I made PATH=$PATH:/usr/python/bin (where python2.5 resides on my machine). I ran
autogen and reconfigured. Then I did:
make include-server-maintainer-check
make pump-maintainer-check
and I made sure that -Is now are set according to Python2.5.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
to the ClientRootKeeper package in basics. Replace _RemoveDirectoryTree with
shutil function. Add tests to see that directories are created and deleted.
Add a couple of title headers to basics.py. Remove a couple of now irrelevant
comments.
Tests: make pump-maintainer-check
make include-server-maintainer-check
Reviewer: csilvers@google.com
|
| |
|
|
|
|
|
|
|
| |
is needed on systems that don't define asprintf/etc on their own.
Tested by running 'make check' on a linux ubuntu machine and on a
solaris machine.
Reviewed by fergus@google.com
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
which -- on linux FC5 at least -- gives warnings (which we turn into
errors via -Werror) on distcc code for libc functions where we ignore
the return value. Unfortunately, setup.py always uses the same flags
that python was compiled with on the local machine, so _FORTIFY_SOURCE
is always set when compiling distcc extensions via setup.py, and that
compilation fails.
Without getting into a philosophical debate about the merits of the
warn-unused warnings, we'd rather the code compile, so I turn off
_FORTIFY_SOURCE when it exists.
Tested by running 'make check' on a goobuntu machine (no
_FORTIFY_SOURCE) and an FC5 machine (with _FORTIFY_SOURCE).
Reviewed by fergus@google.com
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The code was lacked encapsulation and proper object-orientation. (I wrote it --
it had started out much simpler.) For example, key parameteres were
communicated through file name patterns expressed in file names on disk. These
patterns were then inferred from reading file names. Now the patterns are
properly abstracted away in a class.
There should be no semantic changes.
Testing:
make include-server-maintainer-check
make pump-maintainer-check
DISTCC_CLIENT_TMP='/tmp' make pump-maintainer-check
The latter test exercices the padding gymnastics.
|
| |
|
|
| |
Reviewed by fergus@google.com and klarlund@google.com
|
| |
|
|
|
|
|
|
|
|
| |
This option only affects the name of the ".d" file, not the include
closure, so the include server doesn't need to do anything for this
option; the actual handling of this option in distcc is done by the distcc
client, which already handles it correctly. This change just stops the
include server from throwing an exception whenever '-MF' is encountered.
Reviewers: Nils Klarlund
|
| |
|
|
|
|
| |
Reviewer: csilvers@google.com, fergus@google.com.
Tests: make pump-maintainer-check
make include-server-maintainer-check
|
| |
|
|
|
|
| |
Reviewers: csilvers@google.com, fergus@google.com
Tests: make include-server-maintainer-check
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The recent distcheck revealed that paths were set incorrectly for the setup.py
script. Also, as I dug deeper, it turned out that built files were placed in
the src directory (thanks to os.path.join I found in the distutil's source code,
that trips up the location if relative paths contains too many '..'s.). [The
distccheck revealed this!] I didn't like either that setup was run in the
source directory and not from the build directory (that's asking for trouble).
I did't like either that the search path, the list of includes, in setup.py was
handcoded and not simply that of CPPFLAGS. Finally, I was confused by _builddir
being another build directory under $(buildir). I renamed the former
_include_server to better explain its role.
So, I rewrote most of setup.py (correcting some of the documentation strings
along the way). Also, I partly removed the 'jumping through the hoops'
gymnastics from the Makefile.
TESTING: 'make distcheck'
REVIEWERS: csilvers, fergus
|
| |
|
|
|
|
|
| |
consequences.
TESTS: make distcheck
REVIEWER: fergus@google.com
|
| | |
|
| |
|
|
|
|
| |
-- Do TODOs.
-- Heed most pylint warnings.
|