Imported Upstream version 3.4 upstream/3.4
authorJinWang An <jinwang.an@samsung.com>
Tue, 3 Aug 2021 07:24:29 +0000 (16:24 +0900)
committerJinWang An <jinwang.an@samsung.com>
Tue, 3 Aug 2021 07:24:29 +0000 (16:24 +0900)
123 files changed:
AUTHORS.html
CONTRIBUTING.md [moved from HACKING.txt with 68% similarity]
LICENSE.html
LICENSE.txt
MANUAL.html
Makefile.in
NEWS.html
README.md
ccache.1
config.guess [changed mode: 0755->0644]
config.sub [changed mode: 0755->0644]
configure
configure.ac
dev.mk.in
doc/AUTHORS.txt [moved from AUTHORS.txt with 89% similarity]
doc/MANUAL.txt [moved from MANUAL.txt with 94% similarity]
doc/NEWS.txt [moved from NEWS.txt with 93% similarity]
src/args.c [moved from args.c with 100% similarity]
src/ccache.c [moved from ccache.c with 89% similarity]
src/ccache.h [moved from ccache.h with 96% similarity]
src/cleanup.c [moved from cleanup.c with 100% similarity]
src/compopt.c [moved from compopt.c with 90% similarity]
src/compopt.h [moved from compopt.h with 100% similarity]
src/conf.c [moved from conf.c with 96% similarity]
src/conf.h [moved from conf.h with 100% similarity]
src/confitems.gperf [moved from confitems.gperf with 100% similarity]
src/confitems_lookup.c [moved from confitems_lookup.c with 86% similarity]
src/counters.c [moved from counters.c with 100% similarity]
src/counters.h [moved from counters.h with 100% similarity]
src/envtoconfitems.gperf [moved from envtoconfitems.gperf with 100% similarity]
src/envtoconfitems_lookup.c [moved from envtoconfitems_lookup.c with 82% similarity]
src/execute.c [moved from execute.c with 98% similarity]
src/exitfn.c [moved from exitfn.c with 100% similarity]
src/getopt_long.c [moved from getopt_long.c with 100% similarity]
src/getopt_long.h [moved from getopt_long.h with 100% similarity]
src/hash.c [moved from hash.c with 100% similarity]
src/hashtable.c [moved from hashtable.c with 100% similarity]
src/hashtable.h [moved from hashtable.h with 100% similarity]
src/hashtable_itr.c [moved from hashtable_itr.c with 100% similarity]
src/hashtable_itr.h [moved from hashtable_itr.h with 100% similarity]
src/hashtable_private.h [moved from hashtable_private.h with 100% similarity]
src/hashutil.c [moved from hashutil.c with 100% similarity]
src/hashutil.h [moved from hashutil.h with 100% similarity]
src/language.c [moved from language.c with 100% similarity]
src/language.h [moved from language.h with 100% similarity]
src/lockfile.c [moved from lockfile.c with 98% similarity]
src/macroskip.h [moved from macroskip.h with 100% similarity]
src/main.c [moved from main.c with 100% similarity]
src/manifest.c [moved from manifest.c with 100% similarity]
src/manifest.h [moved from manifest.h with 100% similarity]
src/mdfour.c [moved from mdfour.c with 100% similarity]
src/mdfour.h [moved from mdfour.h with 100% similarity]
src/murmurhashneutral2.c [moved from murmurhashneutral2.c with 100% similarity]
src/murmurhashneutral2.h [moved from murmurhashneutral2.h with 100% similarity]
src/snprintf.c [moved from snprintf.c with 100% similarity]
src/stats.c [moved from stats.c with 92% similarity]
src/system.h [moved from system.h with 100% similarity]
src/unify.c [moved from unify.c with 95% similarity]
src/util.c [moved from util.c with 99% similarity]
src/version.c [new file with mode: 0644]
src/zlib/adler32.c [moved from zlib/adler32.c with 100% similarity]
src/zlib/crc32.c [moved from zlib/crc32.c with 100% similarity]
src/zlib/crc32.h [moved from zlib/crc32.h with 100% similarity]
src/zlib/deflate.c [moved from zlib/deflate.c with 100% similarity]
src/zlib/deflate.h [moved from zlib/deflate.h with 100% similarity]
src/zlib/gzclose.c [moved from zlib/gzclose.c with 100% similarity]
src/zlib/gzguts.h [moved from zlib/gzguts.h with 100% similarity]
src/zlib/gzlib.c [moved from zlib/gzlib.c with 100% similarity]
src/zlib/gzread.c [moved from zlib/gzread.c with 100% similarity]
src/zlib/gzwrite.c [moved from zlib/gzwrite.c with 100% similarity]
src/zlib/inffast.c [moved from zlib/inffast.c with 100% similarity]
src/zlib/inffast.h [moved from zlib/inffast.h with 100% similarity]
src/zlib/inffixed.h [moved from zlib/inffixed.h with 100% similarity]
src/zlib/inflate.c [moved from zlib/inflate.c with 100% similarity]
src/zlib/inflate.h [moved from zlib/inflate.h with 100% similarity]
src/zlib/inftrees.c [moved from zlib/inftrees.c with 100% similarity]
src/zlib/inftrees.h [moved from zlib/inftrees.h with 100% similarity]
src/zlib/trees.c [moved from zlib/trees.c with 100% similarity]
src/zlib/trees.h [moved from zlib/trees.h with 100% similarity]
src/zlib/zconf.h [moved from zlib/zconf.h with 100% similarity]
src/zlib/zlib.h [moved from zlib/zlib.h with 100% similarity]
src/zlib/zutil.c [moved from zlib/zutil.c with 100% similarity]
src/zlib/zutil.h [moved from zlib/zutil.h with 100% similarity]
test.sh [deleted file]
test/run [new file with mode: 0755]
test/suites/base.bash [new file with mode: 0644]
test/suites/basedir.bash [new file with mode: 0644]
test/suites/cleanup.bash [new file with mode: 0644]
test/suites/compression.bash [new file with mode: 0644]
test/suites/cpp1.bash [new file with mode: 0644]
test/suites/debug_prefix_map.bash [new file with mode: 0644]
test/suites/direct.bash [new file with mode: 0644]
test/suites/hardlink.bash [new file with mode: 0644]
test/suites/input_charset.bash [new file with mode: 0644]
test/suites/masquerading.bash [new file with mode: 0644]
test/suites/multi_arch.bash [new file with mode: 0644]
test/suites/nocpp2.bash [new file with mode: 0644]
test/suites/nvcc.bash [new file with mode: 0644]
test/suites/nvcc_direct.bash [new file with mode: 0644]
test/suites/nvcc_ldir.bash [new file with mode: 0644]
test/suites/nvcc_nocpp2.bash [new file with mode: 0644]
test/suites/pch.bash [new file with mode: 0644]
test/suites/readonly.bash [new file with mode: 0644]
test/suites/readonly_direct.bash [new file with mode: 0644]
test/suites/serialize_diagnostics.bash [new file with mode: 0644]
test/suites/upgrade.bash [new file with mode: 0644]
unittest/framework.c [moved from test/framework.c with 99% similarity]
unittest/framework.h [moved from test/framework.h with 98% similarity]
unittest/main.c [moved from test/main.c with 96% similarity]
unittest/suites.h [moved from test/suites.h with 100% similarity]
unittest/test_args.c [moved from test/test_args.c with 98% similarity]
unittest/test_argument_processing.c [moved from test/test_argument_processing.c with 94% similarity]
unittest/test_compopt.c [moved from test/test_compopt.c with 92% similarity]
unittest/test_conf.c [moved from test/test_conf.c with 98% similarity]
unittest/test_counters.c [moved from test/test_counters.c with 94% similarity]
unittest/test_hash.c [moved from test/test_hash.c with 96% similarity]
unittest/test_hashutil.c [moved from test/test_hashutil.c with 98% similarity]
unittest/test_lockfile.c [moved from test/test_lockfile.c with 96% similarity]
unittest/test_stats.c [moved from test/test_stats.c with 93% similarity]
unittest/test_util.c [moved from test/test_util.c with 98% similarity]
unittest/util.c [moved from test/util.c with 94% similarity]
unittest/util.h [moved from test/util.h with 100% similarity]
version.c [deleted file]

index b0d38b3..44e038e 100644 (file)
@@ -734,7 +734,7 @@ asciidoc.install(2);
 <body class="article">\r
 <div id="header">\r
 <h1>ccache authors</h1>\r
-<span id="revnumber">version 3.3.6</span>\r
+<span id="revnumber">version 3.4</span>\r
 <div id="toc">
   <div id="toctitle">Table of Contents</div>
   <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
@@ -804,17 +804,12 @@ Björn Jacke &lt;<a href="mailto:bj@sernet.de">bj@sernet.de</a>&gt;
 </li>\r
 <li>\r
 <p>\r
-Bo Rydberg &lt;<a href="mailto:bolry@hotmail.com">bolry@hotmail.com</a>&gt;\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
 Chiaki Ishikawa &lt;<a href="mailto:ishikawa@yk.rim.or.jp">ishikawa@yk.rim.or.jp</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Chris AtLee &lt;<a href="mailto:chris@atlee.ca">chris@atlee.ca</a>&gt;\r
+Chris AtLee &lt;<a href="mailto:catlee@mozilla.com">catlee@mozilla.com</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
@@ -834,17 +829,17 @@ Edward Z. Yang &lt;<a href="mailto:ezyang@fb.com">ezyang@fb.com</a>&gt;
 </li>\r
 <li>\r
 <p>\r
-Eric Blau &lt;<a href="mailto:Eric.Blau@tekelec.com">Eric.Blau@tekelec.com</a>&gt;\r
+Francois Marier &lt;<a href="mailto:francois@debian.org">francois@debian.org</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Francois Marier &lt;<a href="mailto:francois@debian.org">francois@debian.org</a>&gt;\r
+Geert Bosch &lt;<a href="mailto:geert@mongodb.com">geert@mongodb.com</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Geert Bosch &lt;<a href="mailto:geert@mongodb.com">geert@mongodb.com</a>&gt;\r
+Grigory Entin &lt;<a href="mailto:grigorye@dins.ru">grigorye@dins.ru</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
@@ -899,7 +894,7 @@ Karl Chen &lt;<a href="mailto:quarl@cs.berkeley.edu">quarl@cs.berkeley.edu</a>&g
 </li>\r
 <li>\r
 <p>\r
-KonaBlend &lt;<a href="mailto:kona8lend@gmail.com">kona8lend@gmail.com</a>&gt;\r
+Kona Blend &lt;<a href="mailto:kona8lend@gmail.com">kona8lend@gmail.com</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
@@ -934,11 +929,21 @@ Mark Starovoytov &lt;<a href="mailto:starovoytov.mark@googlemail.com">starovoyto
 </li>\r
 <li>\r
 <p>\r
+Martin Ettl &lt;<a href="mailto:ettl.martin78@gmail.com">ettl.martin78@gmail.com</a>&gt;\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
 Martin Pool &lt;<a href="mailto:mbp@sourcefrog.net">mbp@sourcefrog.net</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
+Mathias De Maré &lt;<a href="mailto:mathias.de_mare@nokia.com">mathias.de_mare@nokia.com</a>&gt;\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
 Matthias Kretz &lt;<a href="mailto:kretz@kde.org">kretz@kde.org</a>&gt;\r
 </p>\r
 </li>\r
@@ -974,27 +979,27 @@ Mikhail Kolomeytsev &lt;<a href="mailto:mkolom@yandex-team.ru">mkolom@yandex-tea
 </li>\r
 <li>\r
 <p>\r
-Neil Mushell &lt;<a href="mailto:nmushell@bloomberg.net">nmushell@bloomberg.net</a>&gt;\r
+Mostyn Bramley-Moore &lt;<a href="mailto:mostyn@antipode.se">mostyn@antipode.se</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Nick Schultz &lt;<a href="mailto:nick.schultz@intel.com">nick.schultz@intel.com</a>&gt;\r
+Neil Mushell &lt;<a href="mailto:nmushell@bloomberg.net">nmushell@bloomberg.net</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Norbert Lange &lt;<a href="mailto:nolange79@gmail.com">nolange79@gmail.com</a>&gt;\r
+Nick Schultz &lt;<a href="mailto:nick.schultz@intel.com">nick.schultz@intel.com</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Oded Shimon &lt;<a href="mailto:oded@istraresearch.com">oded@istraresearch.com</a>&gt;\r
+Norbert Lange &lt;<a href="mailto:nolange79@gmail.com">nolange79@gmail.com</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-orbitcowboy &lt;<a href="mailto:ettl.martin78@gmail.com">ettl.martin78@gmail.com</a>&gt;\r
+Oded Shimon &lt;<a href="mailto:oded@istraresearch.com">oded@istraresearch.com</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
@@ -1029,6 +1034,11 @@ Pavel Boldin &lt;<a href="mailto:pboldin@cloudlinux.com">pboldin@cloudlinux.com<
 </li>\r
 <li>\r
 <p>\r
+Per Nordlöw &lt;<a href="mailto:per.nordlow@autoliv.com">per.nordlow@autoliv.com</a>&gt;\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
 Philippe Proulx &lt;<a href="mailto:eeppeliteloop@gmail.com">eeppeliteloop@gmail.com</a>&gt;\r
 </p>\r
 </li>\r
@@ -1059,6 +1069,16 @@ Ryan Brown &lt;<a href="mailto:ryb@ableton.com">ryb@ableton.com</a>&gt;
 </li>\r
 <li>\r
 <p>\r
+Sam Gross &lt;<a href="mailto:sgross@fb.com">sgross@fb.com</a>&gt;\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Thomas Röfer &lt;<a href="mailto:Thomas.Roefer@dfki.de">Thomas.Roefer@dfki.de</a>&gt;\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
 Tim Potter &lt;<a href="mailto:tpot@samba.org">tpot@samba.org</a>&gt;\r
 </p>\r
 </li>\r
@@ -1105,9 +1125,9 @@ Yiding Jia &lt;<a href="mailto:yiding@fb.com">yiding@fb.com</a>&gt;
 <div id="footnotes"><hr /></div>\r
 <div id="footer">\r
 <div id="footer-text">\r
-Version 3.3.6<br />\r
+Version 3.4<br />\r
 Last updated\r
- 2018-01-28 16:21:55 CET\r
+ 2018-02-11 15:24:06 CET\r
 </div>\r
 </div>\r
 </body>\r
similarity index 68%
rename from HACKING.txt
rename to CONTRIBUTING.md
index 50ed26f..0147aa7 100644 (file)
@@ -1,8 +1,68 @@
-Hacking ccache
-==============
+# Contributing to ccache
 
-Code formatting
----------------
+Want to contribute to ccache? Awesome!
+
+## Asking a question?
+
+It's OK to ask questions in the issue tracker for now.
+
+However, please consider posting your question to the
+[mailing list](https://lists.samba.org/mailman/listinfo/ccache/) instead, since
+you are more likely to get an answer there.
+
+## Reporting an issue?
+
+Please include at least the following information in your bug report:
+
+1. Which version of ccache you use.
+2. Which compiler you use, if applicable.
+3. Which operating system you use, if applicable.
+4. The problematic behavior you experienced (_actual behavior_).
+5. How you would like ccache to behave instead (_expected behavior_).
+6. Steps to reproduce the problematic behavior.
+
+Also, consider reading [Effective Ways to Get Help from Maintainers](
+https://www.snoyman.com/blog/2017/10/effective-ways-help-from-maintainers).
+
+
+## Contributing code?
+
+Great! You can create a pull request with your proposal on github, or you could
+post one or several patches to the
+[mailing list](https://lists.samba.org/mailman/listinfo/ccache/).
+
+### How to write commit messages
+
+* Write a summary (short description) on the first line.
+* Start the summary with a capital letter. Optional: prefix the short
+  description with a context followed by a colon.
+* The summary should be in imperative mood (see examples below).
+* The summary should not end with a period. It's a title and titles don't end
+  with a period.
+* If a longer description is wanted, add a second line empty and write the
+  longer description on line three and below.
+* Keep lines in the message at most 72 characters wide.
+
+Example 1:
+
+    Hash a delimiter string between parts to separate them
+
+    Previously, "gcc -I-O2 -c file.c" and "gcc -I -O2 -c file.c" would hash
+    to the same sum.
+
+Example 2:
+
+    win32: Add a space between filename and error string in x_fmmap()
+
+See also:
+
+* http://stopwritingramblingcommitmessages.com
+* http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
+* https://github.com/erlang/otp/wiki/Writing-good-commit-messages
+
+### Code style
+
+#### Formatting
 
 * Use tabs for indenting and spaces for aligning C code.
 * Use 4 spaces for indenting other code (and spaces for aligning).
@@ -22,8 +82,7 @@ Code formatting
 Tip: Install the tool uncrustify <http://uncrustify.sourceforge.net> and then
 run "make uncrustify" to fix up source code formatting.
 
-Idioms
-------
+#### Idioms
 
 * Declare variables as late as convenient, not necessarily at the beginning of
   the scope.
@@ -37,38 +96,7 @@ Idioms
 * Use tmp_unlink() or x_unlink() instead of unlink().
 * Use x_rename() instead of rename().
 
-Other
------
+#### Other
 
 * Strive to minimize use of global variables.
 * Write test cases for new code.
-
-Commit messages
----------------
-
-* Write a summary (short description) on the first line.
-* Start the summary with a capital letter. Optional: prefix the short
-  description with a context followed by a colon.
-* The summary should be in imperative mood (see examples below).
-* The summary should not end with a period. It's a title and titles don't end
-  with a period.
-* If a longer description is wanted, add a second line empty and write the
-  longer description on line three and below.
-* Keep lines in the message at most 72 characters wide.
-
-Example 1:
-
-    Hash a delimiter string between parts to separate them
-
-    Previously, "gcc -I-O2 -c file.c" and "gcc -I -O2 -c file.c" would hash
-    to the same sum.
-
-Example 2:
-
-    win32: Add a space between filename and error string in x_fmmap()
-
-See also:
-
-* http://stopwritingramblingcommitmessages.com
-* http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
-* https://github.com/erlang/otp/wiki/Writing-good-commit-messages
index 0673b9c..af6e0e8 100644 (file)
@@ -734,7 +734,7 @@ asciidoc.install(2);
 <body class="article">\r
 <div id="header">\r
 <h1>ccache copyright and license</h1>\r
-<span id="revnumber">version 3.3.5+dirty</span>\r
+<span id="revnumber">version 3.4</span>\r
 <div id="toc">
   <div id="toctitle">Table of Contents</div>
   <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
@@ -789,7 +789,7 @@ may qualify as &#8220;separate and independent works in themselves&#8221; for pu
 the GPL: that is, if separated from the ccache sources, they may be usable\r
 under less restrictive terms.</p></div>\r
 <div class="sect2">\r
-<h3 id="_getopt_long_hc">getopt_long.[hc]</h3>\r
+<h3 id="_src_getopt_long_hc">src/getopt_long.[hc]</h3>\r
 <div class="paragraph"><p>This implementation of <code>getopt_long()</code> was copied from\r
 <a href="http://www.postgresql.org">PostgreSQL</a> and has the following license text:</p></div>\r
 <div class="listingblock">\r
@@ -826,7 +826,7 @@ under less restrictive terms.</p></div>
 </div></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_hashtable_hc">hashtable*.[hc]</h3>\r
+<h3 id="_src_hashtable_hc">src/hashtable*.[hc]</h3>\r
 <div class="paragraph"><p>This code comes from <a href="http://www.cl.cam.ac.uk/~cwc22/hashtable/">http://www.cl.cam.ac.uk/~cwc22/hashtable/</a> with the\r
 following license:</p></div>\r
 <div class="listingblock">\r
@@ -1144,12 +1144,12 @@ following license:</p></div>
 </div></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_murmurhashneutral2_hc">murmurhashneutral2.[hc]</h3>\r
+<h3 id="_src_murmurhashneutral2_hc">src/murmurhashneutral2.[hc]</h3>\r
 <div class="paragraph"><p>This fast hash implementation is released to the public domain by Austin\r
 Appleby. See <a href="http://murmurhash.googlepages.com">http://murmurhash.googlepages.com</a>.</p></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_snprintf_c_and_m4_snprintf_m4">snprintf.c and m4/snprintf.m4</h3>\r
+<h3 id="_src_snprintf_c_and_m4_snprintf_m4">src/snprintf.c and m4/snprintf.m4</h3>\r
 <div class="paragraph"><p>This implementation of <code>snprintf()</code> and similar functions was downloaded from\r
 <a href="http://www.jhweiss.de/software/snprintf.html">http://www.jhweiss.de/software/snprintf.html</a> and has the following license:</p></div>\r
 <div class="listingblock">\r
@@ -1172,7 +1172,7 @@ Appleby. See <a href="http://murmurhash.googlepages.com">http://murmurhash.googl
 </div></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_zlib_hc">zlib/*.[hc]</h3>\r
+<h3 id="_src_zlib_hc">src/zlib/*.[hc]</h3>\r
 <div class="paragraph"><p>This is a bundled subset of zlib 1.2.8 from <a href="http://zlib.net">http://zlib.net</a> with the\r
 following license:</p></div>\r
 <div class="listingblock">\r
@@ -1205,9 +1205,9 @@ following license:</p></div>
 <div id="footnotes"><hr /></div>\r
 <div id="footer">\r
 <div id="footer-text">\r
-Version 3.3.5+dirty<br />\r
+Version 3.4<br />\r
 Last updated\r
- 2018-01-13 19:38:26 CET\r
+ 2018-02-06 22:28:44 CET\r
 </div>\r
 </div>\r
 </body>\r
index 316fb81..73a4522 100644 (file)
@@ -52,8 +52,8 @@ the GPL: that is, if separated from the ccache sources, they may be usable
 under less restrictive terms.
 
 
-getopt_long.[hc]
-~~~~~~~~~~~~~~~~
+src/getopt_long.[hc]
+~~~~~~~~~~~~~~~~~~~~
 
 This implementation of `getopt_long()` was copied from
 http://www.postgresql.org[PostgreSQL] and has the following license text:
@@ -91,8 +91,8 @@ http://www.postgresql.org[PostgreSQL] and has the following license text:
 -------------------------------------------------------------------------------
 
 
-hashtable*.[hc]
-~~~~~~~~~~~~~~~
+src/hashtable*.[hc]
+~~~~~~~~~~~~~~~~~~~
 
 This code comes from http://www.cl.cam.ac.uk/~cwc22/hashtable/ with the
 following license:
@@ -413,15 +413,15 @@ This Autoconf M4 snippet comes from http://www.python.org[Python] 2.6's
 -------------------------------------------------------------------------------
 
 
-murmurhashneutral2.[hc]
-~~~~~~~~~~~~~~~~~~~~~~~
+src/murmurhashneutral2.[hc]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 This fast hash implementation is released to the public domain by Austin
 Appleby. See http://murmurhash.googlepages.com.
 
 
-snprintf.c and m4/snprintf.m4
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src/snprintf.c and m4/snprintf.m4
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 This implementation of `snprintf()` and similar functions was downloaded from
 http://www.jhweiss.de/software/snprintf.html and has the following license:
@@ -445,8 +445,8 @@ http://www.jhweiss.de/software/snprintf.html and has the following license:
 -------------------------------------------------------------------------------
 
 
-zlib/*.[hc]
-~~~~~~~~~~~
+src/zlib/*.[hc]
+~~~~~~~~~~~~~~~
 
 This is a bundled subset of zlib 1.2.8 from <http://zlib.net> with the
 following license:
index 5b0c105..71c4b5a 100644 (file)
@@ -734,7 +734,7 @@ asciidoc.install(2);
 <body class="article">\r
 <div id="header">\r
 <h1>CCACHE(1)</h1>\r
-<span id="revnumber">version 3.3.6</span>\r
+<span id="revnumber">version 3.4</span>\r
 <div id="toc">
   <div id="toctitle">Table of Contents</div>
   <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
@@ -800,11 +800,6 @@ Low overhead.
 </li>\r
 <li>\r
 <p>\r
-Optionally uses hard links where possible to avoid copies.\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
 Optionally compresses files in the cache to reduce disk space.\r
 </p>\r
 </li>\r
@@ -1066,11 +1061,13 @@ max_size = 10G</code></pre>
 <div class="paragraph"><p>Some settings are boolean values (i.e. truth values). In a configuration file,\r
 such values must be set to the string <strong>true</strong> or <strong>false</strong>. For the corresponding\r
 environment variables, the semantics are a bit different: a set environment\r
-variable means &#8220;true&#8221; regardless of the value (even if set to the empty\r
-string), and an unset environment variable means &#8220;false&#8221;. Each boolean\r
-environment variable also has a negated form starting with <strong>CCACHE_NO</strong>. For\r
-example, <strong>CCACHE_COMPRESS</strong> can be set to force compression and\r
-<strong>CCACHE_NOCOMPRESS</strong> can be set to force no compression.</p></div>\r
+variable means &#8220;true&#8221; (even if set to the empty string), the following\r
+case-insensitive negative values are considered an error (rather than\r
+surprising the user): <strong>0</strong>, <strong>false</strong>, <strong>disable</strong> and <strong>no</strong>, and an unset\r
+environment variable means &#8220;false&#8221;. Each boolean environment variable also\r
+has a negated form starting with <strong>CCACHE_NO</strong>. For example, <strong>CCACHE_COMPRESS</strong>\r
+can be set to force compression and <strong>CCACHE_NOCOMPRESS</strong> can be set to force no\r
+compression.</p></div>\r
 </div>\r
 <div class="sect2">\r
 <h3 id="_configuration_settings">Configuration settings</h3>\r
@@ -1283,14 +1280,39 @@ the <strong>prefix_command</strong> setting if possible. See
 <dd>\r
 <p>\r
     If true, ccache will attempt to use hard links from the cache directory\r
-    when creating the compiler output rather than using a file copy. Using hard\r
-    links may be slightly faster in some situations, but can confuse programs\r
-    like &#8220;make&#8221; that rely on modification times. Another thing to keep in\r
-    mind is that if the resulting object file is modified in any way, this\r
-    corrupts the cached object file as well. Hard links are never made for\r
-    compressed cache files. This means that you should not enable compression\r
-    if you want to use hard links. The default is false.\r
+    when creating the compiler output rather than using a file copy. Hard links\r
+    are never made for compressed cache files. This means that you should not\r
+    enable compression if you want to use hard links. The default is false.\r
 </p>\r
+<div class="admonitionblock">\r
+<table><tr>\r
+<td class="icon">\r
+<div class="title">Warning</div>\r
+</td>\r
+<td class="content">Do not enable this option unless you are aware of the consequences.\r
+Using hard links may be slightly faster in some situations, but there are\r
+several pitfalls since the resulting object file will share i-node with the\r
+cached object file:</td>\r
+</tr></table>\r
+</div>\r
+<div class="olist arabic"><ol class="arabic">\r
+<li>\r
+<p>\r
+If the resulting object file is modified in any way, the cached object file\r
+   will be modified as well. For instance, if you run <strong>strip object.o</strong> or <strong>echo\r
+   &gt;object.o</strong>, you will corrupt the cache.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Programs that rely on modification times (like &#8220;make&#8221;) can be confused\r
+   since ccache updates the cached files' modification times as part of the\r
+   automatic cache size management. This will affect object files in the build\r
+   tree as well, which can retrigger the linking step even though nothing\r
+   really has changed.\r
+</p>\r
+</li>\r
+</ol></div>\r
 </dd>\r
 <dt class="hdlist1">\r
 <strong>hash_dir</strong> (<strong>CCACHE_HASHDIR</strong> or <strong>CCACHE_NOHASHDIR</strong>, see <a href="#_boolean_values">Boolean values</a> above)\r
@@ -1451,6 +1473,12 @@ of the original source code. This makes cache misses slightly faster since the
 source code only has to be preprocessed once. The downside is that some\r
 compilers won&#8217;t produce the same result (for instance diagnostics warnings)\r
 when compiling preprocessed source code.</p></div>\r
+<div class="paragraph"><p>A solution to the above mentioned downside is to set <strong>run_second_cpp</strong> to false\r
+and pass <strong>-fdirectives-only</strong> (for GCC) or <strong>-frewrite-includes</strong> (for Clang) to\r
+the compiler. This will cause the compiler to leave the macros and other\r
+preprocessor information, and only process the <strong>#include</strong> directives. When run\r
+in this way, the preprocessor arguments will be passed to the compiler since it\r
+still has to do <em>some</em> preprocessing (like macros).</p></div>\r
 </dd>\r
 <dt class="hdlist1">\r
 <strong>sloppiness</strong> (<strong>CCACHE_SLOPPINESS</strong>)\r
@@ -1586,8 +1614,7 @@ information.</p></div>
     unifier changes the hash, so cached compilations produced when the unifier\r
     is enabled cannot be reused when the unifier is disabled, and vice versa.\r
     Enabling the unifier may result in incorrect line number information in\r
-    compiler warning messages and expansions of the <strong>__LINE__</strong> macro. Also\r
-    note that enabling the unifier implies turning off the direct mode.\r
+    compiler warning messages and expansions of the <strong>__LINE__</strong> macro.\r
 </p>\r
 </dd>\r
 </dl></div>\r
@@ -1935,11 +1962,6 @@ a modification time of one of the include files is too new (needed to avoid a
 </li>\r
 <li>\r
 <p>\r
-the unifier is enabled (the configuration setting <strong>unify</strong> is true)\r
-</p>\r
-</li>\r
-<li>\r
-<p>\r
 a compiler option not supported by the direct mode is used:\r
 </p>\r
 <div class="ulist"><ul>\r
@@ -2234,6 +2256,27 @@ The direct mode fails to pick up new header files in some rare scenarios. See
   <a href="#_the_direct_mode">THE DIRECT MODE</a> above.\r
 </p>\r
 </li>\r
+<li>\r
+<p>\r
+When run via ccache, warning messages produced by GCC 4.9 and newer will only\r
+  be colored when the environment variable <strong>GCC_COLORS</strong> is set. An alternative\r
+  to setting <strong>GCC_COLORS</strong> is to pass <code>-fdiagnostics-color</code> explicitly when\r
+  compiling (but then color codes will also be present when redirecting stderr\r
+  to a file).\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+If ccache guesses that the compiler may emit colored warnings, then a\r
+  compilation with stderr referring to a TTY will be considered different from\r
+  a compilation with a redirected stderr, thus not sharing cache entries. This\r
+  happens for clang by default and for GCC when <strong>GCC_COLORS</strong> is set as\r
+  mentioned above. If you want to share cache hits, you can pass\r
+  <code>-f[no-]diagnostics-color</code> (GCC) or <code>-f[no-]color-diagnostics</code> (clang)\r
+  explicitly when compiling (but then color codes will be either on or off for\r
+  both the TTY and the redirected case).\r
+</p>\r
+</li>\r
 </ul></div>\r
 </div>\r
 </div>\r
@@ -2431,9 +2474,9 @@ maintained by Joel Rosdahl. See AUTHORS.txt or AUTHORS.html and
 <div id="footnotes"><hr /></div>\r
 <div id="footer">\r
 <div id="footer-text">\r
-Version 3.3.6<br />\r
+Version 3.4<br />\r
 Last updated\r
- 2018-01-28 16:20:40 CET\r
+ 2018-02-06 21:44:11 CET\r
 </div>\r
 </div>\r
 </body>\r
index 5aee02d..e414e87 100644 (file)
@@ -10,6 +10,7 @@ sysconfdir = @sysconfdir@
 installcmd = @INSTALL@
 
 AR = @AR@
+BASH = @BASH@
 CC = @CC@
 CFLAGS = @CFLAGS@
 CPPFLAGS = @CPPFLAGS@
@@ -19,38 +20,38 @@ LIBS = @LIBS@
 RANLIB = @RANLIB@
 
 all_cflags = $(CFLAGS)
-all_cppflags = @DEFS@ -DSYSCONFDIR=$(sysconfdir) -I. -I$(srcdir) $(CPPFLAGS)
+all_cppflags = @DEFS@ -DSYSCONFDIR=$(sysconfdir) -I. -I$(srcdir)/src $(CPPFLAGS)
 extra_libs = @extra_libs@
 
 non_3pp_sources = \
-    args.c \
-    ccache.c \
-    cleanup.c \
-    compopt.c \
-    conf.c \
-    counters.c \
-    execute.c \
-    exitfn.c \
-    hash.c \
-    hashutil.c \
-    language.c \
-    lockfile.c \
-    manifest.c \
-    mdfour.c \
-    stats.c \
-    unify.c \
-    util.c \
-    version.c
+    src/args.c \
+    src/ccache.c \
+    src/cleanup.c \
+    src/compopt.c \
+    src/conf.c \
+    src/counters.c \
+    src/execute.c \
+    src/exitfn.c \
+    src/hash.c \
+    src/hashutil.c \
+    src/language.c \
+    src/lockfile.c \
+    src/manifest.c \
+    src/mdfour.c \
+    src/stats.c \
+    src/unify.c \
+    src/util.c \
+    src/version.c
 3pp_sources = \
-    getopt_long.c \
-    hashtable.c \
-    hashtable_itr.c \
-    murmurhashneutral2.c \
-    snprintf.c
+    src/getopt_long.c \
+    src/hashtable.c \
+    src/hashtable_itr.c \
+    src/murmurhashneutral2.c \
+    src/snprintf.c
 base_sources = $(non_3pp_sources) $(3pp_sources)
 base_objs = $(base_sources:.c=.o)
 
-ccache_sources = main.c $(base_sources)
+ccache_sources = src/main.c $(base_sources)
 ccache_objs = $(ccache_sources:.c=.o)
 
 zlib_sources = \
@@ -60,13 +61,14 @@ zlib_sources = \
 zlib_objs = $(zlib_sources:.c=.o)
 
 test_suites = @test_suites@
-test_sources = test/main.c test/framework.c test/util.c $(test_suites)
+test_sources = unittest/main.c unittest/framework.c unittest/util.c
+test_sources += $(test_suites)
 test_objs = $(test_sources:.c=.o)
 
 all_sources = $(ccache_sources) $(test_sources)
 all_objs = $(ccache_objs) $(test_objs) $(zlib_objs)
 
-files_to_clean = $(all_objs) ccache$(EXEEXT) test/main$(EXEEXT) *~ testdir.*
+files_to_clean = $(all_objs) ccache$(EXEEXT) unittest/run$(EXEEXT) *~ testdir.*
 files_to_distclean = Makefile config.h config.log config.status
 
 .PHONY: all
@@ -96,23 +98,23 @@ zlib/libz.a: $(zlib_objs)
 
 .PHONY: perf
 perf: ccache$(EXEEXT)
-       $(srcdir)/perf.py --ccache ccache$(EXEEXT) $(CC) $(all_cppflags) $(all_cflags) $(srcdir)/ccache.c
+       $(srcdir)/perf/perf.py --ccache ccache$(EXEEXT) $(CC) $(all_cppflags) $(all_cflags) $(srcdir)/src/ccache.c
 
 .PHONY: test
-test: ccache$(EXEEXT) test/main$(EXEEXT)
-       test/main$(EXEEXT)
-       CC='$(CC)' $(srcdir)/test.sh
+test: ccache$(EXEEXT) unittest/run$(EXEEXT)
+       unittest/run$(EXEEXT)
+       CC='$(CC)' $(BASH) $(srcdir)/test/run
 
-.PHONY: quicktest
-quicktest: test/main$(EXEEXT)
-       test/main$(EXEEXT)
+.PHONY: unittest
+unittest: unittest/run$(EXEEXT)
+       unittest/run$(EXEEXT)
 
-test/main$(EXEEXT): $(base_objs) $(test_objs) $(extra_libs)
+unittest/run$(EXEEXT): $(base_objs) $(test_objs) $(extra_libs)
        $(CC) $(all_cflags) -o $@ $(base_objs) $(test_objs) $(LDFLAGS) $(extra_libs) $(LIBS)
 
-test/main.o: test/suites.h
+unittest/main.o: unittest/suites.h
 
-test/suites.h: $(test_suites) Makefile
+unittest/suites.h: $(test_suites) Makefile
        sed -n 's/TEST_SUITE(\(.*\))/SUITE(\1)/p' $(test_suites) >$@
 
 .PHONY: check
@@ -123,9 +125,9 @@ distclean: clean
        rm -rf $(files_to_distclean)
 
 .PHONY: installcheck
-installcheck: ccache$(EXEEXT) test/main$(EXEEXT)
-       test/main$(EXEEXT)
-       CCACHE=$(bindir)/ccache CC='$(CC)' $(srcdir)/test.sh
+installcheck: ccache$(EXEEXT) unittest/run$(EXEEXT)
+       unittest/run$(EXEEXT)
+       CCACHE=$(bindir)/ccache CC='$(CC)' $(BASH) $(srcdir)/test/run
 
 .c.o:
        $(CC) $(all_cppflags) $(all_cflags) -c -o $@ $<
index 396f60d..0e60bf1 100644 (file)
--- a/NEWS.html
+++ b/NEWS.html
@@ -734,7 +734,7 @@ asciidoc.install(2);
 <body class="article">\r
 <div id="header">\r
 <h1>ccache news</h1>\r
-<span id="revnumber">version 3.3.6</span>\r
+<span id="revnumber">version 3.4</span>\r
 <div id="toc">
   <div id="toctitle">Table of Contents</div>
   <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
@@ -742,11 +742,108 @@ asciidoc.install(2);
 </div>\r
 <div id="content">\r
 <div class="sect1">\r
+<h2 id="_ccache_3_4">ccache 3.4</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>Release date: 2018-02-11</p></div>\r
+<div class="sect2">\r
+<h3 id="_new_features_and_enhancements">New features and enhancements</h3>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+The compiler option form <code>--sysroot arg</code> is now handled like the documented\r
+  <code>--sysroot=arg</code> form.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Added support for caching <code>.su</code> files generated by GCC flag <code>-fstack-usage</code>.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+ccache should now work with distcc&#8217;s &#8220;pump&#8221; wrapper.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+The optional unifier is no longer disabled when the direct mode is enabled.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Added support for nvcc compiler options <code>--compiler-bindir/-ccbin</code>,\r
+  <code>--output-directory/-odir</code> and <code>--libdevice-directory/-ldir</code>.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Boolean environment variable settings no longer accept the following\r
+  (case-insensitive) values: <code>0</code>, <code>false</code>, <code>disable</code> and <code>no</code>. All other values\r
+  are accepted and taken to mean &#8220;true&#8221;. This is to stop users from setting\r
+  e.g. <code>CCACHE_DISABLE=0</code> and then expect the cache to be used.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Improved support for <code>run_second_cpp = false</code>: If combined with passing\r
+  <code>-fdirectives-only</code> (GCC) or <code>frewrite-includes</code> (Clang) to the compiler,\r
+  diagnostics warnings and similar will be correct.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+An implicit <code>-MQ</code> is now passed to the preprocessor only if the object file\r
+  extension is non-standard. This should make it easier to use EDG-based\r
+  compilers (e.g. GHS) which don&#8217;t understand <code>-MQ</code>.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+ccache now treats an unreadable configuration file just like a missing\r
+  configuration file.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Documented more pitfalls with enabling <code>hard_links</code> (<code>CCACHE_HARDLINK</code>).\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Documented caveats related to colored warnings from compilers.\r
+</p>\r
+</li>\r
+</ul></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_bug_fixes">Bug fixes</h3>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+File size and number counters are now updated correctly when files are\r
+  overwritten in the cache, e.g. when using <code>CCACHE_RECACHE</code>.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>run_second_cpp</code> is now forced for nvcc.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Fixed how the nvcc options <code>-optf</code> and <code>-odir</code> are handled.\r
+</p>\r
+</li>\r
+</ul></div>\r
+</div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
 <h2 id="_ccache_3_3_6">ccache 3.3.6</h2>\r
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2018-01-28</p></div>\r
 <div class="sect2">\r
-<h3 id="_new_features_and_improvements">New features and improvements</h3>\r
+<h3 id="_new_features_and_enhancements_2">New features and enhancements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -757,7 +854,7 @@ Improved instructions on how to get cache hits between different working
 </ul></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes">Bug fixes</h3>\r
+<h3 id="_bug_fixes_2">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -773,7 +870,7 @@ Fixed regression in ccache 3.3.5 related to the <code>UNCACHED_ERR_FD</code> fea
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2018-01-13</p></div>\r
 <div class="sect2">\r
-<h3 id="_new_features_and_improvements_2">New features and improvements</h3>\r
+<h3 id="_new_features_and_enhancements_3">New features and enhancements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -783,7 +880,7 @@ Documented how automatic cache cleanup works.
 </ul></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_2">Bug fixes</h3>\r
+<h3 id="_bug_fixes_3">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -856,7 +953,7 @@ Fixed a bug where ccache would skip hashing the compiler argument following a
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2017-02-17</p></div>\r
 <div class="sect2">\r
-<h3 id="_new_features_and_improvements_3">New features and improvements</h3>\r
+<h3 id="_new_features_and_enhancements_4">New features and enhancements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -866,7 +963,7 @@ Documented the different cache statistics counters.
 </ul></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_3">Bug fixes</h3>\r
+<h3 id="_bug_fixes_4">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -896,7 +993,7 @@ Fixed undefined behavior warnings in ccache found by <code>-fsanitize=undefined<
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2016-10-26</p></div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_4">Bug fixes</h3>\r
+<h3 id="_bug_fixes_5">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -913,7 +1010,7 @@ ccache now detects usage of <code>.incbin</code> assembler directives in the sou
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2016-09-28</p></div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_5">Bug fixes</h3>\r
+<h3 id="_bug_fixes_6">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -938,7 +1035,7 @@ Fixed a regression in ccache 3.3.1: ccache could get confused when using the
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2016-09-07</p></div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_6">Bug fixes</h3>\r
+<h3 id="_bug_fixes_7">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -973,7 +1070,7 @@ A C99-compatible compiler is now required to build ccache.
 </ul></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_new_features_and_improvements_4">New features and improvements</h3>\r
+<h3 id="_new_features_and_enhancements_5">New features and enhancements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1120,7 +1217,7 @@ Increased buffer size used when reading file data. This improves performance
 </ul></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_7">Bug fixes</h3>\r
+<h3 id="_bug_fixes_8">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1146,7 +1243,7 @@ Fixed build and test for MinGW32 and Windows.
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2016-09-28</p></div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_8">Bug fixes</h3>\r
+<h3 id="_bug_fixes_9">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1164,7 +1261,7 @@ Fixed a regression in ccache 3.2.8: ccache could get confused when using the
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2016-09-07</p></div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_9">Bug fixes</h3>\r
+<h3 id="_bug_fixes_10">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1188,7 +1285,7 @@ ccache now understands the undocumented <code>-coverage</code> (only one dash) G
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2016-07-20</p></div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_10">Bug fixes</h3>\r
+<h3 id="_bug_fixes_11">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1211,7 +1308,7 @@ ccache now knows how to work around a glitch in the output of GCC 6&#8217;s
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2016-07-12</p></div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_11">Bug fixes</h3>\r
+<h3 id="_bug_fixes_12">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1240,7 +1337,7 @@ Fixed a bug where (due to ccache rewriting paths) the compiler could choose
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2016-04-17</p></div>\r
 <div class="sect2">\r
-<h3 id="_new_features_and_improvements_5">New features and improvements</h3>\r
+<h3 id="_new_features_and_enhancements_6">New features and enhancements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1261,7 +1358,7 @@ Made it harder to misinterpret documentation of boolean environment settings'
 </ul></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_12">Bug fixes</h3>\r
+<h3 id="_bug_fixes_13">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1321,7 +1418,7 @@ The man page is now built when running &#8220;make install&#8221; from Git repos
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2015-10-08</p></div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_13">Bug fixes</h3>\r
+<h3 id="_bug_fixes_14">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1366,7 +1463,7 @@ Fixed a bug where cache cleanup could be run too early for caches larger than
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2015-08-16</p></div>\r
 <div class="sect2">\r
-<h3 id="_new_features_and_improvements_6">New features and improvements</h3>\r
+<h3 id="_new_features_and_enhancements_7">New features and enhancements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1376,7 +1473,7 @@ Added support for compiler option <code>-gsplit-dwarf</code>.
 </ul></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_14">Bug fixes</h3>\r
+<h3 id="_bug_fixes_15">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1413,7 +1510,7 @@ Only log "Disabling direct mode" once when failing to read potential include
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2015-05-10</p></div>\r
 <div class="sect2">\r
-<h3 id="_new_features_and_improvements_7">New features and improvements</h3>\r
+<h3 id="_new_features_and_enhancements_8">New features and enhancements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1430,7 +1527,7 @@ Add support for caching code coverage results (compiling for gcov).
 </ul></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_15">Bug fixes</h3>\r
+<h3 id="_bug_fixes_16">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1501,7 +1598,7 @@ Fixed build error when compiling ccache with recent clang versions.
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2014-12-10</p></div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_16">Bug fixes</h3>\r
+<h3 id="_bug_fixes_17">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1542,7 +1639,7 @@ Added missing documentation for <code>max_files</code> and <code>max_size</code>
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2014-11-17</p></div>\r
 <div class="sect2">\r
-<h3 id="_new_features_and_improvements_8">New features and improvements</h3>\r
+<h3 id="_new_features_and_enhancements_9">New features and enhancements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1733,7 +1830,7 @@ Various other improvements of the test suite.
 </ul></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_17">Bug fixes</h3>\r
+<h3 id="_bug_fixes_18">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1764,7 +1861,7 @@ Fixed test suite failures when <code>CC</code> is a ccache-wrapped compiler.
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2016-07-12</p></div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_18">Bug fixes</h3>\r
+<h3 id="_bug_fixes_19">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1782,7 +1879,7 @@ Fixed a bug where (due to ccache rewriting paths) the compiler could choose
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2015-03-07</p></div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_19">Bug fixes</h3>\r
+<h3 id="_bug_fixes_20">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1813,7 +1910,7 @@ Don&#8217;t try to reset a non-existing stats file. This avoids &#8220;No such f
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2014-10-19</p></div>\r
 <div class="sect2">\r
-<h3 id="_new_features_and_improvements_9">New features and improvements</h3>\r
+<h3 id="_new_features_and_enhancements_10">New features and enhancements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1865,7 +1962,7 @@ Stale files in the internal temporary directory (<code>&lt;ccache_dir&gt;/tmp</c
 </ul></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_20">Bug fixes</h3>\r
+<h3 id="_bug_fixes_21">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1905,7 +2002,7 @@ Fixed problem with logging of current working directory.
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2013-01-06</p></div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_21">Bug fixes</h3>\r
+<h3 id="_bug_fixes_22">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1955,7 +2052,7 @@ Fixed test suite to work on ecryptfs.
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2012-08-11</p></div>\r
 <div class="sect2">\r
-<h3 id="_new_features_and_improvements_10">New features and improvements</h3>\r
+<h3 id="_new_features_and_enhancements_11">New features and enhancements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1976,7 +2073,7 @@ Clang plugins are now hashed to catch plugin upgrades.
 </ul></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_22">Bug fixes</h3>\r
+<h3 id="_bug_fixes_23">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2024,7 +2121,7 @@ Fixed <code>static_assert</code> macro definition clash with GCC 4.7.
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2012-01-08</p></div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_23">Bug fixes</h3>\r
+<h3 id="_bug_fixes_24">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2097,7 +2194,7 @@ Improved documentation on how to fix bad object files in the cache.
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2011-08-21</p></div>\r
 <div class="sect2">\r
-<h3 id="_new_features_and_improvements_11">New features and improvements</h3>\r
+<h3 id="_new_features_and_enhancements_12">New features and enhancements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2107,7 +2204,7 @@ Rewrite argument to <code>--sysroot</code> if <code>CCACHE_BASEDIR</code> is use
 </ul></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_24">Bug fixes</h3>\r
+<h3 id="_bug_fixes_25">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2128,7 +2225,7 @@ Fixed alignment of &#8220;called for preprocessing&#8221; counter.
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2011-05-29</p></div>\r
 <div class="sect2">\r
-<h3 id="_new_features_and_improvements_12">New features and improvements</h3>\r
+<h3 id="_new_features_and_enhancements_13">New features and enhancements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2160,7 +2257,7 @@ Improved order of statistics counters in <code>ccache -s</code> output.
 </ul></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_25">Bug fixes</h3>\r
+<h3 id="_bug_fixes_26">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2193,7 +2290,7 @@ Systems that lack (and don&#8217;t need to be linked with) libm are now supporte
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2011-01-09</p></div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_26">Bug fixes</h3>\r
+<h3 id="_bug_fixes_27">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2226,7 +2323,7 @@ The file handle in now correctly closed on write error when trying to create
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2010-11-28</p></div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_27">Bug fixes</h3>\r
+<h3 id="_bug_fixes_28">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2253,7 +2350,7 @@ Portability fixes for HP-UX 11.00 and other esoteric systems.
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2010-11-21</p></div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_28">Bug fixes</h3>\r
+<h3 id="_bug_fixes_29">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2301,7 +2398,7 @@ The test suite now also works on systems that lack a /dev/zero.
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2010-11-07</p></div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_29">Bug fixes</h3>\r
+<h3 id="_bug_fixes_30">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2355,7 +2452,7 @@ Minor debug log message improvements.
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2010-09-16</p></div>\r
 <div class="sect2">\r
-<h3 id="_new_features_and_improvements_13">New features and improvements</h3>\r
+<h3 id="_new_features_and_enhancements_14">New features and enhancements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2423,7 +2520,7 @@ Added <code>-install_name</code> as an option known to take an argument. (This i
 </ul></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_30">Bug fixes</h3>\r
+<h3 id="_bug_fixes_31">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2509,7 +2606,7 @@ New <code>HACKING.txt</code> file with some notes about ccache code conventions.
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2010-07-15</p></div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_31">Bug fixes</h3>\r
+<h3 id="_bug_fixes_32">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2555,7 +2652,7 @@ The way the hashes are calculated has changed, so you won&#8217;t get cache hits
 </ul></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_new_features_and_improvements_14">New features and improvements</h3>\r
+<h3 id="_new_features_and_enhancements_15">New features and enhancements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2698,7 +2795,7 @@ The following options are no longer hashed in the preprocessor mode:
 </ul></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_bug_fixes_32">Bug fixes</h3>\r
+<h3 id="_bug_fixes_33">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2843,9 +2940,9 @@ Statistics counters are now correctly updated for -E option failures and
 <div id="footnotes"><hr /></div>\r
 <div id="footer">\r
 <div id="footer-text">\r
-Version 3.3.6<br />\r
+Version 3.4<br />\r
 Last updated\r
- 2018-01-28 16:21:15 CET\r
+ 2018-02-11 15:20:55 CET\r
 </div>\r
 </div>\r
 </body>\r
index cbb985a..d6b127d 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,66 +1,33 @@
-ccache
-======
+ccache â€“ a fast compiler cache
+==============================
 
 [![Build Status](https://travis-ci.org/ccache/ccache.svg?branch=master)](https://travis-ci.org/ccache/ccache)
 
-About
------
-
 ccache is a compiler cache. It speeds up recompilation by caching the result of
 previous compilations and detecting when the same compilation is being done
 again. Supported languages are C, C++, Objective-C and Objective-C++.
 
 
-Documentation
--------------
-
-See the https://ccache.samba.org.
-
-
-Installation
-------------
-
-See [INSTALL.md](INSTALL.md).
-
-
-Web site
---------
-
-The main ccache web site is here:
-
-https://ccache.samba.org
-
-
-Mailing list
-------------
-
-There is a mailing list for discussing usage and development of ccache:
-
-https://lists.samba.org/mailman/listinfo/ccache/
-
-Anyone is welcome to join.
-
-
-Bug reports
------------
-
-To submit a bug report or to search for existing reports, please visit this web
-page:
-
-https://ccache.samba.org/bugs.html
-
-
-History
--------
-
-ccache was originally written by Andrew Tridgell and is currently developed and
-maintained by Joel Rosdahl. ccache started out as a reimplementation of Erik
-Thiele's "compilercache" (see http://www.erikyyy.de/compilercache/) in C.
+General information
+-------------------
 
-See also https://ccache.samba.org/news.html.
+* [Main web site](https://ccache.samba.org)
+* [Documentation](https://ccache.samba.org/documentation.html)
+  * [Latest manual](https://ccache.samba.org/manual/latest.html)
+  * [Installation from Git source repository](https://github.com/ccache/ccache/blob/master/doc/INSTALL.md)
+  * [Installation from release archive](https://github.com/ccache/ccache/blob/master/doc/INSTALL-from-release-archive.md)
+* [Release notes](https://ccache.samba.org/releasenotes.html)
+* [Credits and history](https://ccache.samba.org/credits.html)
+* [License and copyright](https://ccache.samba.org/license.html)
 
 
-License and copyright
----------------------
+Contributing to ccache
+----------------------
 
-See https://ccache.samba.org/license.html.
+* [Source repository](https://github.com/ccache/ccache)
+* [Notes on how to contribute](https://github.com/ccache/ccache/blob/master/CONTRIBUTING.md)
+* [Mailing list](https://lists.samba.org/mailman/listinfo/ccache/)
+* [Bug report info](https://ccache.samba.org/bugs.html)
+* [Issue tracker](https://github.com/ccache/ccache/issues)
+  * [Help wanted!](https://github.com/ccache/ccache/issues/help%20wanted)
+  * [Good first issues!](https://github.com/ccache/ccache/issues/good%20first%20issue)
index 03398d6..c24c53f 100644 (file)
--- a/ccache.1
+++ b/ccache.1
@@ -2,12 +2,12 @@
 .\"     Title: ccache
 .\"    Author: [see the "Author" section]
 .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
-.\"      Date: 01/28/2018
+.\"      Date: 02/11/2018
 .\"    Manual: ccache Manual
-.\"    Source: ccache 3.3.6
+.\"    Source: ccache 3.3.6+95_g181effa
 .\"  Language: English
 .\"
-.TH "CCACHE" "1" "01/28/2018" "ccache 3\&.3\&.6" "ccache Manual"
+.TH "CCACHE" "1" "02/11/2018" "ccache 3\&.3\&.6+95_g181effa" "ccache Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -106,17 +106,6 @@ Low overhead\&.
 .sp -1
 .IP \(bu 2.3
 .\}
-Optionally uses hard links where possible to avoid copies\&.
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
 Optionally compresses files in the cache to reduce disk space\&.
 .RE
 .SS "Limitations"
@@ -364,7 +353,7 @@ max_size = 10G
 .\}
 .SS "Boolean values"
 .sp
-Some settings are boolean values (i\&.e\&. truth values)\&. In a configuration file, such values must be set to the string \fBtrue\fR or \fBfalse\fR\&. For the corresponding environment variables, the semantics are a bit different: a set environment variable means \(lqtrue\(rq regardless of the value (even if set to the empty string), and an unset environment variable means \(lqfalse\(rq\&. Each boolean environment variable also has a negated form starting with \fBCCACHE_NO\fR\&. For example, \fBCCACHE_COMPRESS\fR can be set to force compression and \fBCCACHE_NOCOMPRESS\fR can be set to force no compression\&.
+Some settings are boolean values (i\&.e\&. truth values)\&. In a configuration file, such values must be set to the string \fBtrue\fR or \fBfalse\fR\&. For the corresponding environment variables, the semantics are a bit different: a set environment variable means \(lqtrue\(rq (even if set to the empty string), the following case\-insensitive negative values are considered an error (rather than surprising the user): \fB0\fR, \fBfalse\fR, \fBdisable\fR and \fBno\fR, and an unset environment variable means \(lqfalse\(rq\&. Each boolean environment variable also has a negated form starting with \fBCCACHE_NO\fR\&. For example, \fBCCACHE_COMPRESS\fR can be set to force compression and \fBCCACHE_NOCOMPRESS\fR can be set to force no compression\&.
 .SS "Configuration settings"
 .sp
 Below is a list of available configuration settings\&. The corresponding environment variable name is indicated in parentheses after each configuration setting key\&.
@@ -502,7 +491,47 @@ This setting is a list of paths to files that ccache will include in the the has
 .PP
 \fBhard_link\fR (\fBCCACHE_HARDLINK\fR or \fBCCACHE_NOHARDLINK\fR, see Boolean values above)
 .RS 4
-If true, ccache will attempt to use hard links from the cache directory when creating the compiler output rather than using a file copy\&. Using hard links may be slightly faster in some situations, but can confuse programs like \(lqmake\(rq that rely on modification times\&. Another thing to keep in mind is that if the resulting object file is modified in any way, this corrupts the cached object file as well\&. Hard links are never made for compressed cache files\&. This means that you should not enable compression if you want to use hard links\&. The default is false\&.
+If true, ccache will attempt to use hard links from the cache directory when creating the compiler output rather than using a file copy\&. Hard links are never made for compressed cache files\&. This means that you should not enable compression if you want to use hard links\&. The default is false\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBWarning\fR
+.ps -1
+.br
+Do not enable this option unless you are aware of the consequences\&. Using hard links may be slightly faster in some situations, but there are several pitfalls since the resulting object file will share i\-node with the cached object file:
+.sp .5v
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 1.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP "  1." 4.2
+.\}
+If the resulting object file is modified in any way, the cached object file will be modified as well\&. For instance, if you run
+\fBstrip object\&.o\fR
+or
+\fBecho >object\&.o\fR, you will corrupt the cache\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 2.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP "  2." 4.2
+.\}
+Programs that rely on modification times (like \(lqmake\(rq) can be confused since ccache updates the cached files\*(Aq modification times as part of the automatic cache size management\&. This will affect object files in the build tree as well, which can retrigger the linking step even though nothing really has changed\&.
+.RE
 .RE
 .PP
 \fBhash_dir\fR (\fBCCACHE_HASHDIR\fR or \fBCCACHE_NOHASHDIR\fR, see Boolean values above)
@@ -605,6 +634,18 @@ THE PREPROCESSOR MODE) and then on a cache miss run the compiler on the source c
 If false, ccache will first run preprocessor to preprocess the source code and then on a cache miss run the compiler on the
 \fIpreprocessed source code\fR
 instead of the original source code\&. This makes cache misses slightly faster since the source code only has to be preprocessed once\&. The downside is that some compilers won\(cqt produce the same result (for instance diagnostics warnings) when compiling preprocessed source code\&.
+.sp
+A solution to the above mentioned downside is to set
+\fBrun_second_cpp\fR
+to false and pass
+\fB\-fdirectives\-only\fR
+(for GCC) or
+\fB\-frewrite\-includes\fR
+(for Clang) to the compiler\&. This will cause the compiler to leave the macros and other preprocessor information, and only process the
+\fB#include\fR
+directives\&. When run in this way, the preprocessor arguments will be passed to the compiler since it still has to do
+\fIsome\fR
+preprocessing (like macros)\&.
 .RE
 .PP
 \fBsloppiness\fR (\fBCCACHE_SLOPPINESS\fR)
@@ -701,7 +742,7 @@ If true, ccache will use a C/C++ unifier when hashing the preprocessor output if
 \fB\-g\fR
 option is not used\&. The unifier is slower than a normal hash, so setting this environment variable loses a little bit of speed, but it means that ccache can take advantage of not recompiling when the changes to the source code consist of reformatting only\&. Note that enabling the unifier changes the hash, so cached compilations produced when the unifier is enabled cannot be reused when the unifier is disabled, and vice versa\&. Enabling the unifier may result in incorrect line number information in compiler warning messages and expansions of the
 \fB__LINE__\fR
-macro\&. Also note that enabling the unifier implies turning off the direct mode\&.
+macro\&.
 .RE
 .SH "CACHE SIZE MANAGEMENT"
 .sp
@@ -1200,19 +1241,6 @@ a modification time of one of the include files is too new (needed to avoid a ra
 .sp -1
 .IP \(bu 2.3
 .\}
-the unifier is enabled (the configuration setting
-\fBunify\fR
-is true)
-.RE
-.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
 a compiler option not supported by the direct mode is used:
 .sp
 .RS 4
@@ -1631,6 +1659,40 @@ The direct mode fails to pick up new header files in some rare scenarios\&. See
 THE DIRECT MODE
 above\&.
 .RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+When run via ccache, warning messages produced by GCC 4\&.9 and newer will only be colored when the environment variable
+\fBGCC_COLORS\fR
+is set\&. An alternative to setting
+\fBGCC_COLORS\fR
+is to pass
+\-fdiagnostics\-color
+explicitly when compiling (but then color codes will also be present when redirecting stderr to a file)\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+If ccache guesses that the compiler may emit colored warnings, then a compilation with stderr referring to a TTY will be considered different from a compilation with a redirected stderr, thus not sharing cache entries\&. This happens for clang by default and for GCC when
+\fBGCC_COLORS\fR
+is set as mentioned above\&. If you want to share cache hits, you can pass
+\-f[no\-]diagnostics\-color
+(GCC) or
+\-f[no\-]color\-diagnostics
+(clang) explicitly when compiling (but then color codes will be either on or off for both the TTY and the redirected case)\&.
+.RE
 .SH "TROUBLESHOOTING"
 .SS "General"
 .sp
old mode 100755 (executable)
new mode 100644 (file)
index ad5f74a..9baaa27
@@ -1,14 +1,12 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-#   2011, 2012 Free Software Foundation, Inc.
+#   Copyright 1992-2018 Free Software Foundation, Inc.
 
-timestamp='2012-07-31'
+timestamp='2018-01-26'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
+# the Free Software Foundation; either version 3 of the License, or
 # (at your option) any later version.
 #
 # This program is distributed in the hope that it will be useful, but
@@ -17,24 +15,22 @@ timestamp='2012-07-31'
 # General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
 #
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
 # configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-
-# Originally written by Per Bothner.  Please send patches (context
-# diff format) to <config-patches@gnu.org> and include a ChangeLog
-# entry.
+# the same distribution terms that you use for the rest of that
+# program.  This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
 #
-# This script attempts to guess a canonical system name similar to
-# config.sub.  If it succeeds, it prints the system name on stdout, and
-# exits with 0.  Otherwise, it exits with 1.
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
 #
 # You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+#
+# Please send patches to <config-patches@gnu.org>.
+
 
 me=`echo "$0" | sed -e 's,.*/,,'`
 
@@ -43,7 +39,7 @@ Usage: $0 [OPTION]
 
 Output the configuration name of the system \`$me' is run on.
 
-Operation modes:
+Options:
   -h, --help         print this help, then exit
   -t, --time-stamp   print date of last modification, then exit
   -v, --version      print version number, then exit
@@ -54,9 +50,7 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
-Free Software Foundation, Inc.
+Copyright 1992-2018 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -113,9 +107,9 @@ trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
 dummy=$tmp/dummy ;
 tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
 case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,)    echo "int x;" > $dummy.c ;
+ ,,)    echo "int x;" > "$dummy.c" ;
        for c in cc gcc c89 c99 ; do
-         if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+         if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
             CC_FOR_BUILD="$c"; break ;
          fi ;
        done ;
@@ -138,9 +132,37 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
 UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
 UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
 
+case "$UNAME_SYSTEM" in
+Linux|GNU|GNU/*)
+       # If the system lacks a compiler, then just pick glibc.
+       # We could probably try harder.
+       LIBC=gnu
+
+       eval "$set_cc_for_build"
+       cat <<-EOF > "$dummy.c"
+       #include <features.h>
+       #if defined(__UCLIBC__)
+       LIBC=uclibc
+       #elif defined(__dietlibc__)
+       LIBC=dietlibc
+       #else
+       LIBC=gnu
+       #endif
+       EOF
+       eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`"
+
+       # If ldd exists, use it to detect musl libc.
+       if command -v ldd >/dev/null && \
+               ldd --version 2>&1 | grep -q ^musl
+       then
+           LIBC=musl
+       fi
+       ;;
+esac
+
 # Note: order is significant - the case branches are not exclusive.
 
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
     *:NetBSD:*:*)
        # NetBSD (nbsd) targets should (where applicable) match one or
        # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
@@ -153,21 +175,31 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
        # Note: NetBSD doesn't particularly care about the vendor
        # portion of the name.  We always set it to "unknown".
        sysctl="sysctl -n hw.machine_arch"
-       UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
-           /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
-       case "${UNAME_MACHINE_ARCH}" in
+       UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+           "/sbin/$sysctl" 2>/dev/null || \
+           "/usr/sbin/$sysctl" 2>/dev/null || \
+           echo unknown)`
+       case "$UNAME_MACHINE_ARCH" in
            armeb) machine=armeb-unknown ;;
            arm*) machine=arm-unknown ;;
            sh3el) machine=shl-unknown ;;
            sh3eb) machine=sh-unknown ;;
            sh5el) machine=sh5le-unknown ;;
-           *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+           earmv*)
+               arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+               endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
+               machine="${arch}${endian}"-unknown
+               ;;
+           *) machine="$UNAME_MACHINE_ARCH"-unknown ;;
        esac
        # The Operating System including object format, if it has switched
-       # to ELF recently, or will in the future.
-       case "${UNAME_MACHINE_ARCH}" in
+       # to ELF recently (or will in the future) and ABI.
+       case "$UNAME_MACHINE_ARCH" in
+           earm*)
+               os=netbsdelf
+               ;;
            arm*|i386|m68k|ns32k|sh3*|sparc|vax)
-               eval $set_cc_for_build
+               eval "$set_cc_for_build"
                if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
                        | grep -q __ELF__
                then
@@ -182,44 +214,67 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
                os=netbsd
                ;;
        esac
+       # Determine ABI tags.
+       case "$UNAME_MACHINE_ARCH" in
+           earm*)
+               expr='s/^earmv[0-9]/-eabi/;s/eb$//'
+               abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
+               ;;
+       esac
        # The OS release
        # Debian GNU/NetBSD machines have a different userland, and
        # thus, need a distinct triplet. However, they do not need
        # kernel version information, so it can be replaced with a
        # suitable tag, in the style of linux-gnu.
-       case "${UNAME_VERSION}" in
+       case "$UNAME_VERSION" in
            Debian*)
                release='-gnu'
                ;;
            *)
-               release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+               release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2`
                ;;
        esac
        # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
        # contains redundant information, the shorter form:
        # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
-       echo "${machine}-${os}${release}"
+       echo "$machine-${os}${release}${abi}"
        exit ;;
     *:Bitrig:*:*)
        UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
-       echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+       echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
        exit ;;
     *:OpenBSD:*:*)
        UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
-       echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+       echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
+       exit ;;
+    *:LibertyBSD:*:*)
+       UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+       echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
+       exit ;;
+    *:MidnightBSD:*:*)
+       echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE"
        exit ;;
     *:ekkoBSD:*:*)
-       echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+       echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE"
        exit ;;
     *:SolidBSD:*:*)
-       echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+       echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE"
        exit ;;
     macppc:MirBSD:*:*)
-       echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+       echo powerpc-unknown-mirbsd"$UNAME_RELEASE"
        exit ;;
     *:MirBSD:*:*)
-       echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+       echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE"
+       exit ;;
+    *:Sortix:*:*)
+       echo "$UNAME_MACHINE"-unknown-sortix
        exit ;;
+    *:Redox:*:*)
+       echo "$UNAME_MACHINE"-unknown-redox
+       exit ;;
+    mips:OSF1:*.*)
+        echo mips-dec-osf1
+        exit ;;
     alpha:OSF1:*:*)
        case $UNAME_RELEASE in
        *4.0)
@@ -236,63 +291,54 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
        ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
        case "$ALPHA_CPU_TYPE" in
            "EV4 (21064)")
-               UNAME_MACHINE="alpha" ;;
+               UNAME_MACHINE=alpha ;;
            "EV4.5 (21064)")
-               UNAME_MACHINE="alpha" ;;
+               UNAME_MACHINE=alpha ;;
            "LCA4 (21066/21068)")
-               UNAME_MACHINE="alpha" ;;
+               UNAME_MACHINE=alpha ;;
            "EV5 (21164)")
-               UNAME_MACHINE="alphaev5" ;;
+               UNAME_MACHINE=alphaev5 ;;
            "EV5.6 (21164A)")
-               UNAME_MACHINE="alphaev56" ;;
+               UNAME_MACHINE=alphaev56 ;;
            "EV5.6 (21164PC)")
-               UNAME_MACHINE="alphapca56" ;;
+               UNAME_MACHINE=alphapca56 ;;
            "EV5.7 (21164PC)")
-               UNAME_MACHINE="alphapca57" ;;
+               UNAME_MACHINE=alphapca57 ;;
            "EV6 (21264)")
-               UNAME_MACHINE="alphaev6" ;;
+               UNAME_MACHINE=alphaev6 ;;
            "EV6.7 (21264A)")
-               UNAME_MACHINE="alphaev67" ;;
+               UNAME_MACHINE=alphaev67 ;;
            "EV6.8CB (21264C)")
-               UNAME_MACHINE="alphaev68" ;;
+               UNAME_MACHINE=alphaev68 ;;
            "EV6.8AL (21264B)")
-               UNAME_MACHINE="alphaev68" ;;
+               UNAME_MACHINE=alphaev68 ;;
            "EV6.8CX (21264D)")
-               UNAME_MACHINE="alphaev68" ;;
+               UNAME_MACHINE=alphaev68 ;;
            "EV6.9A (21264/EV69A)")
-               UNAME_MACHINE="alphaev69" ;;
+               UNAME_MACHINE=alphaev69 ;;
            "EV7 (21364)")
-               UNAME_MACHINE="alphaev7" ;;
+               UNAME_MACHINE=alphaev7 ;;
            "EV7.9 (21364A)")
-               UNAME_MACHINE="alphaev79" ;;
+               UNAME_MACHINE=alphaev79 ;;
        esac
        # A Pn.n version is a patched version.
        # A Vn.n version is a released version.
        # A Tn.n version is a released field test version.
        # A Xn.n version is an unreleased experimental baselevel.
        # 1.2 uses "1.2" for uname -r.
-       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+       echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`"
        # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
        exitcode=$?
        trap '' 0
        exit $exitcode ;;
-    Alpha\ *:Windows_NT*:*)
-       # How do we know it's Interix rather than the generic POSIX subsystem?
-       # Should we change UNAME_MACHINE based on the output of uname instead
-       # of the specific Alpha model?
-       echo alpha-pc-interix
-       exit ;;
-    21064:Windows_NT:50:3)
-       echo alpha-dec-winnt3.5
-       exit ;;
     Amiga*:UNIX_System_V:4.0:*)
        echo m68k-unknown-sysv4
        exit ;;
     *:[Aa]miga[Oo][Ss]:*:*)
-       echo ${UNAME_MACHINE}-unknown-amigaos
+       echo "$UNAME_MACHINE"-unknown-amigaos
        exit ;;
     *:[Mm]orph[Oo][Ss]:*:*)
-       echo ${UNAME_MACHINE}-unknown-morphos
+       echo "$UNAME_MACHINE"-unknown-morphos
        exit ;;
     *:OS/390:*:*)
        echo i370-ibm-openedition
@@ -304,9 +350,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
        echo powerpc-ibm-os400
        exit ;;
     arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
-       echo arm-acorn-riscix${UNAME_RELEASE}
+       echo arm-acorn-riscix"$UNAME_RELEASE"
        exit ;;
-    arm:riscos:*:*|arm:RISCOS:*:*)
+    arm*:riscos:*:*|arm*:RISCOS:*:*)
        echo arm-unknown-riscos
        exit ;;
     SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
@@ -331,38 +377,38 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
            sparc) echo sparc-icl-nx7; exit ;;
        esac ;;
     s390x:SunOS:*:*)
-       echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
        exit ;;
     sun4H:SunOS:5.*:*)
-       echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
        exit ;;
     sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
-       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
        exit ;;
     i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
-       echo i386-pc-auroraux${UNAME_RELEASE}
+       echo i386-pc-auroraux"$UNAME_RELEASE"
        exit ;;
     i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
-       eval $set_cc_for_build
-       SUN_ARCH="i386"
+       eval "$set_cc_for_build"
+       SUN_ARCH=i386
        # If there is a compiler, see if it is configured for 64-bit objects.
        # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
        # This test works for both compilers.
-       if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+       if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
            if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
-               (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+               (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
                grep IS_64BIT_ARCH >/dev/null
            then
-               SUN_ARCH="x86_64"
+               SUN_ARCH=x86_64
            fi
        fi
-       echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
        exit ;;
     sun4*:SunOS:6*:*)
        # According to config.sub, this is the proper way to canonicalize
        # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
        # it's likely to be more like Solaris than SunOS4.
-       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
        exit ;;
     sun4*:SunOS:*:*)
        case "`/usr/bin/arch -k`" in
@@ -371,25 +417,25 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
                ;;
        esac
        # Japanese Language versions have a version number like `4.1.3-JL'.
-       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+       echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`"
        exit ;;
     sun3*:SunOS:*:*)
-       echo m68k-sun-sunos${UNAME_RELEASE}
+       echo m68k-sun-sunos"$UNAME_RELEASE"
        exit ;;
     sun*:*:4.2BSD:*)
        UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
-       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+       test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
        case "`/bin/arch`" in
            sun3)
-               echo m68k-sun-sunos${UNAME_RELEASE}
+               echo m68k-sun-sunos"$UNAME_RELEASE"
                ;;
            sun4)
-               echo sparc-sun-sunos${UNAME_RELEASE}
+               echo sparc-sun-sunos"$UNAME_RELEASE"
                ;;
        esac
        exit ;;
     aushp:SunOS:*:*)
-       echo sparc-auspex-sunos${UNAME_RELEASE}
+       echo sparc-auspex-sunos"$UNAME_RELEASE"
        exit ;;
     # The situation for MiNT is a little confusing.  The machine name
     # can be virtually everything (everything which is not
@@ -400,44 +446,44 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     # MiNT.  But MiNT is downward compatible to TOS, so this should
     # be no problem.
     atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
-       echo m68k-atari-mint${UNAME_RELEASE}
+       echo m68k-atari-mint"$UNAME_RELEASE"
        exit ;;
     atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
-       echo m68k-atari-mint${UNAME_RELEASE}
+       echo m68k-atari-mint"$UNAME_RELEASE"
        exit ;;
     *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
-       echo m68k-atari-mint${UNAME_RELEASE}
+       echo m68k-atari-mint"$UNAME_RELEASE"
        exit ;;
     milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
-       echo m68k-milan-mint${UNAME_RELEASE}
+       echo m68k-milan-mint"$UNAME_RELEASE"
        exit ;;
     hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
-       echo m68k-hades-mint${UNAME_RELEASE}
+       echo m68k-hades-mint"$UNAME_RELEASE"
        exit ;;
     *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
-       echo m68k-unknown-mint${UNAME_RELEASE}
+       echo m68k-unknown-mint"$UNAME_RELEASE"
        exit ;;
     m68k:machten:*:*)
-       echo m68k-apple-machten${UNAME_RELEASE}
+       echo m68k-apple-machten"$UNAME_RELEASE"
        exit ;;
     powerpc:machten:*:*)
-       echo powerpc-apple-machten${UNAME_RELEASE}
+       echo powerpc-apple-machten"$UNAME_RELEASE"
        exit ;;
     RISC*:Mach:*:*)
        echo mips-dec-mach_bsd4.3
        exit ;;
     RISC*:ULTRIX:*:*)
-       echo mips-dec-ultrix${UNAME_RELEASE}
+       echo mips-dec-ultrix"$UNAME_RELEASE"
        exit ;;
     VAX*:ULTRIX*:*:*)
-       echo vax-dec-ultrix${UNAME_RELEASE}
+       echo vax-dec-ultrix"$UNAME_RELEASE"
        exit ;;
     2020:CLIX:*:* | 2430:CLIX:*:*)
-       echo clipper-intergraph-clix${UNAME_RELEASE}
+       echo clipper-intergraph-clix"$UNAME_RELEASE"
        exit ;;
     mips:*:*:UMIPS | mips:*:*:RISCos)
-       eval $set_cc_for_build
-       sed 's/^        //' << EOF >$dummy.c
+       eval "$set_cc_for_build"
+       sed 's/^        //' << EOF > "$dummy.c"
 #ifdef __cplusplus
 #include <stdio.h>  /* for printf() prototype */
        int main (int argc, char *argv[]) {
@@ -446,23 +492,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 #endif
        #if defined (host_mips) && defined (MIPSEB)
        #if defined (SYSTYPE_SYSV)
-         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+         printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0);
        #endif
        #if defined (SYSTYPE_SVR4)
-         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+         printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0);
        #endif
        #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
-         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+         printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0);
        #endif
        #endif
          exit (-1);
        }
 EOF
-       $CC_FOR_BUILD -o $dummy $dummy.c &&
-         dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
-         SYSTEM_NAME=`$dummy $dummyarg` &&
+       $CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
+         dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+         SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
            { echo "$SYSTEM_NAME"; exit; }
-       echo mips-mips-riscos${UNAME_RELEASE}
+       echo mips-mips-riscos"$UNAME_RELEASE"
        exit ;;
     Motorola:PowerMAX_OS:*:*)
        echo powerpc-motorola-powermax
@@ -488,17 +534,17 @@ EOF
     AViiON:dgux:*:*)
        # DG/UX returns AViiON for all architectures
        UNAME_PROCESSOR=`/usr/bin/uname -p`
-       if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+       if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ]
        then
-           if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
-              [ ${TARGET_BINARY_INTERFACE}x = x ]
+           if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \
+              [ "$TARGET_BINARY_INTERFACE"x = x ]
            then
-               echo m88k-dg-dgux${UNAME_RELEASE}
+               echo m88k-dg-dgux"$UNAME_RELEASE"
            else
-               echo m88k-dg-dguxbcs${UNAME_RELEASE}
+               echo m88k-dg-dguxbcs"$UNAME_RELEASE"
            fi
        else
-           echo i586-dg-dgux${UNAME_RELEASE}
+           echo i586-dg-dgux"$UNAME_RELEASE"
        fi
        exit ;;
     M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
@@ -515,7 +561,7 @@ EOF
        echo m68k-tektronix-bsd
        exit ;;
     *:IRIX*:*:*)
-       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+       echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`"
        exit ;;
     ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
        echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
@@ -527,14 +573,14 @@ EOF
        if [ -x /usr/bin/oslevel ] ; then
                IBM_REV=`/usr/bin/oslevel`
        else
-               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+               IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
        fi
-       echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+       echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV"
        exit ;;
     *:AIX:2:3)
        if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
-               eval $set_cc_for_build
-               sed 's/^                //' << EOF >$dummy.c
+               eval "$set_cc_for_build"
+               sed 's/^                //' << EOF > "$dummy.c"
                #include <sys/systemcfg.h>
 
                main()
@@ -545,7 +591,7 @@ EOF
                        exit(0);
                        }
 EOF
-               if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+               if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
                then
                        echo "$SYSTEM_NAME"
                else
@@ -559,26 +605,27 @@ EOF
        exit ;;
     *:AIX:*:[4567])
        IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
-       if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+       if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
                IBM_ARCH=rs6000
        else
                IBM_ARCH=powerpc
        fi
-       if [ -x /usr/bin/oslevel ] ; then
-               IBM_REV=`/usr/bin/oslevel`
+       if [ -x /usr/bin/lslpp ] ; then
+               IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+                          awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
        else
-               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+               IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
        fi
-       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+       echo "$IBM_ARCH"-ibm-aix"$IBM_REV"
        exit ;;
     *:AIX:*:*)
        echo rs6000-ibm-aix
        exit ;;
-    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+    ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
        echo romp-ibm-bsd4.4
        exit ;;
     ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
-       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+       echo romp-ibm-bsd"$UNAME_RELEASE"   # 4.3 with uname added to
        exit ;;                             # report: romp-ibm BSD 4.3
     *:BOSX:*:*)
        echo rs6000-bull-bosx
@@ -593,28 +640,28 @@ EOF
        echo m68k-hp-bsd4.4
        exit ;;
     9000/[34678]??:HP-UX:*:*)
-       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
-       case "${UNAME_MACHINE}" in
-           9000/31? )            HP_ARCH=m68000 ;;
-           9000/[34]?? )         HP_ARCH=m68k ;;
+       HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+       case "$UNAME_MACHINE" in
+           9000/31?)            HP_ARCH=m68000 ;;
+           9000/[34]??)         HP_ARCH=m68k ;;
            9000/[678][0-9][0-9])
                if [ -x /usr/bin/getconf ]; then
                    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
-                   case "${sc_cpu_version}" in
-                     523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
-                     528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                   case "$sc_cpu_version" in
+                     523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
+                     528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
                      532)                      # CPU_PA_RISC2_0
-                       case "${sc_kernel_bits}" in
-                         32) HP_ARCH="hppa2.0n" ;;
-                         64) HP_ARCH="hppa2.0w" ;;
-                         '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                       case "$sc_kernel_bits" in
+                         32) HP_ARCH=hppa2.0n ;;
+                         64) HP_ARCH=hppa2.0w ;;
+                         '') HP_ARCH=hppa2.0 ;;   # HP-UX 10.20
                        esac ;;
                    esac
                fi
-               if [ "${HP_ARCH}" = "" ]; then
-                   eval $set_cc_for_build
-                   sed 's/^            //' << EOF >$dummy.c
+               if [ "$HP_ARCH" = "" ]; then
+                   eval "$set_cc_for_build"
+                   sed 's/^            //' << EOF > "$dummy.c"
 
                #define _HPUX_SOURCE
                #include <stdlib.h>
@@ -647,13 +694,13 @@ EOF
                    exit (0);
                }
 EOF
-                   (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+                   (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"`
                    test -z "$HP_ARCH" && HP_ARCH=hppa
                fi ;;
        esac
-       if [ ${HP_ARCH} = "hppa2.0w" ]
+       if [ "$HP_ARCH" = hppa2.0w ]
        then
-           eval $set_cc_for_build
+           eval "$set_cc_for_build"
 
            # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
            # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
@@ -664,23 +711,23 @@ EOF
            # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
            # => hppa64-hp-hpux11.23
 
-           if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+           if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
                grep -q __LP64__
            then
-               HP_ARCH="hppa2.0w"
+               HP_ARCH=hppa2.0w
            else
-               HP_ARCH="hppa64"
+               HP_ARCH=hppa64
            fi
        fi
-       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+       echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
        exit ;;
     ia64:HP-UX:*:*)
-       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
-       echo ia64-hp-hpux${HPUX_REV}
+       HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
+       echo ia64-hp-hpux"$HPUX_REV"
        exit ;;
     3050*:HI-UX:*:*)
-       eval $set_cc_for_build
-       sed 's/^        //' << EOF >$dummy.c
+       eval "$set_cc_for_build"
+       sed 's/^        //' << EOF > "$dummy.c"
        #include <unistd.h>
        int
        main ()
@@ -705,11 +752,11 @@ EOF
          exit (0);
        }
 EOF
-       $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+       $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
                { echo "$SYSTEM_NAME"; exit; }
        echo unknown-hitachi-hiuxwe2
        exit ;;
-    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
        echo hppa1.1-hp-bsd
        exit ;;
     9000/8??:4.3bsd:*:*)
@@ -718,7 +765,7 @@ EOF
     *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
        echo hppa1.0-hp-mpeix
        exit ;;
-    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
        echo hppa1.1-hp-osf
        exit ;;
     hp8??:OSF1:*:*)
@@ -726,9 +773,9 @@ EOF
        exit ;;
     i*86:OSF1:*:*)
        if [ -x /usr/sbin/sysversion ] ; then
-           echo ${UNAME_MACHINE}-unknown-osf1mk
+           echo "$UNAME_MACHINE"-unknown-osf1mk
        else
-           echo ${UNAME_MACHINE}-unknown-osf1
+           echo "$UNAME_MACHINE"-unknown-osf1
        fi
        exit ;;
     parisc*:Lites*:*:*)
@@ -753,127 +800,109 @@ EOF
        echo c4-convex-bsd
        exit ;;
     CRAY*Y-MP:*:*:*)
-       echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
        exit ;;
     CRAY*[A-Z]90:*:*:*)
-       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+       echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \
        | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
              -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
              -e 's/\.[^.]*$/.X/'
        exit ;;
     CRAY*TS:*:*:*)
-       echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
        exit ;;
     CRAY*T3E:*:*:*)
-       echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
        exit ;;
     CRAY*SV1:*:*:*)
-       echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
        exit ;;
     *:UNICOS/mp:*:*)
-       echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
        exit ;;
     F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
-       FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
-       FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-       FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+       FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+       FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+       FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
        exit ;;
     5000:UNIX_System_V:4.*:*)
-       FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-       FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+       FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+       FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
        exit ;;
     i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
-       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+       echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE"
        exit ;;
     sparc*:BSD/OS:*:*)
-       echo sparc-unknown-bsdi${UNAME_RELEASE}
+       echo sparc-unknown-bsdi"$UNAME_RELEASE"
        exit ;;
     *:BSD/OS:*:*)
-       echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+       echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
        exit ;;
     *:FreeBSD:*:*)
        UNAME_PROCESSOR=`/usr/bin/uname -p`
-       case ${UNAME_PROCESSOR} in
+       case "$UNAME_PROCESSOR" in
            amd64)
-               echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
-           *)
-               echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+               UNAME_PROCESSOR=x86_64 ;;
+           i386)
+               UNAME_PROCESSOR=i586 ;;
        esac
+       echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
        exit ;;
     i*:CYGWIN*:*)
-       echo ${UNAME_MACHINE}-pc-cygwin
+       echo "$UNAME_MACHINE"-pc-cygwin
        exit ;;
     *:MINGW64*:*)
-       echo ${UNAME_MACHINE}-pc-mingw64
+       echo "$UNAME_MACHINE"-pc-mingw64
        exit ;;
     *:MINGW*:*)
-       echo ${UNAME_MACHINE}-pc-mingw32
+       echo "$UNAME_MACHINE"-pc-mingw32
        exit ;;
-    i*:MSYS*:*)
-       echo ${UNAME_MACHINE}-pc-msys
-       exit ;;
-    i*:windows32*:*)
-       # uname -m includes "-pc" on this system.
-       echo ${UNAME_MACHINE}-mingw32
+    *:MSYS*:*)
+       echo "$UNAME_MACHINE"-pc-msys
        exit ;;
     i*:PW*:*)
-       echo ${UNAME_MACHINE}-pc-pw32
+       echo "$UNAME_MACHINE"-pc-pw32
        exit ;;
     *:Interix*:*)
-       case ${UNAME_MACHINE} in
+       case "$UNAME_MACHINE" in
            x86)
-               echo i586-pc-interix${UNAME_RELEASE}
+               echo i586-pc-interix"$UNAME_RELEASE"
                exit ;;
            authenticamd | genuineintel | EM64T)
-               echo x86_64-unknown-interix${UNAME_RELEASE}
+               echo x86_64-unknown-interix"$UNAME_RELEASE"
                exit ;;
            IA64)
-               echo ia64-unknown-interix${UNAME_RELEASE}
+               echo ia64-unknown-interix"$UNAME_RELEASE"
                exit ;;
        esac ;;
-    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
-       echo i${UNAME_MACHINE}-pc-mks
-       exit ;;
-    8664:Windows_NT:*)
-       echo x86_64-pc-mks
-       exit ;;
-    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
-       # How do we know it's Interix rather than the generic POSIX subsystem?
-       # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
-       # UNAME_MACHINE based on the output of uname instead of i386?
-       echo i586-pc-interix
-       exit ;;
     i*:UWIN*:*)
-       echo ${UNAME_MACHINE}-pc-uwin
+       echo "$UNAME_MACHINE"-pc-uwin
        exit ;;
     amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
        echo x86_64-unknown-cygwin
        exit ;;
-    p*:CYGWIN*:*)
-       echo powerpcle-unknown-cygwin
-       exit ;;
     prep*:SunOS:5.*:*)
-       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
        exit ;;
     *:GNU:*:*)
        # the GNU system
-       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`"
        exit ;;
     *:GNU/*:*:*)
        # other systems with GNU libc and userland
-       echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+       echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC"
        exit ;;
     i*86:Minix:*:*)
-       echo ${UNAME_MACHINE}-pc-minix
+       echo "$UNAME_MACHINE"-pc-minix
        exit ;;
     aarch64:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     aarch64_be:Linux:*:*)
        UNAME_MACHINE=aarch64_be
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     alpha:Linux:*:*)
        case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
@@ -886,63 +915,64 @@ EOF
          EV68*) UNAME_MACHINE=alphaev68 ;;
        esac
        objdump --private-headers /bin/sh | grep -q ld.so.1
-       if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
-       echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+       if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+       exit ;;
+    arc:Linux:*:* | arceb:Linux:*:*)
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     arm*:Linux:*:*)
-       eval $set_cc_for_build
+       eval "$set_cc_for_build"
        if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
            | grep -q __ARM_EABI__
        then
-           echo ${UNAME_MACHINE}-unknown-linux-gnu
+           echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        else
            if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
                | grep -q __ARM_PCS_VFP
            then
-               echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+               echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi
            else
-               echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+               echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf
            fi
        fi
        exit ;;
     avr32*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     cris:Linux:*:*)
-       echo ${UNAME_MACHINE}-axis-linux-gnu
+       echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
        exit ;;
     crisv32:Linux:*:*)
-       echo ${UNAME_MACHINE}-axis-linux-gnu
+       echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
+       exit ;;
+    e2k:Linux:*:*)
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     frv:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     hexagon:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     i*86:Linux:*:*)
-       LIBC=gnu
-       eval $set_cc_for_build
-       sed 's/^        //' << EOF >$dummy.c
-       #ifdef __dietlibc__
-       LIBC=dietlibc
-       #endif
-EOF
-       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
-       echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+       echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
        exit ;;
     ia64:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+       exit ;;
+    k1om:Linux:*:*)
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     m32r*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     m68*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     mips:Linux:*:* | mips64:Linux:*:*)
-       eval $set_cc_for_build
-       sed 's/^        //' << EOF >$dummy.c
+       eval "$set_cc_for_build"
+       sed 's/^        //' << EOF > "$dummy.c"
        #undef CPU
        #undef ${UNAME_MACHINE}
        #undef ${UNAME_MACHINE}el
@@ -956,55 +986,70 @@ EOF
        #endif
        #endif
 EOF
-       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
-       test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+       eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`"
+       test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; }
        ;;
-    or32:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+    mips64el:Linux:*:*)
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+       exit ;;
+    openrisc*:Linux:*:*)
+       echo or1k-unknown-linux-"$LIBC"
+       exit ;;
+    or32:Linux:*:* | or1k*:Linux:*:*)
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     padre:Linux:*:*)
-       echo sparc-unknown-linux-gnu
+       echo sparc-unknown-linux-"$LIBC"
        exit ;;
     parisc64:Linux:*:* | hppa64:Linux:*:*)
-       echo hppa64-unknown-linux-gnu
+       echo hppa64-unknown-linux-"$LIBC"
        exit ;;
     parisc:Linux:*:* | hppa:Linux:*:*)
        # Look for CPU level
        case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
-         PA7*) echo hppa1.1-unknown-linux-gnu ;;
-         PA8*) echo hppa2.0-unknown-linux-gnu ;;
-         *)    echo hppa-unknown-linux-gnu ;;
+         PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;
+         PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;
+         *)    echo hppa-unknown-linux-"$LIBC" ;;
        esac
        exit ;;
     ppc64:Linux:*:*)
-       echo powerpc64-unknown-linux-gnu
+       echo powerpc64-unknown-linux-"$LIBC"
        exit ;;
     ppc:Linux:*:*)
-       echo powerpc-unknown-linux-gnu
+       echo powerpc-unknown-linux-"$LIBC"
+       exit ;;
+    ppc64le:Linux:*:*)
+       echo powerpc64le-unknown-linux-"$LIBC"
+       exit ;;
+    ppcle:Linux:*:*)
+       echo powerpcle-unknown-linux-"$LIBC"
+       exit ;;
+    riscv32:Linux:*:* | riscv64:Linux:*:*)
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     s390:Linux:*:* | s390x:Linux:*:*)
-       echo ${UNAME_MACHINE}-ibm-linux
+       echo "$UNAME_MACHINE"-ibm-linux-"$LIBC"
        exit ;;
     sh64*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     sh*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     sparc:Linux:*:* | sparc64:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     tile*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     vax:Linux:*:*)
-       echo ${UNAME_MACHINE}-dec-linux-gnu
+       echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
        exit ;;
     x86_64:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
        exit ;;
     xtensa*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
        exit ;;
     i*86:DYNIX/ptx:4*:*)
        # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
@@ -1018,34 +1063,34 @@ EOF
        # I am not positive that other SVR4 systems won't match this,
        # I just have to hope.  -- rms.
        # Use sysv4.2uw... so that sysv4* matches it.
-       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+       echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION"
        exit ;;
     i*86:OS/2:*:*)
        # If we were able to find `uname', then EMX Unix compatibility
        # is probably installed.
-       echo ${UNAME_MACHINE}-pc-os2-emx
+       echo "$UNAME_MACHINE"-pc-os2-emx
        exit ;;
     i*86:XTS-300:*:STOP)
-       echo ${UNAME_MACHINE}-unknown-stop
+       echo "$UNAME_MACHINE"-unknown-stop
        exit ;;
     i*86:atheos:*:*)
-       echo ${UNAME_MACHINE}-unknown-atheos
+       echo "$UNAME_MACHINE"-unknown-atheos
        exit ;;
     i*86:syllable:*:*)
-       echo ${UNAME_MACHINE}-pc-syllable
+       echo "$UNAME_MACHINE"-pc-syllable
        exit ;;
     i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
-       echo i386-unknown-lynxos${UNAME_RELEASE}
+       echo i386-unknown-lynxos"$UNAME_RELEASE"
        exit ;;
     i*86:*DOS:*:*)
-       echo ${UNAME_MACHINE}-pc-msdosdjgpp
+       echo "$UNAME_MACHINE"-pc-msdosdjgpp
        exit ;;
-    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
-       UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+    i*86:*:4.*:*)
+       UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
        if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
-               echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+               echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"
        else
-               echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+               echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL"
        fi
        exit ;;
     i*86:*:5:[678]*)
@@ -1055,12 +1100,12 @@ EOF
            *Pentium)        UNAME_MACHINE=i586 ;;
            *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
        esac
-       echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+       echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}"
        exit ;;
     i*86:*:3.2:*)
        if test -f /usr/options/cb.name; then
                UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
-               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+               echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"
        elif /bin/uname -X 2>/dev/null >/dev/null ; then
                UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
                (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
@@ -1070,9 +1115,9 @@ EOF
                        && UNAME_MACHINE=i686
                (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
                        && UNAME_MACHINE=i686
-               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+               echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL"
        else
-               echo ${UNAME_MACHINE}-pc-sysv32
+               echo "$UNAME_MACHINE"-pc-sysv32
        fi
        exit ;;
     pc:*:*:*)
@@ -1080,7 +1125,7 @@ EOF
        # uname -m prints for DJGPP always 'pc', but it prints nothing about
        # the processor, so we play safe by assuming i586.
        # Note: whatever this is, it MUST be the same as what config.sub
-       # prints for the "djgpp" host, or else GDB configury will decide that
+       # prints for the "djgpp" host, or else GDB configure will decide that
        # this is a cross-build.
        echo i586-pc-msdosdjgpp
        exit ;;
@@ -1092,9 +1137,9 @@ EOF
        exit ;;
     i860:*:4.*:*) # i860-SVR4
        if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
-         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+         echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4
        else # Add other i860-SVR4 vendors below as they are discovered.
-         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+         echo i860-unknown-sysv"$UNAME_RELEASE"  # Unknown i860-SVR4
        fi
        exit ;;
     mini*:CTIX:SYS*5:*)
@@ -1114,9 +1159,9 @@ EOF
        test -r /etc/.relid \
        && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-         && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+         && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
        /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
-         && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+         && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
     3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
          && { echo i486-ncr-sysv4; exit; } ;;
@@ -1125,28 +1170,28 @@ EOF
        test -r /etc/.relid \
            && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
-           && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+           && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
        /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
-           && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+           && { echo i586-ncr-sysv4.3"$OS_REL"; exit; }
        /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
-           && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+           && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
     m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
-       echo m68k-unknown-lynxos${UNAME_RELEASE}
+       echo m68k-unknown-lynxos"$UNAME_RELEASE"
        exit ;;
     mc68030:UNIX_System_V:4.*:*)
        echo m68k-atari-sysv4
        exit ;;
     TSUNAMI:LynxOS:2.*:*)
-       echo sparc-unknown-lynxos${UNAME_RELEASE}
+       echo sparc-unknown-lynxos"$UNAME_RELEASE"
        exit ;;
     rs6000:LynxOS:2.*:*)
-       echo rs6000-unknown-lynxos${UNAME_RELEASE}
+       echo rs6000-unknown-lynxos"$UNAME_RELEASE"
        exit ;;
     PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
-       echo powerpc-unknown-lynxos${UNAME_RELEASE}
+       echo powerpc-unknown-lynxos"$UNAME_RELEASE"
        exit ;;
     SM[BE]S:UNIX_SV:*:*)
-       echo mips-dde-sysv${UNAME_RELEASE}
+       echo mips-dde-sysv"$UNAME_RELEASE"
        exit ;;
     RM*:ReliantUNIX-*:*:*)
        echo mips-sni-sysv4
@@ -1157,7 +1202,7 @@ EOF
     *:SINIX-*:*:*)
        if uname -p 2>/dev/null >/dev/null ; then
                UNAME_MACHINE=`(uname -p) 2>/dev/null`
-               echo ${UNAME_MACHINE}-sni-sysv4
+               echo "$UNAME_MACHINE"-sni-sysv4
        else
                echo ns32k-sni-sysv
        fi
@@ -1177,23 +1222,23 @@ EOF
        exit ;;
     i*86:VOS:*:*)
        # From Paul.Green@stratus.com.
-       echo ${UNAME_MACHINE}-stratus-vos
+       echo "$UNAME_MACHINE"-stratus-vos
        exit ;;
     *:VOS:*:*)
        # From Paul.Green@stratus.com.
        echo hppa1.1-stratus-vos
        exit ;;
     mc68*:A/UX:*:*)
-       echo m68k-apple-aux${UNAME_RELEASE}
+       echo m68k-apple-aux"$UNAME_RELEASE"
        exit ;;
     news*:NEWS-OS:6*:*)
        echo mips-sony-newsos6
        exit ;;
     R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
        if [ -d /usr/nec ]; then
-               echo mips-nec-sysv${UNAME_RELEASE}
+               echo mips-nec-sysv"$UNAME_RELEASE"
        else
-               echo mips-unknown-sysv${UNAME_RELEASE}
+               echo mips-unknown-sysv"$UNAME_RELEASE"
        fi
        exit ;;
     BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
@@ -1208,66 +1253,97 @@ EOF
     BePC:Haiku:*:*)    # Haiku running on Intel PC compatible.
        echo i586-pc-haiku
        exit ;;
+    x86_64:Haiku:*:*)
+       echo x86_64-unknown-haiku
+       exit ;;
     SX-4:SUPER-UX:*:*)
-       echo sx4-nec-superux${UNAME_RELEASE}
+       echo sx4-nec-superux"$UNAME_RELEASE"
        exit ;;
     SX-5:SUPER-UX:*:*)
-       echo sx5-nec-superux${UNAME_RELEASE}
+       echo sx5-nec-superux"$UNAME_RELEASE"
        exit ;;
     SX-6:SUPER-UX:*:*)
-       echo sx6-nec-superux${UNAME_RELEASE}
+       echo sx6-nec-superux"$UNAME_RELEASE"
        exit ;;
     SX-7:SUPER-UX:*:*)
-       echo sx7-nec-superux${UNAME_RELEASE}
+       echo sx7-nec-superux"$UNAME_RELEASE"
        exit ;;
     SX-8:SUPER-UX:*:*)
-       echo sx8-nec-superux${UNAME_RELEASE}
+       echo sx8-nec-superux"$UNAME_RELEASE"
        exit ;;
     SX-8R:SUPER-UX:*:*)
-       echo sx8r-nec-superux${UNAME_RELEASE}
+       echo sx8r-nec-superux"$UNAME_RELEASE"
+       exit ;;
+    SX-ACE:SUPER-UX:*:*)
+       echo sxace-nec-superux"$UNAME_RELEASE"
        exit ;;
     Power*:Rhapsody:*:*)
-       echo powerpc-apple-rhapsody${UNAME_RELEASE}
+       echo powerpc-apple-rhapsody"$UNAME_RELEASE"
        exit ;;
     *:Rhapsody:*:*)
-       echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+       echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"
        exit ;;
     *:Darwin:*:*)
        UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
-       case $UNAME_PROCESSOR in
-           i386)
-               eval $set_cc_for_build
-               if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
-                 if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
-                     (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
-                     grep IS_64BIT_ARCH >/dev/null
-                 then
-                     UNAME_PROCESSOR="x86_64"
-                 fi
-               fi ;;
-           unknown) UNAME_PROCESSOR=powerpc ;;
-       esac
-       echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+       eval "$set_cc_for_build"
+       if test "$UNAME_PROCESSOR" = unknown ; then
+           UNAME_PROCESSOR=powerpc
+       fi
+       if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then
+           if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+               if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+                      (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+                      grep IS_64BIT_ARCH >/dev/null
+               then
+                   case $UNAME_PROCESSOR in
+                       i386) UNAME_PROCESSOR=x86_64 ;;
+                       powerpc) UNAME_PROCESSOR=powerpc64 ;;
+                   esac
+               fi
+               # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
+               if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
+                      (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+                      grep IS_PPC >/dev/null
+               then
+                   UNAME_PROCESSOR=powerpc
+               fi
+           fi
+       elif test "$UNAME_PROCESSOR" = i386 ; then
+           # Avoid executing cc on OS X 10.9, as it ships with a stub
+           # that puts up a graphical alert prompting to install
+           # developer tools.  Any system running Mac OS X 10.7 or
+           # later (Darwin 11 and later) is required to have a 64-bit
+           # processor. This is not true of the ARM version of Darwin
+           # that Apple uses in portable devices.
+           UNAME_PROCESSOR=x86_64
+       fi
+       echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"
        exit ;;
     *:procnto*:*:* | *:QNX:[0123456789]*:*)
        UNAME_PROCESSOR=`uname -p`
-       if test "$UNAME_PROCESSOR" = "x86"; then
+       if test "$UNAME_PROCESSOR" = x86; then
                UNAME_PROCESSOR=i386
                UNAME_MACHINE=pc
        fi
-       echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+       echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE"
        exit ;;
     *:QNX:*:4*)
        echo i386-pc-qnx
        exit ;;
-    NEO-?:NONSTOP_KERNEL:*:*)
-       echo neo-tandem-nsk${UNAME_RELEASE}
+    NEO-*:NONSTOP_KERNEL:*:*)
+       echo neo-tandem-nsk"$UNAME_RELEASE"
        exit ;;
     NSE-*:NONSTOP_KERNEL:*:*)
-       echo nse-tandem-nsk${UNAME_RELEASE}
+       echo nse-tandem-nsk"$UNAME_RELEASE"
+       exit ;;
+    NSR-*:NONSTOP_KERNEL:*:*)
+       echo nsr-tandem-nsk"$UNAME_RELEASE"
        exit ;;
-    NSR-?:NONSTOP_KERNEL:*:*)
-       echo nsr-tandem-nsk${UNAME_RELEASE}
+    NSV-*:NONSTOP_KERNEL:*:*)
+       echo nsv-tandem-nsk"$UNAME_RELEASE"
+       exit ;;
+    NSX-*:NONSTOP_KERNEL:*:*)
+       echo nsx-tandem-nsk"$UNAME_RELEASE"
        exit ;;
     *:NonStop-UX:*:*)
        echo mips-compaq-nonstopux
@@ -1276,18 +1352,18 @@ EOF
        echo bs2000-siemens-sysv
        exit ;;
     DS/*:UNIX_System_V:*:*)
-       echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+       echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE"
        exit ;;
     *:Plan9:*:*)
        # "uname -m" is not consistent, so use $cputype instead. 386
        # is converted to i386 for consistency with other x86
        # operating systems.
-       if test "$cputype" = "386"; then
+       if test "$cputype" = 386; then
            UNAME_MACHINE=i386
        else
            UNAME_MACHINE="$cputype"
        fi
-       echo ${UNAME_MACHINE}-unknown-plan9
+       echo "$UNAME_MACHINE"-unknown-plan9
        exit ;;
     *:TOPS-10:*:*)
        echo pdp10-unknown-tops10
@@ -1308,14 +1384,14 @@ EOF
        echo pdp10-unknown-its
        exit ;;
     SEI:*:*:SEIUX)
-       echo mips-sei-seiux${UNAME_RELEASE}
+       echo mips-sei-seiux"$UNAME_RELEASE"
        exit ;;
     *:DragonFly:*:*)
-       echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
        exit ;;
     *:*VMS:*:*)
        UNAME_MACHINE=`(uname -p) 2>/dev/null`
-       case "${UNAME_MACHINE}" in
+       case "$UNAME_MACHINE" in
            A*) echo alpha-dec-vms ; exit ;;
            I*) echo ia64-dec-vms ; exit ;;
            V*) echo vax-dec-vms ; exit ;;
@@ -1324,182 +1400,48 @@ EOF
        echo i386-pc-xenix
        exit ;;
     i*86:skyos:*:*)
-       echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+       echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`"
        exit ;;
     i*86:rdos:*:*)
-       echo ${UNAME_MACHINE}-pc-rdos
+       echo "$UNAME_MACHINE"-pc-rdos
        exit ;;
     i*86:AROS:*:*)
-       echo ${UNAME_MACHINE}-pc-aros
+       echo "$UNAME_MACHINE"-pc-aros
        exit ;;
     x86_64:VMkernel:*:*)
-       echo ${UNAME_MACHINE}-unknown-esx
+       echo "$UNAME_MACHINE"-unknown-esx
+       exit ;;
+    amd64:Isilon\ OneFS:*:*)
+       echo x86_64-unknown-onefs
        exit ;;
 esac
 
-eval $set_cc_for_build
-cat >$dummy.c <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
-  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
-     I don't know....  */
-  printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
-  printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
-       "4"
-#else
-       ""
-#endif
-       ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
-  printf ("arm-acorn-riscix\n"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
-  printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
-  int version;
-  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
-  if (version < 4)
-    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
-  else
-    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
-  exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
-  printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
-  printf ("ns32k-encore-mach\n"); exit (0);
-#else
-  printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
-  printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
-  printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
-  printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
-    struct utsname un;
-
-    uname(&un);
-
-    if (strncmp(un.version, "V2", 2) == 0) {
-       printf ("i386-sequent-ptx2\n"); exit (0);
-    }
-    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
-       printf ("i386-sequent-ptx1\n"); exit (0);
-    }
-    printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-#  include <sys/param.h>
-#  if defined (BSD)
-#   if BSD == 43
-      printf ("vax-dec-bsd4.3\n"); exit (0);
-#   else
-#    if BSD == 199006
-      printf ("vax-dec-bsd4.3reno\n"); exit (0);
-#    else
-      printf ("vax-dec-bsd\n"); exit (0);
-#    endif
-#   endif
-#  else
-    printf ("vax-dec-bsd\n"); exit (0);
-#  endif
-# else
-    printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
+echo "$0: unable to guess system type" >&2
 
-#if defined (alliant) && defined (i860)
-  printf ("i860-alliant-bsd\n"); exit (0);
-#endif
+case "$UNAME_MACHINE:$UNAME_SYSTEM" in
+    mips:Linux | mips64:Linux)
+       # If we got here on MIPS GNU/Linux, output extra information.
+       cat >&2 <<EOF
 
-  exit (1);
-}
+NOTE: MIPS GNU/Linux systems require a C compiler to fully recognize
+the system type. Please install a C compiler and try again.
 EOF
-
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
-       { echo "$SYSTEM_NAME"; exit; }
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
-    case `getsysinfo -f cpu_type` in
-    c1*)
-       echo c1-convex-bsd
-       exit ;;
-    c2*)
-       if getsysinfo -f scalar_acc
-       then echo c32-convex-bsd
-       else echo c2-convex-bsd
-       fi
-       exit ;;
-    c34*)
-       echo c34-convex-bsd
-       exit ;;
-    c38*)
-       echo c38-convex-bsd
-       exit ;;
-    c4*)
-       echo c4-convex-bsd
-       exit ;;
-    esac
-fi
+       ;;
+esac
 
 cat >&2 <<EOF
-$0: unable to guess system type
 
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
+This script (version $timestamp), has failed to recognize the
+operating system you are using. If your script is old, overwrite *all*
+copies of config.guess and config.sub with the latest versions from:
 
-  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+  https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
 and
-  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+  https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
 
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <config-patches@gnu.org> in order to provide the needed
-information to handle your system.
+If $0 has already been updated, send the following data and any
+information you think might be pertinent to config-patches@gnu.org to
+provide the necessary information to handle your system.
 
 config.guess timestamp = $timestamp
 
@@ -1518,16 +1460,16 @@ hostinfo               = `(hostinfo) 2>/dev/null`
 /usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
 /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
 
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM  = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
+UNAME_MACHINE = "$UNAME_MACHINE"
+UNAME_RELEASE = "$UNAME_RELEASE"
+UNAME_SYSTEM  = "$UNAME_SYSTEM"
+UNAME_VERSION = "$UNAME_VERSION"
 EOF
 
 exit 1
 
 # Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'write-file-functions 'time-stamp)
 # time-stamp-start: "timestamp='"
 # time-stamp-format: "%:y-%02m-%02d"
 # time-stamp-end: "'"
old mode 100755 (executable)
new mode 100644 (file)
index b15df57..818892c
@@ -1,36 +1,31 @@
 #! /bin/sh
 # Configuration validation subroutine script.
-#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-#   2011, 2012 Free Software Foundation, Inc.
+#   Copyright 1992-2018 Free Software Foundation, Inc.
 
-timestamp='2012-07-31'
+timestamp='2018-01-15'
 
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine.  It does not imply ALL GNU software can.
-#
-# This file is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
 # (at your option) any later version.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
 #
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
 # configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
+# the same distribution terms that you use for the rest of that
+# program.  This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
 
 
-# Please send patches to <config-patches@gnu.org>.  Submit a context
-# diff and a properly formatted GNU ChangeLog entry.
+# Please send patches to <config-patches@gnu.org>.
 #
 # Configuration subroutine to validate and canonicalize a configuration type.
 # Supply the specified configuration type as an argument.
@@ -38,7 +33,7 @@ timestamp='2012-07-31'
 # Otherwise, we print the canonical config type on stdout and succeed.
 
 # You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
 
 # This file is supposed to be the same for all GNU packages
 # and recognize all the CPU types, system types and aliases
@@ -58,12 +53,11 @@ timestamp='2012-07-31'
 me=`echo "$0" | sed -e 's,.*/,,'`
 
 usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
-       $0 [OPTION] ALIAS
+Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
 
 Canonicalize a configuration name.
 
-Operation modes:
+Options:
   -h, --help         print this help, then exit
   -t, --time-stamp   print date of last modification, then exit
   -v, --version      print version number, then exit
@@ -73,9 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>."
 version="\
 GNU config.sub ($timestamp)
 
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
-Free Software Foundation, Inc.
+Copyright 1992-2018 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -102,7 +94,7 @@ while test $# -gt 0 ; do
 
     *local*)
        # First pass through any local machine types.
-       echo $1
+       echo "$1"
        exit ;;
 
     * )
@@ -120,24 +112,24 @@ esac
 
 # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
 # Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 case $maybe_os in
   nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
-  linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
-  knetbsd*-gnu* | netbsd*-gnu* | \
-  kopensolaris*-gnu* | \
+  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+  knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
+  kopensolaris*-gnu* | cloudabi*-eabi* | \
   storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
-    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
     ;;
   android-linux)
     os=-linux-android
-    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+    basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
     ;;
   *)
-    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
-    if [ $basic_machine != $1 ]
-    then os=`echo $1 | sed 's/.*-/-/'`
+    basic_machine=`echo "$1" | sed 's/-[^-]*$//'`
+    if [ "$basic_machine" != "$1" ]
+    then os=`echo "$1" | sed 's/.*-/-/'`
     else os=; fi
     ;;
 esac
@@ -156,7 +148,7 @@ case $os in
        -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
        -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
        -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-       -apple | -axis | -knuth | -cray | -microblaze)
+       -apple | -axis | -knuth | -cray | -microblaze*)
                os=
                basic_machine=$1
                ;;
@@ -186,44 +178,44 @@ case $os in
                ;;
        -sco6)
                os=-sco5v6
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
                ;;
        -sco5)
                os=-sco3.2v5
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
                ;;
        -sco4)
                os=-sco3.2v4
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
                ;;
        -sco3.2.[4-9]*)
                os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
                ;;
        -sco3.2v[4-9]*)
                # Don't forget version if it is 3.2v4 or newer.
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
                ;;
        -sco5v6*)
                # Don't forget version if it is 3.2v4 or newer.
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
                ;;
        -sco*)
                os=-sco3.2v2
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
                ;;
        -udk*)
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
                ;;
        -isc)
                os=-isc2.2
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
                ;;
        -clix*)
                basic_machine=clipper-intergraph
                ;;
        -isc*)
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
                ;;
        -lynx*178)
                os=-lynxos178
@@ -235,10 +227,7 @@ case $os in
                os=-lynxos
                ;;
        -ptx*)
-               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
-               ;;
-       -windowsnt*)
-               os=`echo $os | sed -e 's/windowsnt/winnt/'`
+               basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'`
                ;;
        -psos*)
                os=-psos
@@ -259,21 +248,25 @@ case $basic_machine in
        | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
        | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
        | am33_2.0 \
-       | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
-        | be32 | be64 \
+       | arc | arceb \
+       | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+       | avr | avr32 \
+       | ba \
+       | be32 | be64 \
        | bfin \
-       | c4x | clipper \
+       | c4x | c8051 | clipper \
        | d10v | d30v | dlx | dsp16xx \
-       | epiphany \
-       | fido | fr30 | frv \
+       | e2k | epiphany \
+       | fido | fr30 | frv | ft32 \
        | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
        | hexagon \
-       | i370 | i860 | i960 | ia64 \
+       | i370 | i860 | i960 | ia16 | ia64 \
        | ip2k | iq2000 \
+       | k1om \
        | le32 | le64 \
        | lm32 \
        | m32c | m32r | m32rle | m68000 | m68k | m88k \
-       | maxq | mb | microblaze | mcore | mep | metag \
+       | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
        | mips | mipsbe | mipseb | mipsel | mipsle \
        | mips16 \
        | mips64 | mips64el \
@@ -287,26 +280,30 @@ case $basic_machine in
        | mips64vr5900 | mips64vr5900el \
        | mipsisa32 | mipsisa32el \
        | mipsisa32r2 | mipsisa32r2el \
+       | mipsisa32r6 | mipsisa32r6el \
        | mipsisa64 | mipsisa64el \
        | mipsisa64r2 | mipsisa64r2el \
+       | mipsisa64r6 | mipsisa64r6el \
        | mipsisa64sb1 | mipsisa64sb1el \
        | mipsisa64sr71k | mipsisa64sr71kel \
+       | mipsr5900 | mipsr5900el \
        | mipstx39 | mipstx39el \
        | mn10200 | mn10300 \
        | moxie \
        | mt \
        | msp430 \
        | nds32 | nds32le | nds32be \
-       | nios | nios2 \
+       | nios | nios2 | nios2eb | nios2el \
        | ns16k | ns32k \
-       | open8 \
-       | or32 \
-       | pdp10 | pdp11 | pj | pjl \
+       | open8 | or1k | or1knd | or32 \
+       | pdp10 | pj | pjl \
        | powerpc | powerpc64 | powerpc64le | powerpcle \
+       | pru \
        | pyramid \
+       | riscv32 | riscv64 \
        | rl78 | rx \
        | score \
-       | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+       | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
        | sh64 | sh64le \
        | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
        | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
@@ -314,7 +311,8 @@ case $basic_machine in
        | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
        | ubicom32 \
        | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
-       | we32k \
+       | visium \
+       | wasm32 \
        | x86 | xc16x | xstormy16 | xtensa \
        | z8k | z80)
                basic_machine=$basic_machine-unknown
@@ -328,11 +326,14 @@ case $basic_machine in
        c6x)
                basic_machine=tic6x-unknown
                ;;
-       m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
+       leon|leon[3-9])
+               basic_machine=sparc-$basic_machine
+               ;;
+       m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
                basic_machine=$basic_machine-unknown
                os=-none
                ;;
-       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
                ;;
        ms1)
                basic_machine=mt-unknown
@@ -361,7 +362,7 @@ case $basic_machine in
          ;;
        # Object if more than one company name word.
        *-*-*)
-               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
                exit 1
                ;;
        # Recognize the basic CPU types with company name.
@@ -370,26 +371,29 @@ case $basic_machine in
        | aarch64-* | aarch64_be-* \
        | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
        | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
-       | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+       | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
        | arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
        | avr-* | avr32-* \
+       | ba-* \
        | be32-* | be64-* \
        | bfin-* | bs2000-* \
        | c[123]* | c30-* | [cjt]90-* | c4x-* \
-       | clipper-* | craynv-* | cydra-* \
+       | c8051-* | clipper-* | craynv-* | cydra-* \
        | d10v-* | d30v-* | dlx-* \
-       | elxsi-* \
+       | e2k-* | elxsi-* \
        | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
        | h8300-* | h8500-* \
        | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
        | hexagon-* \
-       | i*86-* | i860-* | i960-* | ia64-* \
+       | i*86-* | i860-* | i960-* | ia16-* | ia64-* \
        | ip2k-* | iq2000-* \
+       | k1om-* \
        | le32-* | le64-* \
        | lm32-* \
        | m32c-* | m32r-* | m32rle-* \
        | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-       | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+       | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+       | microblaze-* | microblazeel-* \
        | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
        | mips16-* \
        | mips64-* | mips64el-* \
@@ -403,28 +407,34 @@ case $basic_machine in
        | mips64vr5900-* | mips64vr5900el-* \
        | mipsisa32-* | mipsisa32el-* \
        | mipsisa32r2-* | mipsisa32r2el-* \
+       | mipsisa32r6-* | mipsisa32r6el-* \
        | mipsisa64-* | mipsisa64el-* \
        | mipsisa64r2-* | mipsisa64r2el-* \
+       | mipsisa64r6-* | mipsisa64r6el-* \
        | mipsisa64sb1-* | mipsisa64sb1el-* \
        | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+       | mipsr5900-* | mipsr5900el-* \
        | mipstx39-* | mipstx39el-* \
        | mmix-* \
        | mt-* \
        | msp430-* \
        | nds32-* | nds32le-* | nds32be-* \
-       | nios-* | nios2-* \
+       | nios-* | nios2-* | nios2eb-* | nios2el-* \
        | none-* | np1-* | ns16k-* | ns32k-* \
        | open8-* \
+       | or1k*-* \
        | orion-* \
        | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
        | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+       | pru-* \
        | pyramid-* \
+       | riscv32-* | riscv64-* \
        | rl78-* | romp-* | rs6000-* | rx-* \
        | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
        | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
        | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
        | sparclite-* \
-       | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+       | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
        | tahoe-* \
        | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
        | tile*-* \
@@ -432,6 +442,8 @@ case $basic_machine in
        | ubicom32-* \
        | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
        | vax-* \
+       | visium-* \
+       | wasm32-* \
        | we32k-* \
        | x86-* | x86_64-* | xc16x-* | xps100-* \
        | xstormy16-* | xtensa*-* \
@@ -445,7 +457,7 @@ case $basic_machine in
        # Recognize the various machine names and aliases which stand
        # for a CPU type and a company and sometimes even an OS.
        386bsd)
-               basic_machine=i386-unknown
+               basic_machine=i386-pc
                os=-bsd
                ;;
        3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
@@ -479,7 +491,7 @@ case $basic_machine in
                basic_machine=x86_64-pc
                ;;
        amd64-*)
-               basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        amdahl)
                basic_machine=580-amdahl
@@ -508,6 +520,9 @@ case $basic_machine in
                basic_machine=i386-pc
                os=-aros
                ;;
+       asmjs)
+               basic_machine=asmjs-unknown
+               ;;
        aux)
                basic_machine=m68k-apple
                os=-aux
@@ -521,7 +536,7 @@ case $basic_machine in
                os=-linux
                ;;
        blackfin-*)
-               basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                os=-linux
                ;;
        bluegene*)
@@ -529,13 +544,13 @@ case $basic_machine in
                os=-cnk
                ;;
        c54x-*)
-               basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        c55x-*)
-               basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        c6x-*)
-               basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        c90)
                basic_machine=c90-cray
@@ -624,10 +639,18 @@ case $basic_machine in
                basic_machine=rs6000-bull
                os=-bosx
                ;;
-       dpx2* | dpx2*-bull)
+       dpx2*)
                basic_machine=m68k-bull
                os=-sysv3
                ;;
+       e500v[12])
+               basic_machine=powerpc-unknown
+               os=$os"spe"
+               ;;
+       e500v[12]-*)
+               basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+               os=$os"spe"
+               ;;
        ebmon29k)
                basic_machine=a29k-amd
                os=-ebmon
@@ -717,9 +740,6 @@ case $basic_machine in
        hp9k8[0-9][0-9] | hp8[0-9][0-9])
                basic_machine=hppa1.0-hp
                ;;
-       hppa-next)
-               os=-nextstep3
-               ;;
        hppaosf)
                basic_machine=hppa1.1-hp
                os=-osf
@@ -732,26 +752,26 @@ case $basic_machine in
                basic_machine=i370-ibm
                ;;
        i*86v32)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
                os=-sysv32
                ;;
        i*86v4*)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
                os=-sysv4
                ;;
        i*86v)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
                os=-sysv
                ;;
        i*86sol2)
-               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
                os=-solaris2
                ;;
        i386mach)
                basic_machine=i386-mach
                os=-mach
                ;;
-       i386-vsta | vsta)
+       vsta)
                basic_machine=i386-unknown
                os=-vsta
                ;;
@@ -769,17 +789,17 @@ case $basic_machine in
                basic_machine=m68k-isi
                os=-sysv
                ;;
+       leon-*|leon[3-9]-*)
+               basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'`
+               ;;
        m68knommu)
                basic_machine=m68k-unknown
                os=-linux
                ;;
        m68knommu-*)
-               basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                os=-linux
                ;;
-       m88k-omron*)
-               basic_machine=m88k-omron
-               ;;
        magnum | m3230)
                basic_machine=mips-mips
                os=-sysv
@@ -788,7 +808,7 @@ case $basic_machine in
                basic_machine=ns32k-utek
                os=-sysv
                ;;
-       microblaze)
+       microblaze*)
                basic_machine=microblaze-xilinx
                ;;
        mingw64)
@@ -796,7 +816,7 @@ case $basic_machine in
                os=-mingw64
                ;;
        mingw32)
-               basic_machine=i386-pc
+               basic_machine=i686-pc
                os=-mingw32
                ;;
        mingw32ce)
@@ -811,10 +831,10 @@ case $basic_machine in
                os=-mint
                ;;
        mips3*-*)
-               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+               basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`
                ;;
        mips3*)
-               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+               basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown
                ;;
        monitor)
                basic_machine=m68k-rom68k
@@ -824,15 +844,19 @@ case $basic_machine in
                basic_machine=powerpc-unknown
                os=-morphos
                ;;
+       moxiebox)
+               basic_machine=moxie-unknown
+               os=-moxiebox
+               ;;
        msdos)
                basic_machine=i386-pc
                os=-msdos
                ;;
        ms1-*)
-               basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+               basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'`
                ;;
        msys)
-               basic_machine=i386-pc
+               basic_machine=i686-pc
                os=-msys
                ;;
        mvs)
@@ -871,7 +895,7 @@ case $basic_machine in
                basic_machine=v70-nec
                os=-sysv
                ;;
-       next | m*-next )
+       next | m*-next)
                basic_machine=m68k-next
                case $os in
                    -nextstep* )
@@ -916,6 +940,12 @@ case $basic_machine in
        nsr-tandem)
                basic_machine=nsr-tandem
                ;;
+       nsv-tandem)
+               basic_machine=nsv-tandem
+               ;;
+       nsx-tandem)
+               basic_machine=nsx-tandem
+               ;;
        op50n-* | op60c-*)
                basic_machine=hppa1.1-oki
                os=-proelf
@@ -948,7 +978,7 @@ case $basic_machine in
                os=-linux
                ;;
        parisc-*)
-               basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                os=-linux
                ;;
        pbd)
@@ -964,7 +994,7 @@ case $basic_machine in
                basic_machine=i386-pc
                ;;
        pc98-*)
-               basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        pentium | p5 | k5 | k6 | nexgen | viac3)
                basic_machine=i586-pc
@@ -979,16 +1009,16 @@ case $basic_machine in
                basic_machine=i786-pc
                ;;
        pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
-               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        pentiumpro-* | p6-* | 6x86-* | athlon-*)
-               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
-               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        pentium4-*)
-               basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        pn)
                basic_machine=pn-gould
@@ -998,23 +1028,23 @@ case $basic_machine in
        ppc | ppcbe)    basic_machine=powerpc-unknown
                ;;
        ppc-* | ppcbe-*)
-               basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
-       ppcle | powerpclittle | ppc-le | powerpc-little)
+       ppcle | powerpclittle)
                basic_machine=powerpcle-unknown
                ;;
        ppcle-* | powerpclittle-*)
-               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        ppc64)  basic_machine=powerpc64-unknown
                ;;
-       ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+       ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
-       ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+       ppc64le | powerpc64little)
                basic_machine=powerpc64le-unknown
                ;;
        ppc64le-* | powerpc64little-*)
-               basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        ps2)
                basic_machine=i386-ibm
@@ -1023,7 +1053,11 @@ case $basic_machine in
                basic_machine=i586-unknown
                os=-pw32
                ;;
-       rdos)
+       rdos | rdos64)
+               basic_machine=x86_64-pc
+               os=-rdos
+               ;;
+       rdos32)
                basic_machine=i386-pc
                os=-rdos
                ;;
@@ -1064,17 +1098,10 @@ case $basic_machine in
        sequent)
                basic_machine=i386-sequent
                ;;
-       sh)
-               basic_machine=sh-hitachi
-               os=-hms
-               ;;
        sh5el)
                basic_machine=sh5le-unknown
                ;;
-       sh64)
-               basic_machine=sh64-unknown
-               ;;
-       sparclite-wrs | simso-wrs)
+       simso-wrs)
                basic_machine=sparclite-wrs
                os=-vxworks
                ;;
@@ -1093,7 +1120,7 @@ case $basic_machine in
                os=-sysv4
                ;;
        strongarm-* | thumb-*)
-               basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+               basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
                ;;
        sun2)
                basic_machine=m68000-sun
@@ -1215,6 +1242,9 @@ case $basic_machine in
                basic_machine=hppa1.1-winbond
                os=-proelf
                ;;
+       x64)
+               basic_machine=x86_64-pc
+               ;;
        xbox)
                basic_machine=i686-pc
                os=-mingw32
@@ -1223,20 +1253,12 @@ case $basic_machine in
                basic_machine=xps100-honeywell
                ;;
        xscale-* | xscalee[bl]-*)
-               basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+               basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
                ;;
        ymp)
                basic_machine=ymp-cray
                os=-unicos
                ;;
-       z8k-*-coff)
-               basic_machine=z8k-unknown
-               os=-sim
-               ;;
-       z80-*-coff)
-               basic_machine=z80-unknown
-               os=-sim
-               ;;
        none)
                basic_machine=none-none
                os=-none
@@ -1265,10 +1287,6 @@ case $basic_machine in
        vax)
                basic_machine=vax-dec
                ;;
-       pdp10)
-               # there are many clones, so DEC is not a safe bet
-               basic_machine=pdp10-unknown
-               ;;
        pdp11)
                basic_machine=pdp11-dec
                ;;
@@ -1278,9 +1296,6 @@ case $basic_machine in
        sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
                basic_machine=sh-unknown
                ;;
-       sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
-               basic_machine=sparc-sun
-               ;;
        cydra)
                basic_machine=cydra-cydrome
                ;;
@@ -1300,7 +1315,7 @@ case $basic_machine in
                # Make sure to match an already-canonicalized machine name.
                ;;
        *)
-               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
                exit 1
                ;;
 esac
@@ -1308,10 +1323,10 @@ esac
 # Here we canonicalize certain aliases for manufacturers.
 case $basic_machine in
        *-digital*)
-               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+               basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'`
                ;;
        *-commodore*)
-               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+               basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'`
                ;;
        *)
                ;;
@@ -1322,8 +1337,8 @@ esac
 if [ x"$os" != x"" ]
 then
 case $os in
-       # First match some system type aliases
-       # that might get confused with valid system types.
+       # First match some system type aliases that might get confused
+       # with valid system types.
        # -solaris* is a basic system type, with this one exception.
        -auroraux)
                os=-auroraux
@@ -1334,45 +1349,47 @@ case $os in
        -solaris)
                os=-solaris2
                ;;
-       -svr4*)
-               os=-sysv4
-               ;;
        -unixware*)
                os=-sysv4.2uw
                ;;
        -gnu/linux*)
                os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
                ;;
-       # First accept the basic system types.
+       # es1800 is here to avoid being matched by es* (a different OS)
+       -es1800*)
+               os=-ose
+               ;;
+       # Now accept the basic system types.
        # The portable systems comes first.
-       # Each alternative MUST END IN A *, to match a version number.
+       # Each alternative MUST end in a * to match a version number.
        # -sysv* is not here because it comes later, after sysvr4.
        -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
              | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
              | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
-             | -sym* | -kopensolaris* \
+             | -sym* | -kopensolaris* | -plan9* \
              | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-             | -aos* | -aros* \
+             | -aos* | -aros* | -cloudabi* | -sortix* \
              | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
              | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-             | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
-             | -bitrig* | -openbsd* | -solidbsd* \
+             | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \
+             | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
              | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
              | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
              | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
              | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
-             | -chorusos* | -chorusrdb* | -cegcc* \
+             | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
              | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-             | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
-             | -linux-newlib* | -linux-uclibc* \
-             | -uxpv* | -beos* | -mpeix* | -udk* \
-             | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+             | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+             | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+             | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+             | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \
              | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
              | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
              | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
-             | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+             | -morphos* | -superux* | -rtmk* | -windiss* \
              | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-             | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+             | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
+             | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme*)
        # Remember, each alternative MUST END IN *, to match a version number.
                ;;
        -qnx*)
@@ -1389,12 +1406,12 @@ case $os in
        -nto*)
                os=`echo $os | sed -e 's|nto|nto-qnx|'`
                ;;
-       -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
-             | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+       -sim | -xray | -os68k* | -v88r* \
+             | -windows* | -osx | -abug | -netware* | -os9* \
              | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
                ;;
        -mac*)
-               os=`echo $os | sed -e 's|mac|macos|'`
+               os=`echo "$os" | sed -e 's|mac|macos|'`
                ;;
        -linux-dietlibc)
                os=-linux-dietlibc
@@ -1403,10 +1420,10 @@ case $os in
                os=`echo $os | sed -e 's|linux|linux-gnu|'`
                ;;
        -sunos5*)
-               os=`echo $os | sed -e 's|sunos5|solaris2|'`
+               os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
                ;;
        -sunos6*)
-               os=`echo $os | sed -e 's|sunos6|solaris3|'`
+               os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
                ;;
        -opened*)
                os=-openedition
@@ -1417,12 +1434,6 @@ case $os in
        -wince*)
                os=-wince
                ;;
-       -osfrose*)
-               os=-osfrose
-               ;;
-       -osf*)
-               os=-osf
-               ;;
        -utek*)
                os=-bsd
                ;;
@@ -1447,7 +1458,7 @@ case $os in
        -nova*)
                os=-rtmk-nova
                ;;
-       -ns2 )
+       -ns2)
                os=-nextstep2
                ;;
        -nsk*)
@@ -1469,7 +1480,7 @@ case $os in
        -oss*)
                os=-sysv3
                ;;
-       -svr4)
+       -svr4*)
                os=-sysv4
                ;;
        -svr3)
@@ -1484,35 +1495,38 @@ case $os in
        -ose*)
                os=-ose
                ;;
-       -es1800*)
-               os=-ose
-               ;;
-       -xenix)
-               os=-xenix
-               ;;
        -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
                os=-mint
                ;;
-       -aros*)
-               os=-aros
-               ;;
-       -kaos*)
-               os=-kaos
-               ;;
        -zvmoe)
                os=-zvmoe
                ;;
        -dicos*)
                os=-dicos
                ;;
+       -pikeos*)
+               # Until real need of OS specific support for
+               # particular features comes up, bare metal
+               # configurations are quite functional.
+               case $basic_machine in
+                   arm*)
+                       os=-eabi
+                       ;;
+                   *)
+                       os=-elf
+                       ;;
+               esac
+               ;;
        -nacl*)
                ;;
+       -ios)
+               ;;
        -none)
                ;;
        *)
                # Get rid of the `-' at the beginning of $os.
                os=`echo $os | sed 's/[^-]*-//'`
-               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+               echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
                exit 1
                ;;
 esac
@@ -1547,6 +1561,9 @@ case $basic_machine in
        c4x-* | tic4x-*)
                os=-coff
                ;;
+       c8051-*)
+               os=-elf
+               ;;
        hexagon-*)
                os=-elf
                ;;
@@ -1599,12 +1616,12 @@ case $basic_machine in
        sparc-* | *-sun)
                os=-sunos4.1.1
                ;;
+       pru-*)
+               os=-elf
+               ;;
        *-be)
                os=-beos
                ;;
-       *-haiku)
-               os=-haiku
-               ;;
        *-ibm)
                os=-aix
                ;;
@@ -1644,7 +1661,7 @@ case $basic_machine in
        m88k-omron*)
                os=-luna
                ;;
-       *-next )
+       *-next)
                os=-nextstep
                ;;
        *-sequent)
@@ -1659,9 +1676,6 @@ case $basic_machine in
        i370-*)
                os=-mvs
                ;;
-       *-next)
-               os=-nextstep3
-               ;;
        *-gould)
                os=-sysv
                ;;
@@ -1771,15 +1785,15 @@ case $basic_machine in
                                vendor=stratus
                                ;;
                esac
-               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+               basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"`
                ;;
 esac
 
-echo $basic_machine$os
+echo "$basic_machine$os"
 exit
 
 # Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'write-file-functions 'time-stamp)
 # time-stamp-start: "timestamp='"
 # time-stamp-format: "%:y-%02m-%02d"
 # time-stamp-end: "'"
index f21410a..df8692c 100755 (executable)
--- a/configure
+++ b/configure
@@ -623,6 +623,7 @@ ac_subst_vars='LTLIBOBJS
 LIBOBJS
 EGREP
 GREP
+BASH
 AR
 RANLIB
 INSTALL_DATA
@@ -3896,6 +3897,106 @@ if test -z "$AR"; then
     as_fn_error $? "cannot find ar" "$LINENO" 5
 fi
 
+# Prefer bash, needed for test.sh
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}bash", so it can be a program name with args.
+set dummy ${ac_tool_prefix}bash; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_BASH+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $BASH in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_BASH="$BASH" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_BASH="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+BASH=$ac_cv_path_BASH
+if test -n "$BASH"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BASH" >&5
+$as_echo "$BASH" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_BASH"; then
+  ac_pt_BASH=$BASH
+  # Extract the first word of "bash", so it can be a program name with args.
+set dummy bash; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_BASH+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_BASH in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_BASH="$ac_pt_BASH" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_BASH="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+ac_pt_BASH=$ac_cv_path_ac_pt_BASH
+if test -n "$ac_pt_BASH"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_BASH" >&5
+$as_echo "$ac_pt_BASH" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_BASH" = x; then
+    BASH=""/bin/bash""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    BASH=$ac_pt_BASH
+  fi
+else
+  BASH="$ac_cv_path_BASH"
+fi
+
+
 # If GCC, turn on warnings.
 if test "x$GCC" = "xyes"; then
     CFLAGS="$CFLAGS -Wall -W"
@@ -5776,7 +5877,7 @@ $as_echo "$as_me: using bundled zlib as requested" >&6;}
 fi
 
 if test x${use_bundled_zlib} = xyes; then
-    CPPFLAGS="$CPPFLAGS -I\$(srcdir)/zlib"
+    CPPFLAGS="$CPPFLAGS -I\$(srcdir)/src/zlib"
     extra_libs="zlib/libz.a"
     mkdir -p zlib
 else
@@ -6116,13 +6217,13 @@ else
 $as_echo "$as_me: Developer mode disabled" >&6;}
 fi
 
-if test ! -f $srcdir/version.c; then
+if test ! -f $srcdir/src/version.c; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unable to determine ccache version" >&5
 $as_echo "$as_me: WARNING: unable to determine ccache version" >&2;}
-    echo "const char CCACHE_VERSION[] = \"unknown\";" >version.c
+    echo "const char CCACHE_VERSION[] = \"unknown\";" >src/version.c
 fi
 
-test_suites=`ls $srcdir/test/test_*.c | egrep -v 'BASE|BACKUP|LOCAL|REMOTE' | xargs echo`
+test_suites=`ls $srcdir/unittest/test_*.c | egrep -v 'BASE|BACKUP|LOCAL|REMOTE' | xargs echo`
 
 ac_config_files="$ac_config_files Makefile"
 
@@ -7415,7 +7516,7 @@ cat config.h >>config.h.tmp
 echo '#endif' >>config.h.tmp
 mv config.h.tmp config.h
 
-mkdir -p .deps test
+mkdir -p .deps src unittest
 
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: now build ccache by running make" >&5
index 4095f4b..d055b9e 100644 (file)
@@ -36,6 +36,9 @@ if test -z "$AR"; then
     AC_MSG_ERROR(cannot find ar)
 fi
 
+# Prefer bash, needed for test.sh
+AC_PATH_TOOL(BASH, bash, "/bin/bash")
+
 # If GCC, turn on warnings.
 if test "x$GCC" = "xyes"; then
     CFLAGS="$CFLAGS -Wall -W"
@@ -116,7 +119,7 @@ else
 fi
 
 if test x${use_bundled_zlib} = xyes; then
-    CPPFLAGS="$CPPFLAGS -I\$(srcdir)/zlib"
+    CPPFLAGS="$CPPFLAGS -I\$(srcdir)/src/zlib"
     extra_libs="zlib/libz.a"
     mkdir -p zlib
 else
@@ -163,13 +166,13 @@ else
     AC_MSG_NOTICE(Developer mode disabled)
 fi
 
-if test ! -f $srcdir/version.c; then
+if test ! -f $srcdir/src/version.c; then
     AC_MSG_WARN(unable to determine ccache version)
-    echo "const char CCACHE_VERSION@<:@@:>@ = \"unknown\";" >version.c
+    echo "const char CCACHE_VERSION@<:@@:>@ = \"unknown\";" >src/version.c
 fi
 
 dnl Find test suite files.
-test_suites=`ls $srcdir/test/test_*.c | egrep -v 'BASE|BACKUP|LOCAL|REMOTE' | xargs echo`
+test_suites=`ls $srcdir/unittest/test_*.c | egrep -v 'BASE|BACKUP|LOCAL|REMOTE' | xargs echo`
 
 AC_CONFIG_FILES([Makefile])
 AC_OUTPUT
@@ -182,7 +185,7 @@ cat config.h >>config.h.tmp
 echo '#endif' >>config.h.tmp
 mv config.h.tmp config.h
 
-mkdir -p .deps test
+mkdir -p .deps src unittest
 
 
 AC_MSG_NOTICE(now build ccache by running make)
index d141b78..6a20c9e 100644 (file)
--- a/dev.mk.in
+++ b/dev.mk.in
@@ -5,7 +5,9 @@ all_cppflags += -MD -MP -MF .deps/$(subst .._,,$(subst /,_,$<)).d
 
 ASCIIDOC = asciidoc
 CPPCHECK = cppcheck
-CPPCHECK_SUPPRESSIONS = cppcheck-suppressions.txt
+CPPCHECK_SUPPRESSIONS = misc/cppcheck-suppressions.txt
+SCAN_BUILD = scan-build
+DOCKER = docker
 GPERF = gperf
 XSLTPROC = xsltproc
 MANPAGE_XSL = $(shell if [ -e /usr/local/etc/asciidoc/docbook-xsl/manpage.xsl ]; \
@@ -25,44 +27,41 @@ ifneq ($(shell uname), Darwin)
     dist_archives += ccache-$(version).tar.xz
 endif
 
-generated_docs = ccache.1 AUTHORS.html LICENSE.html MANUAL.html NEWS.html
+generated_docs = ccache.1 doc/AUTHORS.html LICENSE.html doc/MANUAL.html doc/NEWS.html
 built_dist_files = $(generated_docs)
 
 headers = \
-    ccache.h \
-    compopt.h \
-    conf.h \
-    counters.h \
-    getopt_long.h \
-    hashtable.h \
-    hashtable_itr.h \
-    hashtable_private.h \
-    hashutil.h \
-    language.h \
-    macroskip.h \
-    manifest.h \
-    mdfour.h \
-    murmurhashneutral2.h \
-    system.h \
-    test/framework.h \
-    test/suites.h \
-    test/util.h
+    src/ccache.h \
+    src/compopt.h \
+    src/conf.h \
+    src/counters.h \
+    src/getopt_long.h \
+    src/hashtable.h \
+    src/hashtable_itr.h \
+    src/hashtable_private.h \
+    src/hashutil.h \
+    src/language.h \
+    src/macroskip.h \
+    src/manifest.h \
+    src/mdfour.h \
+    src/murmurhashneutral2.h \
+    src/system.h \
+    unittest/framework.h \
+    unittest/suites.h \
+    unittest/util.h
 
 files_to_clean += *.tar.bz2 *.tar.gz *.tar.xz *.xml .deps/* perfdir.*
-files_to_distclean += $(built_dist_files) version.c test/suites.h
+files_to_distclean += $(built_dist_files) version.c unittest/suites.h
 files_to_distclean += .deps version.c dev.mk
 
 source_dist_files = \
     $(base_sources) \
     $(headers) \
     $(test_sources) \
-    AUTHORS.txt \
+    CONTRIBUTING.md \
     GPL-3.0.txt \
-    HACKING.txt \
     LICENSE.txt \
-    MANUAL.txt \
     Makefile.in \
-    NEWS.txt \
     README.md \
     autogen.sh \
     config.guess \
@@ -70,27 +69,31 @@ source_dist_files = \
     config.sub \
     configure \
     configure.ac \
-    confitems.gperf \
-    confitems_lookup.c \
     dev.mk.in \
-    envtoconfitems.gperf \
-    envtoconfitems_lookup.c \
+    doc/AUTHORS.txt \
+    doc/MANUAL.txt \
+    doc/NEWS.txt \
     install-sh \
     m4 \
-    main.c \
-    test.sh \
-    zlib/*.c \
-    zlib/*.h
+    src/confitems.gperf \
+    src/confitems_lookup.c \
+    src/envtoconfitems.gperf \
+    src/envtoconfitems_lookup.c \
+    src/main.c \
+    src/zlib/*.c \
+    src/zlib/*.h \
+    test/run \
+    test/suites/*
 
 dist_files = \
     $(addprefix $(srcdir)/, $(source_dist_files)) \
     $(built_dist_files)
 
 uncrustify_exclude_files = \
-    getopt_long.c \
-    hashtable.c \
-    hashtable_itr.c \
-    snprintf.c
+    src/getopt_long.c \
+    src/hashtable.c \
+    src/hashtable_itr.c \
+    src/snprintf.c
 
 ifneq ($(shell sed 's/.*"\(.*\)".*/\1/' version.c 2>/dev/null),$(version))
   $(shell echo 'const char CCACHE_VERSION[] = "$(version)";' >version.c)
@@ -99,7 +102,7 @@ version.o: version.c
 
 %_lookup.c: %.gperf
        $(GPERF) $< | awk '/#ifdef __GNUC__/ { ++i; if (i == 2) { print "static"; }} {print}' >$@
-       echo "static const size_t `echo $* | tr a-z A-Z`_TOTAL_KEYWORDS = `sed -nr 's/.*TOTAL_KEYWORDS = ([0-9]+).*/\1/p' $@`;" >>$@
+       echo "static const size_t $$(echo $(notdir $*) | tr a-z A-Z)_TOTAL_KEYWORDS = $$(sed -nr 's/.*TOTAL_KEYWORDS = ([0-9]+).*/\1/p' $@);" >>$@
 
 .PHONY: dist
 dist: $(dist_archives)
@@ -110,7 +113,7 @@ $(dist_archives): $(dist_files)
        mkdir $$dir && \
        (cd $(srcdir) && \
         rsync -r --relative $(source_dist_files) $$dir) && \
-       cp $(srcdir)/INSTALL-from-release-archive.md $$dir/INSTALL.md && \
+       cp $(srcdir)/doc/INSTALL-from-release-archive.md $$dir/INSTALL.md && \
        cp $(built_dist_files) $$dir && \
        echo "Remove this file to enable developer mode." >$$dir/dev_mode_disabled && \
        (cd $$tmpdir && \
@@ -144,9 +147,15 @@ docs: $(generated_docs)
 %.xml: %.txt
        $(ASCIIDOC) -a revnumber=$(version) -d manpage -b docbook $<
 
-ccache.1: MANUAL.xml
+ccache.1: doc/MANUAL.xml
        $(XSLTPROC) --nonet $(MANPAGE_XSL) $<
 
+.PHONY: update-authors
+update-authors:
+       git log --pretty=format:"* %aN <%aE>" \
+         | sort -u \
+         | perl -00 -p -i -e 's/^\*.*/<STDIN> . "\n"/es' doc/AUTHORS.txt
+
 .PHONY: check-syntax
 check-syntax:
        $(CC) $(all_cppflags) -I. $(all_cflags) -S -o /dev/null $(CHK_SOURCES)
@@ -154,11 +163,20 @@ check-syntax:
 .PHONY: cppcheck
 cppcheck:
        $(CPPCHECK) --suppressions-list=$(CPPCHECK_SUPPRESSIONS) \
-         --inline-suppr -q --enable=all \
-         $(non_3pp_sources) main.c $(test_sources)
+         --inline-suppr -q --enable=all --force \
+         $(non_3pp_sources) src/main.c $(test_sources)
 
 .PHONY: uncrustify
 uncrustify:
-       uncrustify -c uncrustify.cfg --no-backup --replace $(filter-out $(uncrustify_exclude_files), $(base_sources)) $(test_sources)
+       uncrustify -c misc/uncrustify.cfg --no-backup --replace $(filter-out $(uncrustify_exclude_files), $(base_sources)) $(test_sources)
+
+.PHONY: analyze
+analyze:
+       $(SCAN_BUILD) --use-cc=$(CC) ./configure
+       $(SCAN_BUILD) --use-cc=$(CC) --status-bugs $(MAKE) -B
+
+.PHONY: docker
+docker: misc/Dockerfile
+       $(DOCKER) build $(srcdir)
 
 -include .deps/*.d
similarity index 89%
rename from AUTHORS.txt
rename to doc/AUTHORS.txt
index dc2cec4..0ac83eb 100644 (file)
@@ -17,15 +17,14 @@ ccache is a collective work with contributions from many people, including:
 * Andrew Tridgell <tridge@samba.org>
 * Bernhard Bauer <bauerb@chromium.org>
 * Björn Jacke <bj@sernet.de>
-* Bo Rydberg <bolry@hotmail.com>
 * Chiaki Ishikawa <ishikawa@yk.rim.or.jp>
-* Chris AtLee <chris@atlee.ca>
+* Chris AtLee <catlee@mozilla.com>
 * Clemens Rabe <clemens.rabe@gmail.com>
 * David Givone <david@givone.net>
 * Edward Z. Yang <ezyang@fb.com>
-* Eric Blau <Eric.Blau@tekelec.com>
 * Francois Marier <francois@debian.org>
 * Geert Bosch <geert@mongodb.com>
+* Grigory Entin <grigorye@dins.ru>
 * Hongli Lai <hongli@phusion.nl>
 * Ivan Vaigult <i.vaigult@gmail.com>
 * Jiang Jiang <jiangj@opera.com>
@@ -36,14 +35,16 @@ ccache is a collective work with contributions from many people, including:
 * Jørgen P. Tjernø <jorgen@valvesoftware.com>
 * Justin Lebar <justin.lebar@gmail.com>
 * Karl Chen <quarl@cs.berkeley.edu>
-* KonaBlend <kona8lend@gmail.com>
+* Kona Blend <kona8lend@gmail.com>
 * Kovarththanan Rajaratnam <kovarththanan.rajaratnam@gmail.com>
 * Lalit Chhabra <lchhabra@linuxmail.org>
 * Lars Gustäbel <lars@gustaebel.de>
 * Leanid Chaika <leanid.chaika@gmail.com>
 * LuboÅ¡ Luňák <l.lunak@centrum.cz>
 * Mark Starovoytov <starovoytov.mark@googlemail.com>
+* Martin Ettl <ettl.martin78@gmail.com>
 * Martin Pool <mbp@sourcefrog.net>
+* Mathias De Maré <mathias.de_mare@nokia.com>
 * Matthias Kretz <kretz@kde.org>
 * Melven Roehrig-Zoellner <Melven.Roehrig-Zoellner@DLR.de>
 * Michael Marineau <michael.marineau@coreos.com>
@@ -51,23 +52,26 @@ ccache is a collective work with contributions from many people, including:
 * Mihai Serban <mihai.serban@intel.com>
 * Mike Frysinger <vapier@gentoo.org>
 * Mikhail Kolomeytsev <mkolom@yandex-team.ru>
+* Mostyn Bramley-Moore <mostyn@antipode.se>
 * Neil Mushell <nmushell@bloomberg.net>
 * Nick Schultz <nick.schultz@intel.com>
 * Norbert Lange <nolange79@gmail.com>
 * Oded Shimon <oded@istraresearch.com>
-* orbitcowboy <ettl.martin78@gmail.com>
 * Orgad Shaneh <orgad.shaneh@audiocodes.com>
 * Orion Poplawski <orion@cora.nwra.com>
 * Owen Mann <owen@mann.org>
 * Patrick von Reth <vonreth@kde.org>
 * Paul Griffith <paulg@cse.yorku.ca>
 * Pavel Boldin <pboldin@cloudlinux.com>
+* Per Nordlöw <per.nordlow@autoliv.com>
 * Philippe Proulx <eeppeliteloop@gmail.com>
 * Ramiro Polla <ramiro.polla@gmail.com>
 * Robin H. Johnson <robbat2@gentoo.org>
 * Rolf Bjarne Kvinge <rolf@xamarin.com>
 * RW <fbsd06@mlists.homeunix.com>
 * Ryan Brown <ryb@ableton.com>
+* Sam Gross <sgross@fb.com>
+* Thomas Röfer <Thomas.Roefer@dfki.de>
 * Tim Potter <tpot@samba.org>
 * Tom Hughes <tomtheengineer@gmail.com>
 * Tor Arne Vestbø <tor.arne.vestbo@qt.io>
similarity index 94%
rename from MANUAL.txt
rename to doc/MANUAL.txt
index c6ebca3..50fc574 100644 (file)
@@ -43,7 +43,6 @@ Features
 * Can cache compilations that generate warnings.
 * Easy installation.
 * Low overhead.
-* Optionally uses hard links where possible to avoid copies.
 * Optionally compresses files in the cache to reduce disk space.
 
 
@@ -222,11 +221,13 @@ Boolean values
 Some settings are boolean values (i.e. truth values). In a configuration file,
 such values must be set to the string *true* or *false*. For the corresponding
 environment variables, the semantics are a bit different: a set environment
-variable means ``true'' regardless of the value (even if set to the empty
-string), and an unset environment variable means ``false''. Each boolean
-environment variable also has a negated form starting with *CCACHE_NO*. For
-example, *CCACHE_COMPRESS* can be set to force compression and
-*CCACHE_NOCOMPRESS* can be set to force no compression.
+variable means ``true'' (even if set to the empty string), the following
+case-insensitive negative values are considered an error (rather than
+surprising the user): *0*, *false*, *disable* and *no*, and an unset
+environment variable means ``false''. Each boolean environment variable also
+has a negated form starting with *CCACHE_NO*. For example, *CCACHE_COMPRESS*
+can be set to force compression and *CCACHE_NOCOMPRESS* can be set to force no
+compression.
 
 
 Configuration settings
@@ -368,13 +369,23 @@ WRAPPERS>>.
 *hard_link* (*CCACHE_HARDLINK* or *CCACHE_NOHARDLINK*, see <<_boolean_values,Boolean values>> above)::
 
     If true, ccache will attempt to use hard links from the cache directory
-    when creating the compiler output rather than using a file copy. Using hard
-    links may be slightly faster in some situations, but can confuse programs
-    like ``make'' that rely on modification times. Another thing to keep in
-    mind is that if the resulting object file is modified in any way, this
-    corrupts the cached object file as well. Hard links are never made for
-    compressed cache files. This means that you should not enable compression
-    if you want to use hard links. The default is false.
+    when creating the compiler output rather than using a file copy. Hard links
+    are never made for compressed cache files. This means that you should not
+    enable compression if you want to use hard links. The default is false.
++
+WARNING: Do not enable this option unless you are aware of the consequences.
+Using hard links may be slightly faster in some situations, but there are
+several pitfalls since the resulting object file will share i-node with the
+cached object file:
++
+1. If the resulting object file is modified in any way, the cached object file
+   will be modified as well. For instance, if you run *strip object.o* or *echo
+   >object.o*, you will corrupt the cache.
+2. Programs that rely on modification times (like ``make'') can be confused
+   since ccache updates the cached files' modification times as part of the
+   automatic cache size management. This will affect object files in the build
+   tree as well, which can retrigger the linking step even though nothing
+   really has changed.
 
 *hash_dir* (*CCACHE_HASHDIR* or *CCACHE_NOHASHDIR*, see <<_boolean_values,Boolean values>> above)::
 
@@ -483,6 +494,13 @@ of the original source code. This makes cache misses slightly faster since the
 source code only has to be preprocessed once. The downside is that some
 compilers won't produce the same result (for instance diagnostics warnings)
 when compiling preprocessed source code.
++
+A solution to the above mentioned downside is to set *run_second_cpp* to false
+and pass *-fdirectives-only* (for GCC) or *-frewrite-includes* (for Clang) to
+the compiler. This will cause the compiler to leave the macros and other
+preprocessor information, and only process the *#include* directives. When run
+in this way, the preprocessor arguments will be passed to the compiler since it
+still has to do _some_ preprocessing (like macros).
 
 *sloppiness* (*CCACHE_SLOPPINESS*)::
 
@@ -550,8 +568,7 @@ NOTE: In previous versions of ccache, *CCACHE_TEMPDIR* had to be on the same
     unifier changes the hash, so cached compilations produced when the unifier
     is enabled cannot be reused when the unifier is disabled, and vice versa.
     Enabling the unifier may result in incorrect line number information in
-    compiler warning messages and expansions of the *\_\_LINE__* macro. Also
-    note that enabling the unifier implies turning off the direct mode.
+    compiler warning messages and expansions of the *\_\_LINE__* macro.
 
 
 Cache size management
@@ -800,7 +817,6 @@ The direct mode will be disabled if any of the following holds:
 * the configuration setting *direct_mode* is false
 * a modification time of one of the include files is too new (needed to avoid a
   race condition)
-* the unifier is enabled (the configuration setting *unify* is true)
 * a compiler option not supported by the direct mode is used:
 ** a *-Wp,_X_* compiler option other than *-Wp,-MD,_path_*,
    *-Wp,-MMD,_path_* and *-Wp,-D_define_*
@@ -971,6 +987,19 @@ Caveats
 
 * The direct mode fails to pick up new header files in some rare scenarios. See
   <<_the_direct_mode,THE DIRECT MODE>> above.
+* When run via ccache, warning messages produced by GCC 4.9 and newer will only
+  be colored when the environment variable *GCC_COLORS* is set. An alternative
+  to setting *GCC_COLORS* is to pass `-fdiagnostics-color` explicitly when
+  compiling (but then color codes will also be present when redirecting stderr
+  to a file).
+* If ccache guesses that the compiler may emit colored warnings, then a
+  compilation with stderr referring to a TTY will be considered different from
+  a compilation with a redirected stderr, thus not sharing cache entries. This
+  happens for clang by default and for GCC when *GCC_COLORS* is set as
+  mentioned above. If you want to share cache hits, you can pass
+  `-f[no-]diagnostics-color` (GCC) or `-f[no-]color-diagnostics` (clang)
+  explicitly when compiling (but then color codes will be either on or off for
+  both the TTY and the redirected case).
 
 
 Troubleshooting
similarity index 93%
rename from NEWS.txt
rename to doc/NEWS.txt
index 7c6f042..6176107 100644 (file)
--- a/NEWS.txt
@@ -1,11 +1,62 @@
 ccache news
 ===========
 
+ccache 3.4
+----------
+Release date: 2018-02-11
+
+New features and enhancements
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- The compiler option form `--sysroot arg` is now handled like the documented
+  `--sysroot=arg` form.
+
+- Added support for caching `.su` files generated by GCC flag `-fstack-usage`.
+
+- ccache should now work with distcc's ``pump'' wrapper.
+
+- The optional unifier is no longer disabled when the direct mode is enabled.
+
+- Added support for nvcc compiler options `--compiler-bindir/-ccbin`,
+  `--output-directory/-odir` and `--libdevice-directory/-ldir`.
+
+- Boolean environment variable settings no longer accept the following
+  (case-insensitive) values: `0`, `false`, `disable` and `no`. All other values
+  are accepted and taken to mean ``true''. This is to stop users from setting
+  e.g. `CCACHE_DISABLE=0` and then expect the cache to be used.
+
+- Improved support for `run_second_cpp = false`: If combined with passing
+  `-fdirectives-only` (GCC) or `frewrite-includes` (Clang) to the compiler,
+  diagnostics warnings and similar will be correct.
+
+- An implicit `-MQ` is now passed to the preprocessor only if the object file
+  extension is non-standard. This should make it easier to use EDG-based
+  compilers (e.g. GHS) which don't understand `-MQ`.
+
+- ccache now treats an unreadable configuration file just like a missing
+  configuration file.
+
+- Documented more pitfalls with enabling `hard_links` (`CCACHE_HARDLINK`).
+
+- Documented caveats related to colored warnings from compilers.
+
+
+Bug fixes
+~~~~~~~~~
+
+- File size and number counters are now updated correctly when files are
+  overwritten in the cache, e.g. when using `CCACHE_RECACHE`.
+
+- `run_second_cpp` is now forced for nvcc.
+
+- Fixed how the nvcc options `-optf` and `-odir` are handled.
+
+
 ccache 3.3.6
 ------------
 Release date: 2018-01-28
 
-New features and improvements
+New features and enhancements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 - Improved instructions on how to get cache hits between different working
@@ -23,7 +74,7 @@ ccache 3.3.5
 Release date: 2018-01-13
 
 
-New features and improvements
+New features and enhancements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 - Documented how automatic cache cleanup works.
@@ -69,7 +120,7 @@ ccache 3.3.4
 ------------
 Release date: 2017-02-17
 
-New features and improvements
+New features and enhancements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 - Documented the different cache statistics counters.
@@ -88,7 +139,6 @@ Bug fixes
 
 - Fixed undefined behavior warnings in ccache found by `-fsanitize=undefined`.
 
-
 ccache 3.3.3
 ------------
 Release date: 2016-10-26
@@ -142,7 +192,7 @@ Notes
 - A C99-compatible compiler is now required to build ccache.
 
 
-New features and improvements
+New features and enhancements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 - The configuration option `run_second_cpp` (`CCACHE_CPP2`) now defaults to
@@ -289,7 +339,7 @@ ccache 3.2.5
 Release date: 2016-04-17
 
 
-New features and improvements
+New features and enhancements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 - Only pass clang-specific `-stdlib=` to the preprocessor.
@@ -356,7 +406,7 @@ ccache 3.2.3
 Release date: 2015-08-16
 
 
-New features and improvements
+New features and enhancements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 - Added support for compiler option `-gsplit-dwarf`.
@@ -382,7 +432,7 @@ ccache 3.2.2
 Release date: 2015-05-10
 
 
-New features and improvements
+New features and enhancements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 - Added support for `CCACHE_COMPILERCHECK=string:<value>`. This is a faster
@@ -452,7 +502,7 @@ ccache 3.2
 Release date: 2014-11-17
 
 
-New features and improvements
+New features and enhancements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 - Added support for configuring ccache via one or several configuration files
@@ -596,7 +646,7 @@ ccache 3.1.10
 Release date: 2014-10-19
 
 
-New features and improvements
+New features and enhancements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 - Added support for the `-Xclang` compiler option.
@@ -675,7 +725,7 @@ ccache 3.1.8
 Release date: 2012-08-11
 
 
-New features and improvements
+New features and enhancements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 - Made paths to dependency files relative in order to increase cache hits.
@@ -754,7 +804,7 @@ ccache 3.1.6
 Release date: 2011-08-21
 
 
-New features and improvements
+New features and enhancements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 - Rewrite argument to `--sysroot` if `CCACHE_BASEDIR` is used.
@@ -773,7 +823,7 @@ ccache 3.1.5
 Release date: 2011-05-29
 
 
-New features and improvements
+New features and enhancements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 - Added a new statistics counter named ``called for preprocessing''.
@@ -902,7 +952,7 @@ ccache 3.1
 Release date: 2010-09-16
 
 
-New features and improvements
+New features and enhancements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 - Added support for hashing the output of a custom command (e.g. `%compiler%
@@ -1013,7 +1063,7 @@ Upgrade notes
   want, unless you plan to keep using an older ccache version.
 
 
-New features and improvements
+New features and enhancements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 - ccache now has a ``direct mode'' where it computes a hash of the source code
similarity index 100%
rename from args.c
rename to src/args.c
similarity index 89%
rename from ccache.c
rename to src/ccache.c
index d863a5a..9dfdbfc 100644 (file)
--- a/ccache.c
@@ -96,11 +96,17 @@ static char *output_dep;
 // The path to the coverage file (implicit when using -ftest-coverage).
 static char *output_cov;
 
+// The path to the stack usage (implicit when using -fstack-usage).
+static char *output_su;
+
 // Diagnostic generation information (clang). Contains pathname if not NULL.
-static char *output_dia = NULL;
+static char *output_dia;
+
+// Split dwarf information (GCC 4.8 and up). Contains pathname if not NULL.
+static char *output_dwo;
 
-// Split dwarf information (GCC 4.8 andup). Contains pathname if not NULL.
-static char *output_dwo = NULL;
+// Language to use for the compilation target (see language.c).
+static const char *actual_language;
 
 // Array for storing -arch options.
 #define MAX_ARCH_ARGS 10
@@ -127,6 +133,10 @@ static char *cached_dep;
 // (cachedir/a/b/cdef[...]-size.gcno).
 static char *cached_cov;
 
+// Full path to the file containing the stack usage
+// (cachedir/a/b/cdef[...]-size.su).
+static char *cached_su;
+
 // Full path to the file containing the diagnostic information (for clang)
 // (cachedir/a/b/cdef[...]-size.dia).
 static char *cached_dia;
@@ -137,10 +147,6 @@ static char *cached_dia;
 // Contains NULL if -gsplit-dwarf is not given.
 static char *cached_dwo;
 
-// using_split_dwarf is true if "-gsplit-dwarf" is given to the compiler (GCC
-// 4.8 and up).
-bool using_split_dwarf = false;
-
 // Full path to the file containing the manifest
 // (cachedir/a/b/cdef[...]-size.manifest).
 static char *manifest_path;
@@ -171,6 +177,17 @@ static bool generating_dependencies;
 // Is the compiler being asked to output coverage?
 static bool generating_coverage;
 
+// Is the compiler being asked to output stack usage?
+static bool generating_stackusage;
+
+// Us the compiler being asked to generate diagnostics
+// (--serialize-diagnostics)?
+static bool generating_diagnostics;
+
+// Is the compiler being asked to separate dwarf debug info into a separate
+// file (-gsplit-dwarf)"?
+static bool using_split_dwarf;
+
 // Relocating debuginfo in the format old=new.
 static char **debug_prefix_maps = NULL;
 
@@ -452,6 +469,45 @@ clean_up_internal_tempdir(void)
        closedir(dir);
 }
 
+// Note that these compiler checks are unreliable, so nothing should
+// hard-depend on them.
+
+static bool
+compiler_is_clang(struct args *args)
+{
+       char *name = basename(args->argv[0]);
+       bool result = strstr(name, "clang") != NULL;
+       free(name);
+       return result;
+}
+
+static bool
+compiler_is_gcc(struct args *args)
+{
+       char *name = basename(args->argv[0]);
+       bool result = strstr(name, "gcc") || strstr(name, "g++");
+       free(name);
+       return result;
+}
+
+static bool
+compiler_is_nvcc(struct args *args)
+{
+       char *name = basename(args->argv[0]);
+       bool result = strstr(name, "nvcc") != NULL;
+       free(name);
+       return result;
+}
+
+static bool
+compiler_is_pump(struct args *args)
+{
+       char *name = basename(args->argv[0]);
+       bool result = str_eq(name, "pump") || str_eq(name, "distcc-pump");
+       free(name);
+       return result;
+}
+
 static char *
 get_current_working_dir(void)
 {
@@ -697,7 +753,7 @@ make_relative_path(char *path)
 // - Stores the paths and hashes of included files in the global variable
 //   included_files.
 static bool
-process_preprocessed_file(struct mdfour *hash, const char *path)
+process_preprocessed_file(struct mdfour *hash, const char *path, bool pump)
 {
        char *data;
        size_t size;
@@ -851,6 +907,19 @@ process_preprocessed_file(struct mdfour *hash, const char *path)
                        cc_log("Found unsupported .inc" "bin directive in source code");
                        stats_update(STATS_UNSUPPORTED_DIRECTIVE);
                        failed();
+               } else if (pump && strncmp(q, "_________", 9) == 0) {
+                       // Unfortunately the distcc-pump wrapper outputs standard output lines:
+                       // __________Using distcc-pump from /usr/bin
+                       // __________Using # distcc servers in pump mode
+                       // __________Shutting down distcc-pump include server
+                       while (q < end && *q != '\n') {
+                               q++;
+                       }
+                       if (*q == '\n') {
+                               q++;
+                       }
+                       p = q;
+                       continue;
                } else {
                        q++;
                }
@@ -951,41 +1020,85 @@ out:
        free(tmp_file);
 }
 
-// Copy or link a file to the cache.
+// Helper method for copy_file_to_cache and move_file_to_cache_same_fs.
 static void
-put_file_in_cache(const char *source, const char *dest)
+do_copy_or_move_file_to_cache(const char *source, const char *dest, bool copy)
 {
        assert(!conf->read_only);
        assert(!conf->read_only_direct);
 
-       bool do_link = conf->hard_link && !conf->compression;
-       if (do_link) {
-               x_unlink(dest);
-               int ret = link(source, dest);
-               if (ret != 0) {
-                       cc_log("Failed to link %s to %s: %s", source, dest, strerror(errno));
-                       cc_log("Falling back to copying");
-                       do_link = false;
-               }
-       }
-       if (!do_link) {
-               int ret = copy_file(
-                 source, dest, conf->compression ? conf->compression_level : 0);
-               if (ret != 0) {
-                       cc_log("Failed to copy %s to %s: %s", source, dest, strerror(errno));
-                       stats_update(STATS_ERROR);
-                       failed();
+       struct stat orig_dest_st;
+       bool orig_dest_existed = stat(dest, &orig_dest_st) == 0;
+       int compression_level = conf->compression ? conf->compression_level : 0;
+       bool do_move = !copy && !conf->compression;
+       bool do_link = copy && conf->hard_link && !conf->compression;
+
+       if (do_move) {
+               move_uncompressed_file(source, dest, compression_level);
+       } else {
+               if (do_link) {
+                       x_unlink(dest);
+                       int ret = link(source, dest);
+                       if (ret == 0) {
+                       } else {
+                               cc_log("Failed to link %s to %s: %s", source, dest, strerror(errno));
+                               cc_log("Falling back to copying");
+                               do_link = false;
+                       }
+               }
+               if (!do_link) {
+                       int ret = copy_file(source, dest, compression_level);
+                       if (ret != 0) {
+                               cc_log("Failed to copy %s to %s: %s", source, dest, strerror(errno));
+                               stats_update(STATS_ERROR);
+                               failed();
+                       }
                }
        }
 
-       cc_log("Stored in cache: %s -> %s", source, dest);
+       if (!copy && conf->compression) {
+               // We fell back to copying since dest should be compressed, so clean up.
+               x_unlink(source);
+       }
+
+       cc_log("Stored in cache: %s -> %s (%s)",
+              source,
+              dest,
+              do_move ? "moved" : (do_link ? "linked" : "copied"));
 
        struct stat st;
        if (x_stat(dest, &st) != 0) {
                stats_update(STATS_ERROR);
                failed();
        }
-       stats_update_size(file_size(&st), 1);
+       stats_update_size(
+         file_size(&st) - (orig_dest_existed ? file_size(&orig_dest_st) : 0),
+         orig_dest_existed ? 0 : 1);
+}
+
+// Copy a file into the cache.
+//
+// dest must be a path in the cache (see get_path_in_cache). source does not
+// have to be on the same file system as dest.
+//
+// An attempt will be made to hard link source to dest if conf->hard_link is
+// true and conf->compression is false, otherwise copy. dest will be compressed
+// if conf->compression is true.
+static void
+copy_file_to_cache(const char *source, const char *dest)
+{
+       do_copy_or_move_file_to_cache(source, dest, true);
+}
+
+// Move a file into the cache.
+//
+// dest must be a path in the cache (see get_path_in_cache). source must be on
+// the same file system as dest. dest will be compressed if conf->compression
+// is true.
+static void
+move_file_to_cache_same_fs(const char *source, const char *dest)
+{
+       do_copy_or_move_file_to_cache(source, dest, false);
 }
 
 // Copy or link a file from the cache.
@@ -1003,8 +1116,7 @@ get_file_from_cache(const char *source, const char *dest)
 
        if (ret == -1) {
                if (errno == ENOENT || errno == ESTALE) {
-                       // Someone removed the file just before we began copying?
-                       cc_log("Cache file %s just disappeared from cache", source);
+                       cc_log("File missing in cache: %s", source);
                        stats_update(STATS_MISSING);
                } else {
                        cc_log("Failed to %s %s to %s: %s",
@@ -1020,7 +1132,10 @@ get_file_from_cache(const char *source, const char *dest)
                x_unlink(cached_stderr);
                x_unlink(cached_obj);
                x_unlink(cached_dep);
+               x_unlink(cached_cov);
+               x_unlink(cached_su);
                x_unlink(cached_dia);
+               x_unlink(cached_dwo);
 
                failed();
        }
@@ -1074,35 +1189,10 @@ to_cache(struct args *args)
        char *tmp_stderr = format("%s.tmp.stderr", cached_obj);
        int tmp_stderr_fd = create_tmp_fd(&tmp_stderr);
 
-       char *tmp_cov;
-       if (generating_coverage) {
-               char *tmp_aux;
-               // GCC has some funny rule about max extension length.
-               if (strlen(get_extension(output_obj)) < 6) {
-                       tmp_aux = remove_extension(output_obj);
-               } else {
-                       tmp_aux = x_strdup(output_obj);
-               }
-               tmp_cov = format("%s.gcno", tmp_aux);
-               free(tmp_aux);
-       } else {
-               tmp_cov = NULL;
-       }
-
-       // GCC (at least 4.8 and 4.9) forms the .dwo file name by removing everything
-       // after (and including) the last "." from the object file name and then
-       // appending ".dwo".
-       char *tmp_dwo = NULL;
-       if (using_split_dwarf) {
-               char *base_name = remove_extension(output_obj);
-               tmp_dwo = format("%s.dwo", base_name);
-               free(base_name);
-       }
-
        args_add(args, "-o");
        args_add(args, output_obj);
 
-       if (output_dia) {
+       if (generating_diagnostics) {
                args_add(args, "--serialize-diagnostics");
                args_add(args, output_dia);
        }
@@ -1130,25 +1220,16 @@ to_cache(struct args *args)
                stats_update(STATS_MISSING);
                tmp_unlink(tmp_stdout);
                tmp_unlink(tmp_stderr);
-               if (tmp_cov) {
-                       tmp_unlink(tmp_cov);
-               }
-               if (tmp_dwo) {
-                       tmp_unlink(tmp_dwo);
-               }
                failed();
        }
-       if (st.st_size != 0) {
+
+       // distcc-pump outputs lines like this:
+       // __________Using # distcc servers in pump mode
+       if (st.st_size != 0 && !compiler_is_pump(args)) {
                cc_log("Compiler produced stdout");
                stats_update(STATS_STDOUT);
                tmp_unlink(tmp_stdout);
                tmp_unlink(tmp_stderr);
-               if (tmp_cov) {
-                       tmp_unlink(tmp_cov);
-               }
-               if (tmp_dwo) {
-                       tmp_unlink(tmp_dwo);
-               }
                failed();
        }
        tmp_unlink(tmp_stdout);
@@ -1206,13 +1287,6 @@ to_cache(struct args *args)
                }
 
                tmp_unlink(tmp_stderr);
-               if (tmp_cov) {
-                       tmp_unlink(tmp_cov);
-               }
-               if (tmp_dwo) {
-                       tmp_unlink(tmp_dwo);
-               }
-
                failed();
        }
 
@@ -1227,38 +1301,12 @@ to_cache(struct args *args)
                failed();
        }
 
-       if (using_split_dwarf) {
-               if (stat(tmp_dwo, &st) != 0) {
-                       cc_log("Compiler didn't produce a split dwarf file");
-                       stats_update(STATS_NOOUTPUT);
-                       failed();
-               }
-               if (st.st_size == 0) {
-                       cc_log("Compiler produced an empty split dwarf file");
-                       stats_update(STATS_EMPTYOUTPUT);
-                       failed();
-               }
-       }
-
        if (x_stat(tmp_stderr, &st) != 0) {
                stats_update(STATS_ERROR);
                failed();
        }
        if (st.st_size > 0) {
-               if (move_uncompressed_file(
-                     tmp_stderr, cached_stderr,
-                     conf->compression ? conf->compression_level : 0) != 0) {
-                       cc_log("Failed to move %s to %s: %s", tmp_stderr, cached_stderr,
-                              strerror(errno));
-                       stats_update(STATS_ERROR);
-                       failed();
-               }
-               cc_log("Stored in cache: %s", cached_stderr);
-               if (!conf->compression
-                   // If the file was compressed, obtain the size again:
-                   || x_stat(cached_stderr, &st) == 0) {
-                       stats_update_size(file_size(&st), 1);
-               }
+               move_file_to_cache_same_fs(tmp_stderr, cached_stderr);
        } else {
                tmp_unlink(tmp_stderr);
                if (conf->recache) {
@@ -1267,45 +1315,24 @@ to_cache(struct args *args)
                }
        }
 
+       copy_file_to_cache(output_obj, cached_obj);
+       if (generating_dependencies) {
+               use_relative_paths_in_depfile(output_dep);
+               copy_file_to_cache(output_dep, cached_dep);
+       }
        if (generating_coverage) {
-               // GCC won't generate notes if there is no code.
-               if (stat(tmp_cov, &st) != 0 && errno == ENOENT) {
-                       FILE *f = fopen(cached_cov, "wb");
-                       cc_log("Creating placeholder: %s", cached_cov);
-                       if (!f) {
-                               cc_log("Failed to create %s: %s", cached_cov, strerror(errno));
-                               stats_update(STATS_ERROR);
-                               failed();
-                       }
-                       fclose(f);
-                       stats_update_size(0, 1);
-               } else {
-                       put_file_in_cache(tmp_cov, cached_cov);
-               }
+               copy_file_to_cache(output_cov, cached_cov);
        }
-
-       if (output_dia) {
-               if (x_stat(output_dia, &st) != 0) {
-                       stats_update(STATS_ERROR);
-                       failed();
-               }
-               if (st.st_size > 0) {
-                       put_file_in_cache(output_dia, cached_dia);
-               }
+       if (generating_stackusage) {
+               copy_file_to_cache(output_su, cached_su);
+       }
+       if (generating_diagnostics) {
+               copy_file_to_cache(output_dia, cached_dia);
        }
-
-       put_file_in_cache(output_obj, cached_obj);
-
        if (using_split_dwarf) {
-               assert(tmp_dwo);
-               assert(cached_dwo);
-               put_file_in_cache(tmp_dwo, cached_dwo);
+               copy_file_to_cache(output_dwo, cached_dwo);
        }
 
-       if (generating_dependencies) {
-               use_relative_paths_in_depfile(output_dep);
-               put_file_in_cache(output_dep, cached_dep);
-       }
        stats_update(STATS_TOCACHE);
 
        // Make sure we have a CACHEDIR.TAG in the cache part of cache_dir. This can
@@ -1336,8 +1363,6 @@ to_cache(struct args *args)
 
        free(tmp_stderr);
        free(tmp_stdout);
-       free(tmp_cov);
-       free(tmp_dwo);
 }
 
 // Find the object file name by running the compiler in preprocessor mode.
@@ -1402,14 +1427,17 @@ get_object_name_from_cpp(struct args *args, struct mdfour *hash)
                hash_string(hash, input_file);
 
                hash_delimiter(hash, "unifycpp");
-               if (unify_hash(hash, path_stdout) != 0) {
+
+               bool debug_unify = getenv("CCACHE_DEBUG_UNIFY");
+               if (unify_hash(hash, path_stdout, debug_unify) != 0) {
                        stats_update(STATS_ERROR);
                        cc_log("Failed to unify %s", path_stdout);
                        failed();
                }
        } else {
                hash_delimiter(hash, "cpp");
-               if (!process_preprocessed_file(hash, path_stdout)) {
+               if (!process_preprocessed_file(hash, path_stdout,
+                                              compiler_is_pump(args))) {
                        stats_update(STATS_ERROR);
                        failed();
                }
@@ -1455,13 +1483,9 @@ update_cached_result_globals(struct file_hash *hash)
        cached_stderr = get_path_in_cache(object_name, ".stderr");
        cached_dep = get_path_in_cache(object_name, ".d");
        cached_cov = get_path_in_cache(object_name, ".gcno");
+       cached_su = get_path_in_cache(object_name, ".su");
        cached_dia = get_path_in_cache(object_name, ".dia");
-
-       if (using_split_dwarf) {
-               cached_dwo = get_path_in_cache(object_name, ".dwo");
-       } else {
-               cached_dwo = NULL;
-       }
+       cached_dwo = get_path_in_cache(object_name, ".dwo");
 
        stats_file = format("%s/%c/stats", conf->cache_dir, object_name[0]);
        free(object_name);
@@ -1493,25 +1517,56 @@ hash_compiler(struct mdfour *hash, struct stat *st, const char *path,
        }
 }
 
-// Note that these compiler checks are unreliable, so nothing should
-// hard-depend on them.
-
-static bool
-compiler_is_clang(struct args *args)
-{
-       char *name = basename(args->argv[0]);
-       bool result = strstr(name, "clang") != NULL;
-       free(name);
-       return result;
-}
-
-static bool
-compiler_is_gcc(struct args *args)
+// Hash the host compiler(s) invoked by nvcc.
+//
+// If ccbin_st and ccbin are set, they refer to a directory or compiler set
+// with -ccbin/--compiler-bindir. If they are NULL, the compilers are looked up
+// in PATH instead.
+static void
+hash_nvcc_host_compiler(struct mdfour *hash, struct stat *ccbin_st,
+                        const char *ccbin)
 {
-       char *name = basename(args->argv[0]);
-       bool result = strstr(name, "gcc") || strstr(name, "g++");
-       free(name);
-       return result;
+       // From <http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html>:
+       //
+       //   "[...] Specify the directory in which the compiler executable resides.
+       //   The host compiler executable name can be also specified to ensure that
+       //   the correct host compiler is selected."
+       //
+       // and
+       //
+       //   "On all platforms, the default host compiler executable (gcc and g++ on
+       //   Linux, clang and clang++ on Mac OS X, and cl.exe on Windows) found in
+       //   the current execution search path will be used".
+
+       if (!ccbin || S_ISDIR(ccbin_st->st_mode)) {
+#if defined(__APPLE__)
+               const char *compilers[] = {"clang", "clang++"};
+#elif defined(_WIN32)
+               const char *compilers[] = {"cl.exe"};
+#else
+               const char *compilers[] = {"gcc", "g++"};
+#endif
+               for (size_t i = 0; i < ARRAY_SIZE(compilers); i++) {
+                       if (ccbin) {
+                               char *path = format("%s/%s", ccbin, compilers[i]);
+                               struct stat st;
+                               if (stat(path, &st) == 0) {
+                                       hash_compiler(hash, &st, path, false);
+                               }
+                               free(path);
+                       } else {
+                               char *path = find_executable(compilers[i], MYNAME);
+                               if (path) {
+                                       struct stat st;
+                                       x_stat(path, &st);
+                                       hash_compiler(hash, &st, ccbin, false);
+                                       free(path);
+                               }
+                       }
+               }
+       } else {
+               hash_compiler(hash, ccbin_st, ccbin, false);
+       }
 }
 
 // Update a hash sum with information common for the direct and preprocessor
@@ -1634,6 +1689,8 @@ calculate_common_hash(struct args *args, struct mdfour *hash)
 static struct file_hash *
 calculate_object_hash(struct args *args, struct mdfour *hash, int direct_mode)
 {
+       bool found_ccbin = false;
+
        if (direct_mode) {
                hash_delimiter(hash, "manifest version");
                hash_int(hash, MANIFEST_VERSION);
@@ -1743,6 +1800,17 @@ calculate_object_hash(struct args *args, struct mdfour *hash, int direct_mode)
                        continue;
                }
 
+               if ((str_eq(args->argv[i], "-ccbin")
+                    || str_eq(args->argv[i], "--compiler-bindir"))
+                    && i + 1 < args->argc
+                    && x_stat(args->argv[i+1], &st) == 0) {
+                       found_ccbin = true;
+                       hash_delimiter(hash, "ccbin");
+                       hash_nvcc_host_compiler(hash, &st, args->argv[i+1]);
+                       i++;
+                       continue;
+               }
+
                // All other arguments are included in the hash.
                hash_delimiter(hash, "arg");
                hash_string(hash, args->argv[i]);
@@ -1753,6 +1821,10 @@ calculate_object_hash(struct args *args, struct mdfour *hash, int direct_mode)
                }
        }
 
+       if (!found_ccbin && str_eq(actual_language, "cuda")) {
+               hash_nvcc_host_compiler(hash, NULL, NULL);
+       }
+
        // For profile generation (-fprofile-arcs, -fprofile-generate):
        // - hash profile directory
        //
@@ -1853,6 +1925,7 @@ calculate_object_hash(struct args *args, struct mdfour *hash, int direct_mode)
                                       arch_args[i]);
                                if (i != arch_args_size - 1) {
                                        free(object_hash);
+                                       object_hash = NULL;
                                }
                                args_pop(args, 1);
                        }
@@ -1886,70 +1959,40 @@ from_cache(enum fromcache_call_mode mode, bool put_object_in_manifest)
                return;
        }
 
+       // Occasionally, e.g. on hard reset, our cache ends up as just filesystem
+       // meta-data with no content. Catch an easy case of this.
        struct stat st;
        if (stat(cached_obj, &st) != 0) {
                cc_log("Object file %s not in cache", cached_obj);
                return;
        }
-
-       // Occasionally, e.g. on hard reset, our cache ends up as just filesystem
-       // meta-data with no content. Catch an easy case of this.
        if (st.st_size == 0) {
                cc_log("Invalid (empty) object file %s in cache", cached_obj);
                x_unlink(cached_obj);
                return;
        }
 
-       if (using_split_dwarf && !generating_dependencies) {
-               assert(output_dwo);
-       }
-       if (output_dwo) {
-               assert(cached_dwo);
-               if (stat(cached_dwo, &st) != 0) {
-                       cc_log("Split dwarf file %s not in cache", cached_dwo);
-                       return;
-               }
-               if (st.st_size == 0) {
-                       cc_log("Invalid (empty) dwo file %s in cache", cached_dwo);
-                       x_unlink(cached_dwo);
-                       x_unlink(cached_obj); // To really invalidate.
-                       return;
-               }
-       }
-
        // (If mode != FROMCACHE_DIRECT_MODE, the dependency file is created by gcc.)
        bool produce_dep_file =
          generating_dependencies && mode == FROMCACHE_DIRECT_MODE;
 
-       // If the dependency file should be in the cache, check that it is.
-       if (produce_dep_file && stat(cached_dep, &st) != 0) {
-               cc_log("Dependency file %s missing in cache", cached_dep);
-               return;
-       }
-
-       // Check if the diagnostic file is there.
-       if (output_dia && stat(cached_dia, &st) != 0) {
-               cc_log("Diagnostic file %s not in cache", cached_dia);
-               return;
-       }
-
-       // Copy object file from cache. Do so also for FissionDwarf file, cached_dwo,
-       // when -gsplit-dwarf is specified.
+       // Get result from cache.
        if (!str_eq(output_obj, "/dev/null")) {
                get_file_from_cache(cached_obj, output_obj);
                if (using_split_dwarf) {
-                       assert(output_dwo);
                        get_file_from_cache(cached_dwo, output_dwo);
                }
        }
        if (produce_dep_file) {
                get_file_from_cache(cached_dep, output_dep);
        }
-       if (generating_coverage && stat(cached_cov, &st) == 0 && st.st_size > 0) {
-               // The compiler won't generate notes if there is no code
+       if (generating_coverage) {
                get_file_from_cache(cached_cov, output_cov);
        }
-       if (output_dia) {
+       if (generating_stackusage) {
+               get_file_from_cache(cached_su, output_su);
+       }
+       if (generating_diagnostics) {
                get_file_from_cache(cached_dia, output_dia);
        }
 
@@ -1963,7 +2006,10 @@ from_cache(enum fromcache_call_mode mode, bool put_object_in_manifest)
        if (generating_coverage) {
                update_mtime(cached_cov);
        }
-       if (output_dia) {
+       if (generating_stackusage) {
+               update_mtime(cached_su);
+       }
+       if (generating_diagnostics) {
                update_mtime(cached_dia);
        }
        if (cached_dwo) {
@@ -2030,9 +2076,8 @@ find_compiler(char **argv)
 bool
 is_precompiled_header(const char *path)
 {
-       return str_eq(get_extension(path), ".gch")
-              || str_eq(get_extension(path), ".pch")
-              || str_eq(get_extension(path), ".pth");
+       const char *ext = get_extension(path);
+       return str_eq(ext, ".gch") || str_eq(ext, ".pch") || str_eq(ext, ".pth");
 }
 
 static bool
@@ -2104,7 +2149,6 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
        bool found_fpch_preprocess = false;
        const char *explicit_language = NULL; // As specified with -x.
        const char *file_language;            // As deduced from file extension.
-       const char *actual_language;          // Language to actually use.
        const char *input_charset = NULL;
        // Is the dependency makefile name overridden with -MF?
        bool dependency_filename_specified = false;
@@ -2129,6 +2173,9 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
 
        bool found_color_diagnostics = false;
 
+       bool found_directives_only = false;
+       bool found_rewrite_includes = false;
+
        int argc = expanded_args->argc;
        char **argv = expanded_args->argv;
        args_add(stripped_args, argv[0]);
@@ -2177,7 +2224,8 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                }
 
                // Handle cuda "-optf" and "--options-file" argument.
-               if (str_eq(argv[i], "-optf") || str_eq(argv[i], "--options-file")) {
+               if ((str_eq(argv[i], "-optf") || str_eq(argv[i], "--options-file"))
+                   && compiler_is_nvcc(args)) {
                        if (i == argc - 1) {
                                cc_log("Expected argument after %s", argv[i]);
                                stats_update(STATS_ARGS);
@@ -2312,8 +2360,8 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                        continue;
                }
 
-               // Alternate form of -o with no space.
-               if (str_startswith(argv[i], "-o")) {
+               // Alternate form of -o with no space. Nvcc does not support this.
+               if (str_startswith(argv[i], "-o") && !compiler_is_nvcc(args)) {
                        output_obj = make_relative_path(x_strdup(&argv[i][2]));
                        continue;
                }
@@ -2326,8 +2374,8 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                }
                if (str_startswith(argv[i], "-fdebug-prefix-map=")) {
                        debug_prefix_maps = x_realloc(
-                               debug_prefix_maps,
-                               (debug_prefix_maps_len + 1) * sizeof(char *));
+                         debug_prefix_maps,
+                         (debug_prefix_maps_len + 1) * sizeof(char *));
                        debug_prefix_maps[debug_prefix_maps_len++] = x_strdup(argv[i] + 19);
                        args_add(stripped_args, argv[i]);
                        continue;
@@ -2426,6 +2474,11 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                        args_add(stripped_args, argv[i]);
                        continue;
                }
+               if (str_eq(argv[i], "-fstack-usage")) {
+                       generating_stackusage = true;
+                       args_add(stripped_args, argv[i]);
+                       continue;
+               }
                if (str_eq(argv[i], "--coverage") // = -fprofile-arcs -ftest-coverage
                    || str_eq(argv[i], "-coverage")) { // Undocumented but still works.
                        profile_arcs = true;
@@ -2446,6 +2499,21 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                        free(option);
                        continue;
                }
+               // Alternate form of specifying sysroot without =
+               if (str_eq(argv[i], "--sysroot")) {
+                       if (i == argc-1) {
+                               cc_log("Missing argument to %s", argv[i]);
+                               stats_update(STATS_ARGS);
+                               result = false;
+                               goto out;
+                       }
+                       args_add(stripped_args, argv[i]);
+                       char *relpath = make_relative_path(x_strdup(argv[i+1]));
+                       args_add(stripped_args, relpath);
+                       i++;
+                       free(relpath);
+                       continue;
+               }
                if (str_startswith(argv[i], "-Wp,")) {
                        if (str_eq(argv[i], "-Wp,-P")
                            || strstr(argv[i], ",-P,")
@@ -2517,6 +2585,7 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                                result = false;
                                goto out;
                        }
+                       generating_diagnostics = true;
                        output_dia = make_relative_path(x_strdup(argv[i+1]));
                        i++;
                        continue;
@@ -2597,6 +2666,17 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                        continue;
                }
 
+               // GCC
+               if (str_eq(argv[i], "-fdirectives-only")) {
+                       found_directives_only = true;
+                       continue;
+               }
+               // Clang
+               if (str_eq(argv[i], "-frewrite-includes")) {
+                       found_rewrite_includes = true;
+                       continue;
+               }
+
                // Options taking an argument that we may want to rewrite to relative paths
                // to get better hit rate. A secondary effect is that paths in the standard
                // error output produced by the compiler will be normalized.
@@ -2767,7 +2847,7 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                        result = false;
                        goto out;
                }
-               actual_language = explicit_language;
+               actual_language = x_strdup(explicit_language);
        } else {
                actual_language = file_language;
        }
@@ -2808,6 +2888,11 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                goto out;
        }
 
+       if (!conf->run_second_cpp && str_eq(actual_language, "cuda")) {
+               cc_log("Using CUDA compiler; not compiling preprocessed code");
+               conf->run_second_cpp = true;
+       }
+
        direct_i_file = language_is_preprocessed(actual_language);
 
        if (output_is_precompiled_header && !conf->run_second_cpp) {
@@ -2919,7 +3004,8 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                        output_dep = make_relative_path(x_strdup(default_depfile_name));
                }
 
-               if (!dependency_target_specified) {
+               if (!dependency_target_specified
+                   && !str_eq(get_extension(output_dep), ".o")) {
                        args_add(dep_args, "-MQ");
                        args_add(dep_args, output_obj);
                }
@@ -2928,12 +3014,33 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                char *base_name = remove_extension(output_obj);
                char *default_covfile_name = format("%s.gcno", base_name);
                free(base_name);
-               output_cov = make_relative_path(x_strdup(default_covfile_name));
+               output_cov = make_relative_path(default_covfile_name);
+       }
+       if (generating_stackusage) {
+               char *base_name = remove_extension(output_obj);
+               char *default_sufile_name = format("%s.su", base_name);
+               free(base_name);
+               output_su = make_relative_path(default_sufile_name);
        }
 
        *compiler_args = args_copy(stripped_args);
        if (conf->run_second_cpp) {
                args_extend(*compiler_args, cpp_args);
+       } else if (found_directives_only || found_rewrite_includes) {
+               // Need to pass the macros and any other preprocessor directives again.
+               args_extend(*compiler_args, cpp_args);
+               if (found_directives_only) {
+                       args_add(cpp_args, "-fdirectives-only");
+                       // The preprocessed source code still needs some more preprocessing.
+                       args_add(*compiler_args, "-fpreprocessed");
+                       args_add(*compiler_args, "-fdirectives-only");
+               }
+               if (found_rewrite_includes) {
+                       args_add(cpp_args, "-frewrite-includes");
+                       // The preprocessed source code still needs some more preprocessing.
+                       args_add(*compiler_args, "-x");
+                       args_add(*compiler_args, actual_language);
+               }
        } else if (explicit_language) {
                // Workaround for a bug in Apple's patched distcc -- it doesn't properly
                // reset the language specified with -x, so if -x is given, we have to
@@ -3015,17 +3122,17 @@ initialize(void)
        conf = conf_create();
 
        char *errmsg;
-       struct stat st;
        char *p = getenv("CCACHE_CONFIGPATH");
        if (p) {
                primary_config_path = x_strdup(p);
        } else {
                secondary_config_path = format("%s/ccache.conf", TO_STRING(SYSCONFDIR));
                if (!conf_read(conf, secondary_config_path, &errmsg)) {
-                       if (stat(secondary_config_path, &st) == 0) {
+                       if (access(secondary_config_path, R_OK) == 0) {
+                               // We could read the file but it contained errors.
                                fatal("%s", errmsg);
                        }
-                       // Missing config file in SYSCONFDIR is OK.
+                       // A missing config file in SYSCONFDIR is OK.
                        free(errmsg);
                }
 
@@ -3045,20 +3152,19 @@ initialize(void)
 
        bool should_create_initial_config = false;
        if (!conf_read(conf, primary_config_path, &errmsg)) {
-               if (stat(primary_config_path, &st) == 0) {
+               if (access(primary_config_path, R_OK) == 0) {
+                       // We could read the file but it contained errors.
                        fatal("%s", errmsg);
                }
-               should_create_initial_config = true;
+               if (!conf->disable) {
+                       should_create_initial_config = true;
+               }
        }
 
        if (!conf_update_from_environment(conf, &errmsg)) {
                fatal("%s", errmsg);
        }
 
-       if (conf->disable) {
-               should_create_initial_config = false;
-       }
-
        if (should_create_initial_config) {
                create_initial_config_file(conf, primary_config_path);
        }
@@ -3094,17 +3200,19 @@ cc_reset(void)
        args_free(orig_args); orig_args = NULL;
        free(input_file); input_file = NULL;
        free(output_obj); output_obj = NULL;
-       free(output_dwo); output_dwo = NULL;
        free(output_dep); output_dep = NULL;
        free(output_cov); output_cov = NULL;
+       free(output_su); output_su = NULL;
        free(output_dia); output_dia = NULL;
+       free(output_dwo); output_dwo = NULL;
        free(cached_obj_hash); cached_obj_hash = NULL;
-       free(cached_obj); cached_obj = NULL;
-       free(cached_dwo); cached_dwo = NULL;
        free(cached_stderr); cached_stderr = NULL;
+       free(cached_obj); cached_obj = NULL;
        free(cached_dep); cached_dep = NULL;
        free(cached_cov); cached_cov = NULL;
+       free(cached_su); cached_su = NULL;
        free(cached_dia); cached_dia = NULL;
+       free(cached_dwo); cached_dwo = NULL;
        free(manifest_path); manifest_path = NULL;
        time_of_compilation = 0;
        for (size_t i = 0; i < ignore_headers_len; i++) {
@@ -3120,6 +3228,7 @@ cc_reset(void)
        generating_debuginfo = false;
        generating_dependencies = false;
        generating_coverage = false;
+       generating_stackusage = false;
        profile_arcs = false;
        free(profile_dir); profile_dir = NULL;
        i_tmpfile = NULL;
@@ -3135,14 +3244,13 @@ cc_reset(void)
 // Make a copy of stderr that will not be cached, so things like distcc can
 // send networking errors to it.
 static void
-setup_uncached_err(void)
+set_up_uncached_err(void)
 {
-       int uncached_fd = dup(2);
+       int uncached_fd = dup(2); // The file descriptor is intentionally leaked.
        if (uncached_fd == -1) {
                cc_log("dup(2) failed: %s", strerror(errno));
                failed();
        }
-       // Leak the file descriptor.
 
        // Leak a pointer to the environment.
        char *buf = format("UNCACHED_ERR_FD=%d", uncached_fd);
@@ -3185,17 +3293,12 @@ ccache(int argc, char *argv[])
                failed();
        }
 
-       setup_uncached_err();
+       set_up_uncached_err();
 
        cc_log_argv("Command line: ", argv);
        cc_log("Hostname: %s", get_hostname());
        cc_log("Working directory: %s", get_current_working_dir());
 
-       if (conf->unify) {
-               cc_log("Direct mode disabled because unify mode is enabled");
-               conf->direct_mode = false;
-       }
-
        conf->limit_multiple = MIN(MAX(conf->limit_multiple, 0.0), 1.0);
 
        // Arguments (except -E) to send to the preprocessor.
@@ -3213,18 +3316,12 @@ ccache(int argc, char *argv[])
        if (generating_coverage) {
                cc_log("Coverage file: %s", output_cov);
        }
-       if (output_dia) {
-               cc_log("Diagnostic file: %s", output_dia);
+       if (generating_stackusage) {
+               cc_log("Stack usage file: %s", output_su);
        }
-
-       if (using_split_dwarf) {
-               if (!generating_dependencies) {
-                       assert(output_dwo);
-               }
-       } else {
-               assert(!output_dwo);
+       if (generating_diagnostics) {
+               cc_log("Diagnostics file: %s", output_dia);
        }
-
        if (output_dwo) {
                cc_log("Split dwarf file: %s", output_dwo);
        }
similarity index 96%
rename from ccache.h
rename to src/ccache.h
index 229f8b4..dec11fa 100644 (file)
--- a/ccache.h
@@ -53,6 +53,7 @@ enum stats {
        STATS_PREPROCESSING = 28,
        STATS_NUMCLEANUPS = 29,
        STATS_UNSUPPORTED_DIRECTIVE = 30,
+       STATS_ZEROTIMESTAMP = 31,
 
        STATS_END
 };
@@ -75,6 +76,7 @@ enum stats {
 #define str_endswith(s, suffix) \
        (strlen(s) >= strlen(suffix) \
         && str_eq((s) + strlen(s) - strlen(suffix), (suffix)))
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
 
 // Buffer size for I/O operations. Should be a multiple of 4 KiB.
 #define READ_BUFFER_SIZE 65536
@@ -125,6 +127,7 @@ void cc_log(const char *format, ...) ATTR_FORMAT(printf, 1, 2);
 void cc_bulklog(const char *format, ...) ATTR_FORMAT(printf, 1, 2);
 void cc_log_argv(const char *prefix, char **argv);
 void fatal(const char *format, ...) ATTR_FORMAT(printf, 1, 2) ATTR_NORETURN;
+void warn(const char *format, ...) ATTR_FORMAT(printf, 1, 2);
 
 void copy_fd(int fd_in, int fd_out);
 int copy_file(const char *src, const char *dest, int compress_level);
@@ -194,18 +197,19 @@ void stats_flush(void);
 unsigned stats_get_pending(enum stats stat);
 void stats_zero(void);
 void stats_summary(struct conf *conf);
-void stats_update_size(uint64_t size, unsigned files);
+void stats_update_size(int64_t size, int files);
 void stats_get_obsolete_limits(const char *dir, unsigned *maxfiles,
                                uint64_t *maxsize);
 void stats_set_sizes(const char *dir, unsigned num_files, uint64_t total_size);
 void stats_add_cleanup(const char *dir, unsigned count);
+void stats_timestamp(time_t time, struct counters *counters);
 void stats_read(const char *path, struct counters *counters);
 void stats_write(const char *path, struct counters *counters);
 
 // ----------------------------------------------------------------------------
 // unify.c
 
-int unify_hash(struct mdfour *hash, const char *fname);
+int unify_hash(struct mdfour *hash, const char *fname, bool print);
 
 // ----------------------------------------------------------------------------
 // exitfn.c
similarity index 100%
rename from cleanup.c
rename to src/cleanup.c
similarity index 90%
rename from compopt.c
rename to src/compopt.c
index e5bee23..aab9fe5 100644 (file)
--- a/compopt.c
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2016 Joel Rosdahl
+// Copyright (C) 2010-2018 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -30,6 +30,9 @@ struct compopt {
 };
 
 static const struct compopt compopts[] = {
+       {"--compiler-bindir", AFFECTS_CPP | TAKES_ARG}, // nvcc
+       {"--libdevice-directory", AFFECTS_CPP | TAKES_ARG}, // nvcc
+       {"--output-directory", AFFECTS_CPP | TAKES_ARG}, // nvcc
        {"--param",         TAKES_ARG},
        {"--save-temps",    TOO_HARD},
        {"--serialize-diagnostics", TAKES_ARG | TAKES_PATH},
@@ -56,11 +59,11 @@ static const struct compopt compopts[] = {
        {"-arch",           TAKES_ARG},
        {"-aux-info",       TAKES_ARG},
        {"-b",              TAKES_ARG},
+       {"-ccbin",          AFFECTS_CPP | TAKES_ARG}, // nvcc
        {"-fmodules",       TOO_HARD},
        {"-fno-working-directory", AFFECTS_CPP},
        {"-fplugin=libcc1plugin", TOO_HARD}, // interaction with GDB
        {"-frepo",          TOO_HARD},
-       {"-fstack-usage",   TOO_HARD},
        {"-fworking-directory", AFFECTS_CPP},
        {"-idirafter",      AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
        {"-iframework",     AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
@@ -76,8 +79,10 @@ static const struct compopt compopts[] = {
        {"-iwithprefix",    AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
        {"-iwithprefixbefore",
         AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
+       {"-ldir",           AFFECTS_CPP | TAKES_ARG}, // nvcc
        {"-nostdinc",       AFFECTS_CPP},
        {"-nostdinc++",     AFFECTS_CPP},
+       {"-odir",           AFFECTS_CPP | TAKES_ARG}, // nvcc
        {"-remap",          AFFECTS_CPP},
        {"-save-temps",     TOO_HARD},
        {"-stdlib=",        AFFECTS_CPP | TAKES_CONCAT_ARG},
@@ -108,8 +113,8 @@ find(const char *option)
        struct compopt key;
        key.name = option;
        return bsearch(
-                &key, compopts, sizeof(compopts) / sizeof(compopts[0]),
-                sizeof(compopts[0]), compare_compopts);
+               &key, compopts, ARRAY_SIZE(compopts), sizeof(compopts[0]),
+               compare_compopts);
 }
 
 static const struct compopt *
@@ -118,8 +123,8 @@ find_prefix(const char *option)
        struct compopt key;
        key.name = option;
        return bsearch(
-                &key, compopts, sizeof(compopts) / sizeof(compopts[0]),
-                sizeof(compopts[0]), compare_prefix_compopts);
+               &key, compopts, ARRAY_SIZE(compopts), sizeof(compopts[0]),
+               compare_prefix_compopts);
 }
 
 // Runs fn on the first two characters of option.
@@ -136,7 +141,7 @@ compopt_short(bool (*fn)(const char *), const char *option)
 bool
 compopt_verify_sortedness(void)
 {
-       for (size_t i = 1; i < sizeof(compopts)/sizeof(compopts[0]); i++) {
+       for (size_t i = 1; i < ARRAY_SIZE(compopts); i++) {
                if (strcmp(compopts[i-1].name, compopts[i].name) >= 0) {
                        fprintf(stderr,
                                "compopt_verify_sortedness: %s >= %s\n",
similarity index 100%
rename from compopt.h
rename to src/compopt.h
similarity index 96%
rename from conf.c
rename to src/conf.c
index cfa2874..20e744a 100644 (file)
--- a/conf.c
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2016 Joel Rosdahl
+// Copyright (C) 2011-2018 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -241,8 +241,18 @@ handle_conf_setting(struct conf *conf, const char *key, const char *value,
        }
 
        if (from_env_variable && item->parser == parse_bool) {
-               // Special rule for boolean settings from the environment: any value means
-               // true.
+               // Special rule for boolean settings from the environment: "0", "false",
+               // "disable" and "no" (case insensitive) are invalid, and all other values
+               // mean true.
+               //
+               // Previously any value meant true, but this was surprising to users, who
+               // might do something like CCACHE_DISABLE=0 and expect ccache to be
+               // enabled.
+               if (str_eq(value, "0") || strcasecmp(value, "false") == 0
+                   || strcasecmp(value, "disable") == 0 || strcasecmp(value, "no") == 0) {
+                       fatal("invalid boolean environment variable value \"%s\"", value);
+               }
+
                bool *value = (bool *)((char *)conf + item->offset);
                *value = !negate_boolean;
                goto out;
similarity index 100%
rename from conf.h
rename to src/conf.h
similarity index 100%
rename from confitems.gperf
rename to src/confitems.gperf
similarity index 86%
rename from confitems_lookup.c
rename to src/confitems_lookup.c
index 7482557..63f0da0 100644 (file)
@@ -1,5 +1,5 @@
 /* ANSI-C code produced by gperf version 3.0.4 */
-/* Command-line: gperf confitems.gperf  */
+/* Command-line: gperf src/confitems.gperf  */
 /* Computed positions: -k'1-2' */
 
 #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
@@ -29,7 +29,7 @@
 #error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
 #endif
 
-#line 8 "confitems.gperf"
+#line 8 "src/confitems.gperf"
 struct conf_item;
 /* maximum key range = 46, duplicates = 0 */
 
@@ -98,79 +98,79 @@ confitems_get (register const char *str, register unsigned int len)
     {
       {"",0,NULL,0,NULL}, {"",0,NULL,0,NULL},
       {"",0,NULL,0,NULL}, {"",0,NULL,0,NULL},
-#line 29 "confitems.gperf"
+#line 29 "src/confitems.gperf"
       {"path",                19, ITEM(path, env_string)},
       {"",0,NULL,0,NULL}, {"",0,NULL,0,NULL},
       {"",0,NULL,0,NULL},
-#line 13 "confitems.gperf"
+#line 13 "src/confitems.gperf"
       {"compiler",             3, ITEM(compiler, string)},
-#line 11 "confitems.gperf"
+#line 11 "src/confitems.gperf"
       {"cache_dir",            1, ITEM(cache_dir, env_string)},
       {"",0,NULL,0,NULL},
-#line 15 "confitems.gperf"
+#line 15 "src/confitems.gperf"
       {"compression",          5, ITEM(compression, bool)},
       {"",0,NULL,0,NULL},
-#line 17 "confitems.gperf"
+#line 17 "src/confitems.gperf"
       {"cpp_extension",        7, ITEM(cpp_extension, string)},
-#line 14 "confitems.gperf"
+#line 14 "src/confitems.gperf"
       {"compiler_check",       4, ITEM(compiler_check, string)},
-#line 37 "confitems.gperf"
+#line 37 "src/confitems.gperf"
       {"stats",               27, ITEM(stats, bool)},
-#line 12 "confitems.gperf"
+#line 12 "src/confitems.gperf"
       {"cache_dir_levels",     2, ITEM_V(cache_dir_levels, unsigned, dir_levels)},
-#line 16 "confitems.gperf"
+#line 16 "src/confitems.gperf"
       {"compression_level",    6, ITEM(compression_level, unsigned)},
-#line 26 "confitems.gperf"
+#line 26 "src/confitems.gperf"
       {"log_file",            16, ITEM(log_file, env_string)},
-#line 30 "confitems.gperf"
+#line 30 "src/confitems.gperf"
       {"prefix_command",      20, ITEM(prefix_command, env_string)},
-#line 36 "confitems.gperf"
+#line 36 "src/confitems.gperf"
       {"sloppiness",          26, ITEM(sloppiness, sloppiness)},
-#line 10 "confitems.gperf"
+#line 10 "src/confitems.gperf"
       {"base_dir",             0, ITEM_V(base_dir, env_string, absolute_path)},
-#line 34 "confitems.gperf"
+#line 34 "src/confitems.gperf"
       {"recache",             24, ITEM(recache, bool)},
-#line 31 "confitems.gperf"
+#line 31 "src/confitems.gperf"
       {"prefix_command_cpp",  21, ITEM(prefix_command_cpp, env_string)},
-#line 32 "confitems.gperf"
+#line 32 "src/confitems.gperf"
       {"read_only",           22, ITEM(read_only, bool)},
-#line 40 "confitems.gperf"
+#line 40 "src/confitems.gperf"
       {"unify",               30, ITEM(unify, bool)},
       {"",0,NULL,0,NULL},
-#line 24 "confitems.gperf"
+#line 24 "src/confitems.gperf"
       {"keep_comments_cpp",   14, ITEM(keep_comments_cpp, bool)},
-#line 28 "confitems.gperf"
+#line 28 "src/confitems.gperf"
       {"max_size",            18, ITEM(max_size, size)},
-#line 27 "confitems.gperf"
+#line 27 "src/confitems.gperf"
       {"max_files",           17, ITEM(max_files, unsigned)},
       {"",0,NULL,0,NULL},
-#line 33 "confitems.gperf"
+#line 33 "src/confitems.gperf"
       {"read_only_direct",    23, ITEM(read_only_direct, bool)},
-#line 19 "confitems.gperf"
+#line 19 "src/confitems.gperf"
       {"disable",              9, ITEM(disable, bool)},
-#line 38 "confitems.gperf"
+#line 38 "src/confitems.gperf"
       {"temporary_dir",       28, ITEM(temporary_dir, env_string)},
-#line 35 "confitems.gperf"
+#line 35 "src/confitems.gperf"
       {"run_second_cpp",      25, ITEM(run_second_cpp, bool)},
       {"",0,NULL,0,NULL},
-#line 18 "confitems.gperf"
+#line 18 "src/confitems.gperf"
       {"direct_mode",          8, ITEM(direct_mode, bool)},
       {"",0,NULL,0,NULL},
-#line 22 "confitems.gperf"
+#line 22 "src/confitems.gperf"
       {"hash_dir",            12, ITEM(hash_dir, bool)},
-#line 21 "confitems.gperf"
+#line 21 "src/confitems.gperf"
       {"hard_link",           11, ITEM(hard_link, bool)},
-#line 39 "confitems.gperf"
+#line 39 "src/confitems.gperf"
       {"umask",               29, ITEM(umask, umask)},
       {"",0,NULL,0,NULL}, {"",0,NULL,0,NULL},
       {"",0,NULL,0,NULL},
-#line 25 "confitems.gperf"
+#line 25 "src/confitems.gperf"
       {"limit_multiple",      15, ITEM(limit_multiple, float)},
       {"",0,NULL,0,NULL},
-#line 23 "confitems.gperf"
+#line 23 "src/confitems.gperf"
       {"ignore_headers_in_manifest", 13, ITEM(ignore_headers_in_manifest, env_string)},
       {"",0,NULL,0,NULL}, {"",0,NULL,0,NULL},
-#line 20 "confitems.gperf"
+#line 20 "src/confitems.gperf"
       {"extra_files_to_hash", 10, ITEM(extra_files_to_hash, env_string)}
     };
 
similarity index 100%
rename from counters.c
rename to src/counters.c
similarity index 100%
rename from counters.h
rename to src/counters.h
similarity index 82%
rename from envtoconfitems_lookup.c
rename to src/envtoconfitems_lookup.c
index 1265bd6..690ed94 100644 (file)
@@ -1,5 +1,5 @@
 /* ANSI-C code produced by gperf version 3.0.4 */
-/* Command-line: gperf envtoconfitems.gperf  */
+/* Command-line: gperf src/envtoconfitems.gperf  */
 /* Computed positions: -k'1,5' */
 
 #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
@@ -29,7 +29,7 @@
 #error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
 #endif
 
-#line 9 "envtoconfitems.gperf"
+#line 9 "src/envtoconfitems.gperf"
 struct env_to_conf_item;
 /* maximum key range = 42, duplicates = 0 */
 
@@ -111,77 +111,77 @@ envtoconfitems_get (register const char *str, register unsigned int len)
   static const struct env_to_conf_item wordlist[] =
     {
       {"",""}, {"",""},
-#line 12 "envtoconfitems.gperf"
+#line 12 "src/envtoconfitems.gperf"
       {"CC", "compiler"},
-#line 18 "envtoconfitems.gperf"
+#line 18 "src/envtoconfitems.gperf"
       {"DIR", "cache_dir"},
-#line 16 "envtoconfitems.gperf"
+#line 16 "src/envtoconfitems.gperf"
       {"CPP2", "run_second_cpp"},
       {"",""},
-#line 19 "envtoconfitems.gperf"
+#line 19 "src/envtoconfitems.gperf"
       {"DIRECT", "direct_mode"},
-#line 20 "envtoconfitems.gperf"
+#line 20 "src/envtoconfitems.gperf"
       {"DISABLE", "disable"},
-#line 17 "envtoconfitems.gperf"
+#line 17 "src/envtoconfitems.gperf"
       {"COMMENTS", "keep_comments_cpp"},
-#line 31 "envtoconfitems.gperf"
+#line 31 "src/envtoconfitems.gperf"
       {"PATH", "path"},
-#line 41 "envtoconfitems.gperf"
+#line 41 "src/envtoconfitems.gperf"
       {"UNIFY", "unify"},
-#line 32 "envtoconfitems.gperf"
+#line 32 "src/envtoconfitems.gperf"
       {"PREFIX", "prefix_command"},
-#line 36 "envtoconfitems.gperf"
+#line 36 "src/envtoconfitems.gperf"
       {"RECACHE", "recache"},
-#line 13 "envtoconfitems.gperf"
+#line 13 "src/envtoconfitems.gperf"
       {"COMPILERCHECK", "compiler_check"},
       {"",""},
-#line 33 "envtoconfitems.gperf"
+#line 33 "src/envtoconfitems.gperf"
       {"PREFIX_CPP", "prefix_command_cpp"},
-#line 30 "envtoconfitems.gperf"
+#line 30 "src/envtoconfitems.gperf"
       {"NLEVELS", "cache_dir_levels"},
-#line 27 "envtoconfitems.gperf"
+#line 27 "src/envtoconfitems.gperf"
       {"LOGFILE", "log_file"},
-#line 34 "envtoconfitems.gperf"
+#line 34 "src/envtoconfitems.gperf"
       {"READONLY", "read_only"},
-#line 21 "envtoconfitems.gperf"
+#line 21 "src/envtoconfitems.gperf"
       {"EXTENSION", "cpp_extension"},
-#line 40 "envtoconfitems.gperf"
+#line 40 "src/envtoconfitems.gperf"
       {"UMASK", "umask"},
       {"",""},
-#line 24 "envtoconfitems.gperf"
+#line 24 "src/envtoconfitems.gperf"
       {"HASHDIR", "hash_dir"},
-#line 14 "envtoconfitems.gperf"
+#line 14 "src/envtoconfitems.gperf"
       {"COMPRESS", "compression"},
       {"",""},
-#line 35 "envtoconfitems.gperf"
+#line 35 "src/envtoconfitems.gperf"
       {"READONLY_DIRECT", "read_only_direct"},
       {"",""},
-#line 39 "envtoconfitems.gperf"
+#line 39 "src/envtoconfitems.gperf"
       {"TEMPDIR", "temporary_dir"},
-#line 15 "envtoconfitems.gperf"
+#line 15 "src/envtoconfitems.gperf"
       {"COMPRESSLEVEL", "compression_level"},
-#line 26 "envtoconfitems.gperf"
+#line 26 "src/envtoconfitems.gperf"
       {"LIMIT_MULTIPLE", "limit_multiple"},
-#line 38 "envtoconfitems.gperf"
+#line 38 "src/envtoconfitems.gperf"
       {"STATS", "stats"},
       {"",""},
-#line 29 "envtoconfitems.gperf"
+#line 29 "src/envtoconfitems.gperf"
       {"MAXSIZE", "max_size"},
-#line 28 "envtoconfitems.gperf"
+#line 28 "src/envtoconfitems.gperf"
       {"MAXFILES", "max_files"},
       {"",""},
-#line 37 "envtoconfitems.gperf"
+#line 37 "src/envtoconfitems.gperf"
       {"SLOPPINESS", "sloppiness"},
       {"",""},
-#line 11 "envtoconfitems.gperf"
+#line 11 "src/envtoconfitems.gperf"
       {"BASEDIR", "base_dir"},
-#line 23 "envtoconfitems.gperf"
+#line 23 "src/envtoconfitems.gperf"
       {"HARDLINK", "hard_link"},
       {"",""},
-#line 22 "envtoconfitems.gperf"
+#line 22 "src/envtoconfitems.gperf"
       {"EXTRAFILES", "extra_files_to_hash"},
       {"",""}, {"",""},
-#line 25 "envtoconfitems.gperf"
+#line 25 "src/envtoconfitems.gperf"
       {"IGNOREHEADERS", "ignore_headers_in_manifest"}
     };
 
similarity index 98%
rename from execute.c
rename to src/execute.c
index 566ef9e..6579b30 100644 (file)
--- a/execute.c
@@ -1,5 +1,5 @@
 // Copyright (C) 2002 Andrew Tridgell
-// Copyright (C) 2011-2016 Joel Rosdahl
+// Copyright (C) 2011-2018 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -79,7 +79,6 @@ win32argvtos(char *prefix, char **argv)
                }
                *ptr++ = '"';
                *ptr++ = ' ';
-               // cppcheck-suppress unreadVariable
        } while ((arg = argv[i++]));
        ptr[-1] = '\0';
 
@@ -190,7 +189,8 @@ win32execute(char *path, char **argv, int doreturn,
                                      * sizeof(TCHAR));
                _snprintf((LPTSTR) lpDisplayBuf,
                          LocalSize(lpDisplayBuf) / sizeof(TCHAR),
-                         TEXT("%s failed with error %d: %s"), __FILE__, dw, lpMsgBuf);
+                         TEXT("%s failed with error %lu: %s"), __FILE__, dw,
+                         (const char *)lpMsgBuf);
 
                cc_log("can't execute %s; OS returned error: %s",
                       full_path_win_ext, (char *)lpDisplayBuf);
similarity index 100%
rename from exitfn.c
rename to src/exitfn.c
similarity index 100%
rename from getopt_long.c
rename to src/getopt_long.c
similarity index 100%
rename from getopt_long.h
rename to src/getopt_long.h
similarity index 100%
rename from hash.c
rename to src/hash.c
similarity index 100%
rename from hashtable.c
rename to src/hashtable.c
similarity index 100%
rename from hashtable.h
rename to src/hashtable.h
similarity index 100%
rename from hashtable_itr.c
rename to src/hashtable_itr.c
similarity index 100%
rename from hashtable_itr.h
rename to src/hashtable_itr.h
similarity index 100%
rename from hashtable_private.h
rename to src/hashtable_private.h
similarity index 100%
rename from hashutil.c
rename to src/hashutil.c
similarity index 100%
rename from hashutil.h
rename to src/hashutil.h
similarity index 100%
rename from language.c
rename to src/language.c
similarity index 100%
rename from language.h
rename to src/language.h
similarity index 98%
rename from lockfile.c
rename to src/lockfile.c
index ce3dcf4..9d1a49d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2016 Joel Rosdahl
+// Copyright (C) 2010-2018 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -119,7 +119,6 @@ lockfile_acquire(const char *path, unsigned staleness_limit)
                }
                free(content);
                content = x_readlink(lockfile);
-               // cppcheck-suppress nullPointer - false positive
                if (!content) {
                        if (errno == ENOENT) {
                                // The symlink was removed after the symlink() call above, so retry
similarity index 100%
rename from macroskip.h
rename to src/macroskip.h
similarity index 100%
rename from main.c
rename to src/main.c
similarity index 100%
rename from manifest.c
rename to src/manifest.c
similarity index 100%
rename from manifest.h
rename to src/manifest.h
similarity index 100%
rename from mdfour.c
rename to src/mdfour.c
similarity index 100%
rename from mdfour.h
rename to src/mdfour.h
similarity index 100%
rename from snprintf.c
rename to src/snprintf.c
similarity index 92%
rename from stats.c
rename to src/stats.c
index 0ed203d..5ac56fd 100644 (file)
--- a/stats.c
@@ -231,6 +231,12 @@ static struct {
                FLAG_NOZERO|FLAG_NEVER
        },
        {
+               STATS_ZEROTIMESTAMP,
+               "stats last zeroed at",
+               NULL,
+               FLAG_NEVER
+       },
+       {
                STATS_NONE,
                NULL,
                NULL,
@@ -277,6 +283,13 @@ parse_stats(struct counters *counters, const char *buf)
 void
 stats_write(const char *path, struct counters *counters)
 {
+       struct stat st;
+       if (stat(path, &st) != 0 && errno == ENOENT) {
+               // New stats, update zero timestamp.
+               time_t now;
+               time(&now);
+               stats_timestamp(now, counters);
+       }
        char *tmp_file = format("%s.tmp", path);
        FILE *f = create_tmp_file(&tmp_file, "wb");
        for (size_t i = 0; i < counters->size; i++) {
@@ -300,7 +313,7 @@ init_counter_updates(void)
 // Record that a number of bytes and files have been added to the cache. Size
 // is in bytes.
 void
-stats_update_size(uint64_t size, unsigned files)
+stats_update_size(int64_t size, int files)
 {
        init_counter_updates();
        counter_updates->data[STATS_NUMFILES] += files;
@@ -318,6 +331,13 @@ stats_read(const char *sfile, struct counters *counters)
        free(data);
 }
 
+// Set the timestamp when the counters were last zeroed out.
+void
+stats_timestamp(time_t time, struct counters *counters)
+{
+       counters->data[STATS_ZEROTIMESTAMP] = (unsigned) time;
+}
+
 // Write counter updates in counter_updates to disk.
 void
 stats_flush(void)
@@ -424,6 +444,7 @@ void
 stats_summary(struct conf *conf)
 {
        struct counters *counters = counters_init(STATS_END);
+       time_t oldest = 0;
 
        assert(conf);
 
@@ -437,7 +458,12 @@ stats_summary(struct conf *conf)
                        fname = format("%s/%1x/stats", conf->cache_dir, dir);
                }
 
+               counters->data[STATS_ZEROTIMESTAMP] = 0; // Don't add
                stats_read(fname, counters);
+               time_t current = (time_t) counters->data[STATS_ZEROTIMESTAMP];
+               if (current != 0 && (oldest == 0 || current < oldest)) {
+                       oldest = current;
+               }
                free(fname);
        }
 
@@ -446,6 +472,12 @@ stats_summary(struct conf *conf)
               primary_config_path ? primary_config_path : "");
        printf("secondary config      (readonly)    %s\n",
               secondary_config_path ? secondary_config_path : "");
+       if (oldest) {
+               struct tm *tm = localtime(&oldest);
+               char timestamp[100];
+               strftime(timestamp, sizeof(timestamp), "%c", tm);
+               printf("stats zero time                     %s\n", timestamp);
+       }
 
        // ...and display them.
        for (int i = 0; stats_info[i].message; i++) {
@@ -515,6 +547,7 @@ stats_zero(void)
                                        counters->data[stats_info[i].stat] = 0;
                                }
                        }
+                       stats_timestamp(time(NULL), counters);
                        stats_write(fname, counters);
                        lockfile_release(fname);
                }
similarity index 100%
rename from system.h
rename to src/system.h
similarity index 95%
rename from unify.c
rename to src/unify.c
index 7c54e9f..53c3a0f 100644 (file)
--- a/unify.c
@@ -1,5 +1,5 @@
 // Copyright (C) 2002 Andrew Tridgell
-// Copyright (C) 2009-2016 Joel Rosdahl
+// Copyright (C) 2009-2017 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -29,6 +29,8 @@
 
 #include "ccache.h"
 
+static bool print_unified = true;
+
 static const char *const s_tokens[] = {
        "...", ">>=", "<<=", "+=", "-=", "*=", "/=", "%=", "&=", "^=",
        "|=",  ">>",  "<<",  "++", "--", "->", "&&", "||", "<=", ">=",
@@ -108,6 +110,9 @@ pushchar(struct mdfour *hash, unsigned char c)
        if (c == 0) {
                if (len > 0) {
                        hash_buffer(hash, (char *)buf, len);
+                       if (print_unified) {
+                               printf("%.*s", (int) len, buf);
+                       }
                        len = 0;
                }
                hash_buffer(hash, NULL, 0);
@@ -117,6 +122,9 @@ pushchar(struct mdfour *hash, unsigned char c)
        buf[len++] = c;
        if (len == 64) {
                hash_buffer(hash, (char *)buf, len);
+               if (print_unified) {
+                       printf("%.*s", (int) len, buf);
+               }
                len = 0;
        }
 }
@@ -238,7 +246,7 @@ unify(struct mdfour *hash, unsigned char *p, size_t size)
 // Hash a file that consists of preprocessor output, but remove any line number
 // information from the hash.
 int
-unify_hash(struct mdfour *hash, const char *fname)
+unify_hash(struct mdfour *hash, const char *fname, bool debug)
 {
        char *data;
        size_t size;
@@ -246,6 +254,7 @@ unify_hash(struct mdfour *hash, const char *fname)
                stats_update(STATS_PREPROCESSOR);
                return -1;
        }
+       print_unified = debug;
        unify(hash, (unsigned char *)data, size);
        free(data);
        return 0;
similarity index 99%
rename from util.c
rename to src/util.c
index 92bebce..b89a33e 100644 (file)
--- a/util.c
@@ -535,8 +535,8 @@ get_hostname(void)
                  * sizeof(TCHAR));
                _snprintf((LPTSTR) lp_display_buf,
                          LocalSize(lp_display_buf) / sizeof(TCHAR),
-                         TEXT("%s failed with error %d: %s"), __FILE__, dw,
-                         lp_msg_buf);
+                         TEXT("%s failed with error %lu: %s"), __FILE__, dw,
+                         (const char *)lp_msg_buf);
 
                cc_log("can't get hostname OS returned error: %s", (char *)lp_display_buf);
 
@@ -965,13 +965,13 @@ parse_size_with_suffix(const char *str, uint64_t *size)
                switch (*p) {
                case 'T':
                        x *= multiplier;
-                       // Fallthrough.
+               // Fallthrough.
                case 'G':
                        x *= multiplier;
-                       // Fallthrough.
+               // Fallthrough.
                case 'M':
                        x *= multiplier;
-                       // Fallthrough.
+               // Fallthrough.
                case 'K':
                case 'k':
                        x *= multiplier;
@@ -989,8 +989,8 @@ parse_size_with_suffix(const char *str, uint64_t *size)
 
 
 #if !defined(HAVE_REALPATH) && \
-    defined(_WIN32) && \
-    !defined(HAVE_GETFINALPATHNAMEBYHANDLEW)
+  defined(_WIN32) && \
+  !defined(HAVE_GETFINALPATHNAMEBYHANDLEW)
 static BOOL GetFileNameFromHandle(HANDLE file_handle, TCHAR *filename,
                                   WORD cch_filename)
 {
@@ -1445,7 +1445,8 @@ x_rename(const char *oldpath, const char *newpath)
                  * sizeof(TCHAR));
                _snprintf((LPTSTR) lp_display_buf,
                          LocalSize(lp_display_buf) / sizeof(TCHAR),
-                         TEXT("%s failed with error %d: %s"), __FILE__, dw, lp_msg_buf);
+                         TEXT("%s failed with error %lu: %s"), __FILE__, dw,
+                         (const char *)lp_msg_buf);
 
                cc_log("can't rename file %s to %s OS returned error: %s",
                       oldpath, newpath, (char *) lp_display_buf);
diff --git a/src/version.c b/src/version.c
new file mode 100644 (file)
index 0000000..5beeb8b
--- /dev/null
@@ -0,0 +1 @@
+const char CCACHE_VERSION[] = "unknown";
similarity index 100%
rename from zlib/adler32.c
rename to src/zlib/adler32.c
similarity index 100%
rename from zlib/crc32.c
rename to src/zlib/crc32.c
similarity index 100%
rename from zlib/crc32.h
rename to src/zlib/crc32.h
similarity index 100%
rename from zlib/deflate.c
rename to src/zlib/deflate.c
similarity index 100%
rename from zlib/deflate.h
rename to src/zlib/deflate.h
similarity index 100%
rename from zlib/gzclose.c
rename to src/zlib/gzclose.c
similarity index 100%
rename from zlib/gzguts.h
rename to src/zlib/gzguts.h
similarity index 100%
rename from zlib/gzlib.c
rename to src/zlib/gzlib.c
similarity index 100%
rename from zlib/gzread.c
rename to src/zlib/gzread.c
similarity index 100%
rename from zlib/gzwrite.c
rename to src/zlib/gzwrite.c
similarity index 100%
rename from zlib/inffast.c
rename to src/zlib/inffast.c
similarity index 100%
rename from zlib/inffast.h
rename to src/zlib/inffast.h
similarity index 100%
rename from zlib/inffixed.h
rename to src/zlib/inffixed.h
similarity index 100%
rename from zlib/inflate.c
rename to src/zlib/inflate.c
similarity index 100%
rename from zlib/inflate.h
rename to src/zlib/inflate.h
similarity index 100%
rename from zlib/inftrees.c
rename to src/zlib/inftrees.c
similarity index 100%
rename from zlib/inftrees.h
rename to src/zlib/inftrees.h
similarity index 100%
rename from zlib/trees.c
rename to src/zlib/trees.c
similarity index 100%
rename from zlib/trees.h
rename to src/zlib/trees.h
similarity index 100%
rename from zlib/zconf.h
rename to src/zlib/zconf.h
similarity index 100%
rename from zlib/zlib.h
rename to src/zlib/zlib.h
similarity index 100%
rename from zlib/zutil.c
rename to src/zlib/zutil.c
similarity index 100%
rename from zlib/zutil.h
rename to src/zlib/zutil.h
diff --git a/test.sh b/test.sh
deleted file mode 100755 (executable)
index d750afe..0000000
--- a/test.sh
+++ /dev/null
@@ -1,3589 +0,0 @@
-#!/bin/sh
-#
-# A simple test suite for ccache.
-#
-# Copyright (C) 2002-2007 Andrew Tridgell
-# Copyright (C) 2009-2018 Joel Rosdahl
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3 of the License, or (at your option) any later
-# version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-green() {
-    printf "\033[1;32m$*\033[0;0m\n"
-}
-
-red() {
-    printf "\033[1;31m$*\033[0;0m\n"
-}
-
-bold() {
-    printf "\033[1;37m$*\033[0;0m\n"
-}
-
-test_failed() {
-    echo
-    red FAILED
-    echo
-    echo "Test suite:     $(bold $CURRENT_SUITE)"
-    echo "Test case:      $(bold $CURRENT_TEST)"
-    echo "Failure reason: $(red "$1")"
-    echo
-    echo "ccache -s:"
-    $CCACHE -s
-    echo
-    echo "Test data and log file have been left in $TESTDIR"
-    exit 1
-}
-
-generate_code() {
-    local nlines=$1
-    local outfile=$2
-
-    rm -f $outfile
-    for i in $(seq $nlines); do
-        echo "int foo_$i(int x) { return x; }" >>$outfile
-    done
-}
-
-remove_cache() {
-    if [ -d $CCACHE_DIR ]; then
-        chmod -R +w $CCACHE_DIR
-        rm -rf $CCACHE_DIR
-    fi
-}
-
-clear_cache() {
-    $CCACHE -Cz >/dev/null
-}
-
-sed_in_place() {
-    local expr=$1
-    shift
-
-    for file in $*; do
-        sed "$expr" $file >$file.sed
-        mv $file.sed $file
-    done
-}
-
-backdate() {
-    touch -t 199901010000 "$@"
-}
-
-expect_stat() {
-    local stat="$1"
-    local expected_value="$2"
-    local value="$(echo $($CCACHE -s | fgrep "$stat" | cut -c34-))"
-
-    if [ "$expected_value" != "$value" ]; then
-        test_failed "Expected \"$stat\" to be $expected_value, actual $value"
-    fi
-}
-
-expect_equal_files() {
-    if [ ! -e "$1" ]; then
-        test_failed "compare_files: $1 missing"
-    fi
-    if [ ! -e "$2" ]; then
-        test_failed "compare_files: $2 missing"
-    fi
-    if ! cmp -s "$1" "$2"; then
-        test_failed "compare_files:: $1 and $2 differ"
-    fi
-}
-
-expect_equal_object_files() {
-    if $HOST_OS_LINUX && $COMPILER_TYPE_CLANG; then
-        if ! which eu-elfcmp >/dev/null 2>&1; then
-            test_failed "Please install elfutils to get eu-elfcmp"
-        fi
-        eu-elfcmp -q "$1" "$2"
-    else
-        cmp -s "$1" "$2"
-    fi
-    if [ $? -ne 0 ]; then
-        test_failed "Objects differ: $1 != $2"
-    fi
-}
-
-expect_file_content() {
-    local file="$1"
-    local content="$2"
-
-    if [ ! -f "$file" ]; then
-        test_failed "$file not found"
-    fi
-    if [ "$(cat $file)" != "$content" ]; then
-        test_failed "Bad content of $file.\nExpected: $content\nActual: $(cat $file)"
-    fi
-}
-
-expect_file_count() {
-    local expected=$1
-    local pattern=$2
-    local dir=$3
-    local actual=`find $dir -name "$pattern" | wc -l`
-    if [ $actual -ne $expected ]; then
-        test_failed "Found $actual (expected $expected) $pattern files in $dir"
-    fi
-}
-
-run_suite() {
-    local suite_name=$1
-
-    CURRENT_SUITE=$suite_name
-    UNCACHED_COMPILE=uncached_compile
-
-    cd $ABS_TESTDIR
-    rm -rf $ABS_TESTDIR/fixture
-
-    if type SUITE_${suite_name}_PROBE >/dev/null 2>&1; then
-        mkdir $ABS_TESTDIR/probe
-        cd $ABS_TESTDIR/probe
-        local skip_reason="$(SUITE_${suite_name}_PROBE)"
-        cd $ABS_TESTDIR
-        rm -rf $ABS_TESTDIR/probe
-        if [ -n "$skip_reason" ]; then
-            echo "Skipped test suite $suite_name [$skip_reason]"
-            return
-        fi
-    fi
-
-    printf "Running test suite %s" "$(bold $suite_name)"
-    SUITE_$suite_name
-    echo
-}
-
-uncached_compile() {
-    # $COMPILER could be a masquerading system ccache, so make sure it's
-    # disabled:
-    CCACHE_DISABLE=1 $COMPILER "$@"
-}
-
-TEST() {
-    CURRENT_TEST=$1
-
-    while read name; do
-        unset $name
-    done <<EOF
-$(env | sed -n 's/^\(CCACHE_[A-Z0-9_]*\)=.*$/\1/p')
-EOF
-    unset GCC_COLORS
-
-    export CCACHE_CONFIGPATH=$ABS_TESTDIR/ccache.conf
-    export CCACHE_DETECT_SHEBANG=1
-    export CCACHE_DIR=$ABS_TESTDIR/.ccache
-    export CCACHE_LOGFILE=$ABS_TESTDIR/ccache.log
-    export CCACHE_NODIRECT=1
-
-    # Many tests backdate files, which updates their ctimes. In those tests, we
-    # must ignore ctimes. Might as well do so everywhere.
-    DEFAULT_SLOPPINESS=include_file_ctime
-    export CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS"
-
-    CCACHE_COMPILE="$CCACHE $COMPILER"
-
-    if $VERBOSE; then
-        printf "\n  %s" "$CURRENT_TEST"
-    else
-        printf .
-    fi
-
-    cd /
-    remove_cache
-    rm -rf $ABS_TESTDIR/run
-    mkdir $ABS_TESTDIR/run
-    cd $ABS_TESTDIR/run
-    if type SUITE_${suite_name}_SETUP >/dev/null 2>&1; then
-        SUITE_${suite_name}_SETUP
-    fi
-}
-
-# =============================================================================
-
-base_tests() {
-    # -------------------------------------------------------------------------
-    TEST "Base case"
-
-    $UNCACHED_COMPILE -c -o reference_test1.o test1.c
-
-    $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 1
-    expect_equal_object_files reference_test1.o test1.o
-
-    $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 1
-    expect_equal_object_files reference_test1.o test1.o
-
-    # -------------------------------------------------------------------------
-    TEST "Debug option"
-
-    $CCACHE_COMPILE -c test1.c -g
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 1
-
-    $CCACHE_COMPILE -c test1.c -g
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    $UNCACHED_COMPILE -c -o reference_test1.o test1.c -g
-    expect_equal_object_files reference_test1.o reference_test1.o
-
-    # -------------------------------------------------------------------------
-    TEST "Output option"
-
-    $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -c test1.c -o foo.o
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    $UNCACHED_COMPILE -c -o reference_test1.o test1.c
-    expect_equal_object_files reference_test1.o foo.o
-
-    # -------------------------------------------------------------------------
-    TEST "Called for link"
-
-    $CCACHE_COMPILE test1.c -o test 2>/dev/null
-    expect_stat 'called for link' 1
-
-    $CCACHE_COMPILE -c test1.c
-    $CCACHE_COMPILE test1.o -o test 2>/dev/null
-    expect_stat 'called for link' 2
-
-    # -------------------------------------------------------------------------
-    TEST "No input file"
-
-    $CCACHE_COMPILE -c foo.c 2>/dev/null
-    expect_stat 'no input file' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Called for preprocessing"
-
-    $CCACHE_COMPILE -E -c test1.c >/dev/null 2>&1
-    expect_stat 'called for preprocessing' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Multiple source files"
-
-    touch test2.c
-    $CCACHE_COMPILE -c test1.c test2.c
-    expect_stat 'multiple source files' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Couldn't find the compiler"
-
-    $CCACHE blahblah -c test1.c 2>/dev/null
-    expect_stat "couldn't find the compiler" 1
-
-    # -------------------------------------------------------------------------
-    TEST "Bad compiler arguments"
-
-    $CCACHE_COMPILE -c test1.c -I 2>/dev/null
-    expect_stat 'bad compiler arguments' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Unsupported source language"
-
-    ln -f test1.c test1.ccc
-    $CCACHE_COMPILE -c test1.ccc 2>/dev/null
-    expect_stat 'unsupported source language' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Unsupported compiler option"
-
-    $CCACHE_COMPILE -M foo -c test1.c >/dev/null 2>&1
-    expect_stat 'unsupported compiler option' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Compiler produced stdout"
-
-    $CCACHE echo foo -c test1.c >/dev/null
-    expect_stat 'compiler produced stdout' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Output to a non-regular file"
-
-    mkdir testd
-    $CCACHE_COMPILE -o testd -c test1.c >/dev/null 2>&1
-    rmdir testd >/dev/null 2>&1
-    expect_stat 'output to a non-regular file' 1
-
-    # -------------------------------------------------------------------------
-    TEST "No input file"
-
-    $CCACHE_COMPILE -c -O2 2>/dev/null
-    expect_stat 'no input file' 1
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_DISABLE"
-
-    CCACHE_DISABLE=1 $CCACHE_COMPILE -c test1.c 2>/dev/null
-    if [ -d $CCACHE_DIR ]; then
-        test_failed "$CCACHE_DIR created despite CCACHE_DISABLE being set"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_COMMENTS"
-
-    $UNCACHED_COMPILE -c -o reference_test1.o test1.c
-
-    mv test1.c test1-saved.c
-    echo '// initial comment' >test1.c
-    cat test1-saved.c >>test1.c
-    CCACHE_COMMENTS=1 $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    echo '// different comment' >test1.c
-    cat test1-saved.c >>test1.c
-    CCACHE_COMMENTS=1 $CCACHE_COMPILE -c test1.c
-    mv test1-saved.c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    $UNCACHED_COMPILE -c -o reference_test1.o test1.c
-    expect_equal_object_files reference_test1.o test1.o
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_NOSTATS"
-
-    CCACHE_NOSTATS=1 $CCACHE_COMPILE -c test1.c -O -O
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_RECACHE"
-
-    $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_RECACHE=1 $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    $UNCACHED_COMPILE -c -o reference_test1.o test1.c
-    expect_equal_object_files reference_test1.o test1.o
-
-    # CCACHE_RECACHE replaces the object file, so the statistics counter will
-    # be off-by-one until next cleanup.
-    expect_stat 'files in cache' 2
-    $CCACHE -c >/dev/null
-    expect_stat 'files in cache' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Directory is hashed if using -g"
-
-    mkdir dir1 dir2
-    cp test1.c dir1
-    cp test1.c dir2
-
-    cd dir1
-    $CCACHE_COMPILE -c test1.c -g
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    $CCACHE_COMPILE -c test1.c -g
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    cd ../dir2
-    $CCACHE_COMPILE -c test1.c -g
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 2
-    $CCACHE_COMPILE -c test1.c -g
-    expect_stat 'cache hit (preprocessed)' 2
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "Directory is not hashed if not using -g"
-
-    mkdir dir1 dir2
-    cp test1.c dir1
-    cp test1.c dir2
-
-    cd dir1
-    $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    cd ../dir2
-    $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 2
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_NOHASHDIR"
-
-    mkdir dir1 dir2
-    cp test1.c dir1
-    cp test1.c dir2
-
-    cd dir1
-    CCACHE_NOHASHDIR=1 $CCACHE_COMPILE -c test1.c -g
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    CCACHE_NOHASHDIR=1 $CCACHE_COMPILE -c test1.c -g
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    cd ../dir2
-    CCACHE_NOHASHDIR=1 $CCACHE_COMPILE -c test1.c -g
-    expect_stat 'cache hit (preprocessed)' 2
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_UNIFY"
-
-    echo '// a silly comment' >>test1.c
-    CCACHE_UNIFY=1 $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    echo '// another silly comment' >>test1.c
-    CCACHE_UNIFY=1 $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    $UNCACHED_COMPILE -c -o reference_test1.o test1.c
-    expect_equal_object_files reference_test1.o test1.o
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_NLEVELS"
-
-    CCACHE_NLEVELS=4 $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 1
-
-    CCACHE_NLEVELS=4 $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 1
-
-    # Directories in $CCACHE_DIR:
-    # - .
-    # - tmp
-    # - a
-    # - a/b
-    # - a/b/c
-    # - a/b/c/d
-    actual_dirs=$(find $CCACHE_DIR -type d | wc -l)
-    expected_dirs=6
-    if [ $actual_dirs -ne $expected_dirs ]; then
-        test_failed "Expected $expected_dirs directories, found $actual_dirs"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_EXTRAFILES"
-
-    echo a >a
-    echo b >b
-
-    $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    CCACHE_EXTRAFILES="a${PATH_DELIM}b" $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 2
-
-    CCACHE_EXTRAFILES="a${PATH_DELIM}b" $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 2
-    expect_stat 'cache miss' 2
-
-    echo b2 >b
-
-    CCACHE_EXTRAFILES="a${PATH_DELIM}b" $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 2
-    expect_stat 'cache miss' 3
-
-    CCACHE_EXTRAFILES="a${PATH_DELIM}b" $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 3
-    expect_stat 'cache miss' 3
-
-    CCACHE_EXTRAFILES="doesntexist" $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 3
-    expect_stat 'cache miss' 3
-    expect_stat 'error hashing extra file' 1
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_PREFIX"
-
-    cat <<'EOF' >prefix-a
-#!/bin/sh
-echo a >>prefix.result
-exec "$@"
-EOF
-    cat <<'EOF' >prefix-b
-#!/bin/sh
-echo b >>prefix.result
-exec "$@"
-EOF
-    chmod +x prefix-a prefix-b
-    cat <<'EOF' >file.c
-int foo;
-EOF
-    PATH=.:$PATH CCACHE_PREFIX="prefix-a prefix-b" $CCACHE_COMPILE -c file.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_file_content prefix.result "a
-b"
-
-    PATH=.:$PATH CCACHE_PREFIX="prefix-a prefix-b" $CCACHE_COMPILE -c file.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-    expect_file_content prefix.result "a
-b"
-
-    rm -f prefix.result
-    PATH=.:$PATH CCACHE_PREFIX_CPP="prefix-a prefix-b" $CCACHE_COMPILE -c file.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 2
-    expect_stat 'cache miss' 1
-    expect_file_content prefix.result "a
-b"
-
-    # -------------------------------------------------------------------------
-    TEST "Files in cache"
-
-    for i in $(seq 32); do
-        generate_code $i test$i.c
-        $CCACHE_COMPILE -c test$i.c
-    done
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 32
-    expect_stat 'files in cache' 32
-
-    # -------------------------------------------------------------------------
-    TEST "Called for preprocessing"
-
-    $CCACHE_COMPILE -c test1.c -E >test1.i
-    expect_stat 'called for preprocessing' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Direct .i compile"
-
-    $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $UNCACHED_COMPILE -c test1.c -E >test1.i
-    $CCACHE_COMPILE -c test1.i
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "-x c"
-
-    ln -f test1.c test1.ccc
-
-    $CCACHE_COMPILE -x c -c test1.ccc
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -x c -c test1.ccc
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "-xc"
-
-    ln -f test1.c test1.ccc
-
-    $CCACHE_COMPILE -xc -c test1.ccc
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -xc -c test1.ccc
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "-x none"
-
-    $CCACHE_COMPILE -x assembler -x none -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -x assembler -x none -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "-x unknown"
-
-    $CCACHE_COMPILE -x unknown -c test1.c 2>/dev/null
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    expect_stat 'unsupported source language' 1
-
-    # -------------------------------------------------------------------------
-    TEST "-D not hashed"
-
-    $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -DNOT_AFFECTING=1 -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "-S"
-
-    $CCACHE_COMPILE -S test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -S test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -c test1.s
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 2
-
-    $CCACHE_COMPILE -c test1.s
-    expect_stat 'cache hit (preprocessed)' 2
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_PATH"
-
-    override_path=`pwd`/override_path
-    mkdir $override_path
-    cat >$override_path/cc <<EOF
-#!/bin/sh
-touch override_path_compiler_executed
-EOF
-    chmod +x $override_path/cc
-    CCACHE_PATH=$override_path $CCACHE cc -c test1.c
-    if [ ! -f override_path_compiler_executed ]; then
-        test_failed "CCACHE_PATH had no effect"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_COMPILERCHECK=mtime"
-
-    cat >compiler.sh <<EOF
-#!/bin/sh
-export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink...
-exec $COMPILER "\$@"
-# A comment
-EOF
-    chmod +x compiler.sh
-    backdate compiler.sh
-    CCACHE_COMPILERCHECK=mtime $CCACHE ./compiler.sh -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    sed_in_place 's/comment/yoghurt/' compiler.sh # Don't change the size
-    chmod +x compiler.sh
-    backdate compiler.sh # Don't change the timestamp
-
-    CCACHE_COMPILERCHECK=mtime $CCACHE ./compiler.sh -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    touch compiler.sh
-    CCACHE_COMPILERCHECK=mtime $CCACHE ./compiler.sh -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_COMPILERCHECK=content"
-
-    cat >compiler.sh <<EOF
-#!/bin/sh
-export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink...
-exec $COMPILER "\$@"
-EOF
-    chmod +x compiler.sh
-
-    CCACHE_COMPILERCHECK=content $CCACHE ./compiler.sh -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_COMPILERCHECK=content $CCACHE ./compiler.sh -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-    echo "# Compiler upgrade" >>compiler.sh
-
-    CCACHE_COMPILERCHECK=content $CCACHE ./compiler.sh -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_COMPILERCHECK=none"
-
-    cat >compiler.sh <<EOF
-#!/bin/sh
-export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink...
-exec $COMPILER "\$@"
-EOF
-    chmod +x compiler.sh
-
-    CCACHE_COMPILERCHECK=none $CCACHE ./compiler.sh -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_COMPILERCHECK=none $CCACHE ./compiler.sh -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    echo "# Compiler upgrade" >>compiler.sh
-    CCACHE_COMPILERCHECK=none $CCACHE ./compiler.sh -c test1.c
-    expect_stat 'cache hit (preprocessed)' 2
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_COMPILERCHECK=string"
-
-    cat >compiler.sh <<EOF
-#!/bin/sh
-export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink...
-exec $COMPILER "\$@"
-EOF
-    chmod +x compiler.sh
-
-    CCACHE_COMPILERCHECK=string:foo $CCACHE ./compiler.sh -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_COMPILERCHECK=string:foo $CCACHE ./compiler.sh -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    CCACHE_COMPILERCHECK=string:bar $CCACHE ./compiler.sh -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 2
-
-    CCACHE_COMPILERCHECK=string:bar $CCACHE ./compiler.sh -c test1.c
-    expect_stat 'cache hit (preprocessed)' 2
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_COMPILERCHECK=command"
-
-    cat >compiler.sh <<EOF
-#!/bin/sh
-export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink...
-exec $COMPILER "\$@"
-EOF
-    chmod +x compiler.sh
-
-    CCACHE_COMPILERCHECK='echo %compiler%' $CCACHE ./compiler.sh -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    echo "# Compiler upgrade" >>compiler.sh
-    CCACHE_COMPILERCHECK="echo ./compiler.sh" $CCACHE ./compiler.sh -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    cat <<EOF >foobar.sh
-#!/bin/sh
-echo foo
-echo bar
-EOF
-    chmod +x foobar.sh
-    CCACHE_COMPILERCHECK='./foobar.sh' $CCACHE ./compiler.sh -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 2
-
-    CCACHE_COMPILERCHECK='echo foo; echo bar' $CCACHE ./compiler.sh -c test1.c
-    expect_stat 'cache hit (preprocessed)' 2
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_COMPILERCHECK=unknown_command"
-
-    cat >compiler.sh <<EOF
-#!/bin/sh
-export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink...
-exec $COMPILER "\$@"
-EOF
-    chmod +x compiler.sh
-
-    CCACHE_COMPILERCHECK="unknown_command" $CCACHE ./compiler.sh -c test1.c 2>/dev/null
-    if [ "$?" -eq 0 ]; then
-        test_failed "Expected failure running unknown_command to verify compiler but was success"
-    fi
-    expect_stat 'compiler check failed' 1
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_RECACHE should remove previous .stderr"
-
-    $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    num=`find $CCACHE_DIR -name '*.stderr' | wc -l`
-    if [ $num -ne 0 ]; then
-        test_failed "$num stderr files found, expected 0 (#1)"
-    fi
-
-    obj_file=`find $CCACHE_DIR -name '*.o'`
-    stderr_file=`echo $obj_file | sed 's/..$/.stderr/'`
-    echo "Warning: foo" >$stderr_file
-    CCACHE_RECACHE=1 $CCACHE_COMPILE -c test1.c
-    num=`find $CCACHE_DIR -name '*.stderr' | wc -l`
-    if [ $num -ne 0 ]; then
-        test_failed "$num stderr files found, expected 0 (#2)"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "No object file"
-
-    cat <<'EOF' >test_no_obj.c
-int test_no_obj;
-EOF
-    cat <<'EOF' >prefix-remove.sh
-#!/bin/sh
-"$@"
-[ x$2 = x-fcolor-diagnostics ] && shift
-[ x$2 = x-fdiagnostics-color ] && shift
-[ x$2 = x-std=gnu99 ] && shift
-[ x$3 = x-o ] && rm $4
-EOF
-    chmod +x prefix-remove.sh
-    CCACHE_PREFIX=`pwd`/prefix-remove.sh $CCACHE_COMPILE -c test_no_obj.c
-    expect_stat 'compiler produced no output' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Empty object file"
-
-    cat <<'EOF' >test_empty_obj.c
-int test_empty_obj;
-EOF
-    cat <<'EOF' >prefix-empty.sh
-#!/bin/sh
-"$@"
-[ x$2 = x-fcolor-diagnostics ] && shift
-[ x$2 = x-fdiagnostics-color ] && shift
-[ x$2 = x-std=gnu99 ] && shift
-[ x$3 = x-o ] && cp /dev/null $4
-EOF
-    chmod +x prefix-empty.sh
-    CCACHE_PREFIX=`pwd`/prefix-empty.sh $CCACHE_COMPILE -c test_empty_obj.c
-    expect_stat 'compiler produced empty output' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Caching stderr"
-
-    cat <<EOF >stderr.c
-int stderr(void)
-{
-  // Trigger warning by having no return statement.
-}
-EOF
-    $CCACHE_COMPILE -Wall -W -c stderr.c 2>/dev/null
-    num=`find $CCACHE_DIR -name '*.stderr' | wc -l`
-    if [ $num -ne 1 ]; then
-        test_failed "$num stderr files found, expected 1"
-    fi
-    expect_stat 'files in cache' 2
-
-    # -------------------------------------------------------------------------
-    TEST "--zero-stats"
-
-    $CCACHE_COMPILE -c test1.c
-    $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 1
-
-    $CCACHE -z >/dev/null
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    expect_stat 'files in cache' 1
-
-    # -------------------------------------------------------------------------
-    TEST "--clear"
-
-    $CCACHE_COMPILE -c test1.c
-    $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 1
-
-    $CCACHE -C >/dev/null
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 0
-
-    # -------------------------------------------------------------------------
-    TEST "-P"
-
-    # Check that -P disables ccache. (-P removes preprocessor information in
-    # such a way that the object file from compiling the preprocessed file will
-    # not be equal to the object file produced when compiling without ccache.)
-
-    $CCACHE_COMPILE -c -P test1.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    expect_stat 'unsupported compiler option' 1
-
-    # -------------------------------------------------------------------------
-    TEST "-Wp,-P"
-
-    # Check that -Wp,-P disables ccache. (-P removes preprocessor information
-    # in such a way that the object file from compiling the preprocessed file
-    # will not be equal to the object file produced when compiling without
-    # ccache.)
-
-    $CCACHE_COMPILE -c -Wp,-P test1.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    expect_stat 'unsupported compiler option' 1
-
-    $CCACHE_COMPILE -c -Wp,-P,-DFOO test1.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    expect_stat 'unsupported compiler option' 2
-
-    $CCACHE_COMPILE -c -Wp,-DFOO,-P test1.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    expect_stat 'unsupported compiler option' 3
-
-    # -------------------------------------------------------------------------
-    TEST "-Wp,-D"
-
-    $CCACHE_COMPILE -c -Wp,-DFOO test1.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -c -DFOO test1.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Buggy GCC 6 cpp"
-
-    cat >buggy-cpp <<EOF
-#!/bin/sh
-export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink...
-if echo "\$*" | grep -- -D >/dev/null; then
-  $COMPILER "\$@"
-else
-  # Mistreat the preprocessor output in the same way as GCC 6 does.
-  $COMPILER "\$@" |
-    sed -e '/^# 1 "<command-line>"\$/ a\\
-# 31 "<command-line>"' \\
-        -e 's/^# 1 "<command-line>" 2\$/# 32 "<command-line>" 2/'
-fi
-exit 0
-EOF
-    cat <<'EOF' >file.c
-int foo;
-EOF
-    chmod +x buggy-cpp
-
-    $CCACHE ./buggy-cpp -c file.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE ./buggy-cpp -DNOT_AFFECTING=1 -c file.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Symlink to source directory"
-
-    mkdir dir
-    cd dir
-    mkdir -p d1/d2
-    echo '#define A "OK"' >d1/h.h
-    cat <<EOF >d1/d2/c.c
-#include <stdio.h>
-#include "../h.h"
-int main() { printf("%s\n", A); }
-EOF
-    echo '#define A "BUG"' >h.h
-    ln -s d1/d2 d3
-
-    CCACHE_BASEDIR=/ $CCACHE_COMPILE -c $PWD/d3/c.c
-    $UNCACHED_COMPILE c.o -o c
-    if [ "$(./c)" != OK ]; then
-        test_failed "Incorrect header file used"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "Symlink to source file"
-
-    mkdir dir
-    cd dir
-    mkdir d
-    echo '#define A "BUG"' >d/h.h
-    cat <<EOF >d/c.c
-#include <stdio.h>
-#include "h.h"
-int main() { printf("%s\n", A); }
-EOF
-    echo '#define A "OK"' >h.h
-    ln -s d/c.c c.c
-
-    CCACHE_BASEDIR=/ $CCACHE_COMPILE -c $PWD/c.c
-    $UNCACHED_COMPILE c.o -o c
-    if [ "$(./c)" != OK ]; then
-        test_failed "Incorrect header file used"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST ".incbin"
-
-    cat <<EOF >incbin.c
-char x[] = ".incbin";
-EOF
-
-    $CCACHE_COMPILE -c incbin.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    expect_stat 'unsupported code directive' 1
-
-    # -------------------------------------------------------------------------
-    TEST "UNCACHED_ERR_FD"
-
-    cat >compiler.sh <<'EOF'
-#!/bin/sh
-if [ "$1" = "-E" ]; then
-    echo preprocessed
-    printf ${N}Pu >&$UNCACHED_ERR_FD
-else
-    echo compiled >test1.o
-    printf ${N}Cc >&2
-    printf ${N}Cu >&$UNCACHED_ERR_FD
-fi
-EOF
-    chmod +x compiler.sh
-
-    N=1 $CCACHE ./compiler.sh -c test1.c 2>stderr.txt
-    stderr=$(cat stderr.txt)
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    if [ "$stderr" != "1Pu1Cu1Cc" ]; then
-        test_failed "Unexpected stderr: $stderr != 1Pu1Cu1Cc"
-    fi
-
-    N=2 $CCACHE ./compiler.sh -c test1.c 2>stderr.txt
-    stderr=$(cat stderr.txt)
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-    if [ "$stderr" != "2Pu1Cc" ]; then
-        test_failed "Unexpected stderr: $stderr != 2Pu1Cc"
-    fi
-}
-
-# =============================================================================
-
-SUITE_base_SETUP() {
-    generate_code 1 test1.c
-}
-
-SUITE_base() {
-    base_tests
-}
-
-# =============================================================================
-
-SUITE_nocpp2_SETUP() {
-    export CCACHE_NOCPP2=1
-    generate_code 1 test1.c
-}
-
-SUITE_nocpp2() {
-    base_tests
-}
-
-# =============================================================================
-
-SUITE_multi_arch_PROBE() {
-    if ! $HOST_OS_APPLE; then
-        echo "multiple -arch options not supported on $(uname -s)"
-        return
-    fi
-}
-
-SUITE_multi_arch_SETUP() {
-    generate_code 1 test1.c
-    unset CCACHE_NODIRECT
-}
-
-SUITE_multi_arch() {
-    # -------------------------------------------------------------------------
-    TEST "cache hit, direct mode"
-
-    # Different arches shouldn't affect each other
-    $CCACHE_COMPILE -arch i386 -c test1.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -arch x86_64 -c test1.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache miss' 2
-
-    $CCACHE_COMPILE -arch i386 -c test1.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache miss' 2
-
-    # Multiple arches should be cached too
-    $CCACHE_COMPILE -arch i386 -arch x86_64 -c test1.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache miss' 3
-
-    $CCACHE_COMPILE -arch i386 -arch x86_64 -c test1.c
-    expect_stat 'cache hit (direct)' 2
-    expect_stat 'cache miss' 3
-
-    # -------------------------------------------------------------------------
-    TEST "cache hit, preprocessor mode"
-
-    export CCACHE_NODIRECT=1
-
-    $CCACHE_COMPILE -arch i386 -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -arch x86_64 -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    $CCACHE_COMPILE -arch i386 -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 2
-
-    # Multiple arches should be cached too
-    $CCACHE_COMPILE -arch i386 -arch x86_64 -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 3
-
-    $CCACHE_COMPILE -arch i386 -arch x86_64 -c test1.c
-    expect_stat 'cache hit (preprocessed)' 2
-    expect_stat 'cache miss' 3
-}
-
-# =============================================================================
-
-SUITE_serialize_diagnostics_PROBE() {
-    touch test.c
-    if ! $UNCACHED_COMPILE -c --serialize-diagnostics \
-         test1.dia test.c 2>/dev/null; then
-        echo "--serialize-diagnostics not supported by compiler"
-    fi
-}
-
-SUITE_serialize_diagnostics_SETUP() {
-    generate_code 1 test1.c
-}
-
-SUITE_serialize_diagnostics() {
-    # -------------------------------------------------------------------------
-    TEST "Compile OK"
-
-    $UNCACHED_COMPILE -c --serialize-diagnostics expected.dia test1.c
-
-    $CCACHE_COMPILE -c --serialize-diagnostics test.dia test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 2
-    expect_equal_files expected.dia test.dia
-
-    rm test.dia
-
-    $CCACHE_COMPILE -c --serialize-diagnostics test.dia test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 2
-    expect_equal_files expected.dia test.dia
-
-    # -------------------------------------------------------------------------
-    TEST "Compile failed"
-
-    echo "bad source" >error.c
-    if $UNCACHED_COMPILE -c --serialize-diagnostics expected.dia error.c 2>expected.stderr; then
-        test_failed "Expected an error compiling error.c"
-    fi
-
-    $CCACHE_COMPILE -c --serialize-diagnostics test.dia error.c 2>test.stderr
-    expect_stat 'compile failed' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    expect_stat 'files in cache' 0
-    expect_equal_files expected.dia test.dia
-    expect_equal_files expected.stderr test.stderr
-
-    # -------------------------------------------------------------------------
-    TEST "--serialize-diagnostics + CCACHE_BASEDIR"
-
-    mkdir -p dir1/src dir1/include
-    cat <<EOF >dir1/src/test.c
-#include <stdarg.h>
-#include <test.h>
-EOF
-    cat <<EOF >dir1/include/test.h
-int test;
-EOF
-    cp -r dir1 dir2
-    backdate dir1/include/test.h dir2/include/test.h
-
-    cat <<EOF >stderr.h
-int stderr(void)
-{
-  // Trigger warning by having no return statement.
-}
-EOF
-
-    unset CCACHE_NODIRECT
-
-    cd dir1
-    CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -w -MD -MF `pwd`/test.d -I`pwd`/include --serialize-diagnostics `pwd`/test.dia -c src/test.c -o `pwd`/test.o
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 4
-
-    cd ../dir2
-    CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -w -MD -MF `pwd`/test.d -I`pwd`/include --serialize-diagnostics `pwd`/test.dia -c src/test.c -o `pwd`/test.o
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 4
-}
-
-# =============================================================================
-
-SUITE_debug_prefix_map_PROBE() {
-    if $COMPILER_USES_MINGW; then
-        echo "-fdebug-prefix-map not supported by compiler"
-    fi
-}
-
-SUITE_debug_prefix_map_SETUP() {
-    unset CCACHE_NODIRECT
-
-    mkdir -p dir1/src dir1/include
-    cat <<EOF >dir1/src/test.c
-#include <stdarg.h>
-#include <test.h>
-EOF
-    cat <<EOF >dir1/include/test.h
-int test;
-EOF
-    cp -r dir1 dir2
-    backdate dir1/include/test.h dir2/include/test.h
-}
-
-SUITE_debug_prefix_map() {
-    # -------------------------------------------------------------------------
-    TEST "Mapping of debug info CWD"
-
-    cd dir1
-    CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -I`pwd`/include -g -fdebug-prefix-map=`pwd`=dir -c `pwd`/src/test.c -o `pwd`/test.o
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 2
-    if grep -E "[^=]`pwd`[^=]" test.o >/dev/null 2>&1; then
-        test_failed "Source dir (`pwd`) found in test.o"
-    fi
-
-    cd ../dir2
-    CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -I`pwd`/include -g -fdebug-prefix-map=`pwd`=dir -c `pwd`/src/test.c -o `pwd`/test.o
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 2
-    if grep -E "[^=]`pwd`[^=]" test.o >/dev/null 2>&1; then
-        test_failed "Source dir (`pwd`) found in test.o"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "Multiple -fdebug-prefix-map"
-
-    cd dir1
-    CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -I`pwd`/include -g -fdebug-prefix-map=`pwd`=name -fdebug-prefix-map=foo=bar -c `pwd`/src/test.c -o `pwd`/test.o
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 2
-    if grep -E "[^=]`pwd`[^=]" test.o >/dev/null 2>&1; then
-        test_failed "Source dir (`pwd`) found in test.o"
-    fi
-    if ! grep "name" test.o >/dev/null 2>&1; then
-        test_failed "Relocation (name) not found in test.o"
-    fi
-
-    cd ../dir2
-    CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -I`pwd`/include -g -fdebug-prefix-map=`pwd`=name -fdebug-prefix-map=foo=bar -c `pwd`/src/test.c -o `pwd`/test.o
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 2
-    if grep -E "[^=]`pwd`[^=]" test.o >/dev/null 2>&1; then
-        test_failed "Source dir (`pwd`) found in test.o"
-    fi
-}
-
-# =============================================================================
-
-SUITE_masquerading_PROBE() {
-    local compiler_binary=$(echo $COMPILER | cut -d' ' -f1)
-    if [ "$(dirname $compiler_binary)" != . ]; then
-        echo "compiler ($compiler_binary) not taken from PATH"
-    fi
-}
-
-SUITE_masquerading_SETUP() {
-    local compiler_binary=$(echo $COMPILER | cut -d' ' -f1)
-    local compiler_args=$(echo $COMPILER | cut -s -d' ' -f2-)
-
-    ln -s "$CCACHE" $compiler_binary
-    CCACHE_COMPILE="./$compiler_binary $compiler_args"
-    generate_code 1 test1.c
-}
-
-SUITE_masquerading() {
-    # -------------------------------------------------------------------------
-    TEST "Masquerading via symlink"
-
-    $UNCACHED_COMPILE -c -o reference_test1.o test1.c
-
-    $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 1
-    expect_equal_object_files reference_test1.o test1.o
-
-    $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 1
-    expect_equal_object_files reference_test1.o test1.o
-}
-
-# =============================================================================
-
-SUITE_hardlink_PROBE() {
-    touch file1
-    if ! ln file1 file2 >/dev/null 2>&1; then
-        echo "file system doesn't support hardlinks"
-    fi
-}
-
-SUITE_hardlink() {
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_HARDLINK"
-
-    generate_code 1 test1.c
-
-    $UNCACHED_COMPILE -c -o reference_test1.o test1.c
-
-    $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 1
-    expect_equal_object_files reference_test1.o test1.o
-
-    CCACHE_HARDLINK=1 $CCACHE_COMPILE -c test1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 1
-    expect_equal_object_files reference_test1.o test1.o
-
-    local obj_in_cache=$(find $CCACHE_DIR -name '*.o')
-    if [ ! $obj_in_cache -ef test1.o ]; then
-        test_failed "Object file not hard-linked to cached object file"
-    fi
-}
-
-# =============================================================================
-
-SUITE_direct_SETUP() {
-    unset CCACHE_NODIRECT
-
-    cat <<EOF >test.c
-// test.c
-#include "test1.h"
-#include "test2.h"
-EOF
-    cat <<EOF >test1.h
-#include "test3.h"
-int test1;
-EOF
-    cat <<EOF >test2.h
-int test2;
-EOF
-    cat <<EOF >test3.h
-int test3;
-EOF
-    backdate test1.h test2.h test3.h
-
-    $UNCACHED_COMPILE -c -Wp,-MD,expected.d test.c
-    $UNCACHED_COMPILE -c -Wp,-MMD,expected_mmd.d test.c
-    rm test.o
-}
-
-SUITE_direct() {
-    # -------------------------------------------------------------------------
-    TEST "Base case"
-
-    $UNCACHED_COMPILE -c -o reference_test.o test.c
-
-    $CCACHE_COMPILE -c test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 2 # .o + .manifest
-    expect_equal_object_files reference_test.o test.o
-
-    $CCACHE_COMPILE -c test.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_stat 'files in cache' 2
-    expect_equal_object_files reference_test.o test.o
-
-    # -------------------------------------------------------------------------
-    TEST "Corrupt manifest file"
-
-    $CCACHE_COMPILE -c test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    manifest_file=`find $CCACHE_DIR -name '*.manifest'`
-    rm $manifest_file
-    touch $manifest_file
-
-    $CCACHE_COMPILE -c test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -c test.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_NODIRECT"
-
-    CCACHE_NODIRECT=1 $CCACHE_COMPILE -c test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_NODIRECT=1 $CCACHE_COMPILE -c test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Modified include file"
-
-    $CCACHE_COMPILE -c test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    echo "int test3_2;" >>test3.h
-    backdate test3.h
-    $CCACHE_COMPILE -c test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    $CCACHE_COMPILE -c test.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "Removed but previously compiled header file"
-
-    $CCACHE_COMPILE -c test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    rm test3.h
-    cat <<EOF >test1.h
-// No more include of test3.h
-int test1;
-EOF
-    backdate test1.h
-
-    $CCACHE_COMPILE -c test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    $CCACHE_COMPILE -c test.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "Calculation of dependency file names"
-
-    mkdir test.dir
-    for ext in .obj "" . .foo.bar; do
-        dep_file=test.dir/`echo test$ext | sed 's/\.[^.]*\$//'`.d
-        $CCACHE_COMPILE -MD -c test.c -o test.dir/test$ext
-        rm -f $dep_file
-        $CCACHE_COMPILE -MD -c test.c -o test.dir/test$ext
-        if [ ! -f $dep_file ]; then
-            test_failed "$dep_file missing"
-        fi
-    done
-    expect_stat 'files in cache' 12
-
-    # -------------------------------------------------------------------------
-    TEST "-MMD for different source files"
-
-    mkdir a b
-    touch a/source.c b/source.c
-    backdate a/source.h b/source.h
-    $CCACHE_COMPILE -MMD -c a/source.c
-    expect_file_content source.d "source.o: a/source.c"
-
-    $CCACHE_COMPILE -MMD -c b/source.c
-    expect_file_content source.d "source.o: b/source.c"
-
-    $CCACHE_COMPILE -MMD -c a/source.c
-    expect_file_content source.d "source.o: a/source.c"
-
-    # -------------------------------------------------------------------------
-    TEST "-MMD for different include file paths"
-
-    mkdir a b
-    touch a/source.h b/source.h
-    backdate a/source.h b/source.h
-    echo '#include <source.h>' >source.c
-    $CCACHE_COMPILE -MMD -Ia -c source.c
-    expect_file_content source.d "source.o: source.c a/source.h"
-
-    $CCACHE_COMPILE -MMD -Ib -c source.c
-    expect_file_content source.d "source.o: source.c b/source.h"
-
-    $CCACHE_COMPILE -MMD -Ia -c source.c
-    expect_file_content source.d "source.o: source.c a/source.h"
-
-    # -------------------------------------------------------------------------
-    TEST "-Wp,-MD"
-
-    $CCACHE_COMPILE -c -Wp,-MD,other.d test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_equal_files other.d expected.d
-
-    $UNCACHED_COMPILE -c -Wp,-MD,other.d test.c -o reference_test.o
-    expect_equal_object_files reference_test.o test.o
-
-    rm -f other.d
-    $CCACHE_COMPILE -c -Wp,-MD,other.d test.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_equal_files other.d expected.d
-    expect_equal_object_files reference_test.o test.o
-
-    $CCACHE_COMPILE -c -Wp,-MD,different_name.d test.c
-    expect_stat 'cache hit (direct)' 2
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_equal_files different_name.d expected.d
-    expect_equal_object_files reference_test.o test.o
-
-    # -------------------------------------------------------------------------
-    TEST "-Wp,-MMD"
-
-    $CCACHE_COMPILE -c -Wp,-MMD,other.d test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_equal_files other.d expected_mmd.d
-
-    $UNCACHED_COMPILE -c -Wp,-MMD,other.d test.c -o reference_test.o
-    expect_equal_object_files reference_test.o test.o
-
-    rm -f other.d
-    $CCACHE_COMPILE -c -Wp,-MMD,other.d test.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_equal_files other.d expected_mmd.d
-    expect_equal_object_files reference_test.o test.o
-
-    $CCACHE_COMPILE -c -Wp,-MMD,different_name.d test.c
-    expect_stat 'cache hit (direct)' 2
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_equal_files different_name.d expected_mmd.d
-    expect_equal_object_files reference_test.o test.o
-
-    # -------------------------------------------------------------------------
-    TEST "-Wp,-D"
-
-    $CCACHE_COMPILE -c -Wp,-DFOO test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -c -DFOO test.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "-Wp, with multiple arguments"
-
-    # ccache could try to parse and make sense of -Wp, with multiple arguments,
-    # but it currently doesn't, so we have to disable direct mode.
-
-    touch source.c
-
-    $CCACHE_COMPILE -c -Wp,-MMD,source.d,-MT,source.o source.c 2>/dev/null
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_file_content source.d "source.o: source.c"
-
-    $CCACHE_COMPILE -c -Wp,-MMD,source.d,-MT,source.o source.c 2>/dev/null
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-    expect_file_content source.d "source.o: source.c"
-
-    # -------------------------------------------------------------------------
-    TEST "-MMD for different source files"
-
-    mkdir a b
-    touch a/source.c b/source.c
-    $CCACHE_COMPILE -MMD -c a/source.c
-    expect_file_content source.d "source.o: a/source.c"
-
-    $CCACHE_COMPILE -MMD -c b/source.c
-    expect_file_content source.d "source.o: b/source.c"
-
-    $CCACHE_COMPILE -MMD -c a/source.c
-    expect_file_content source.d "source.o: a/source.c"
-
-    # -------------------------------------------------------------------------
-    TEST "Multiple object entries in manifest"
-
-    for i in 0 1 2 3 4; do
-        echo "int test1_$i;" >>test1.h
-        backdate test1.h
-        $CCACHE_COMPILE -c test.c
-        $CCACHE_COMPILE -c test.c
-    done
-    expect_stat 'cache hit (direct)' 5
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 5
-
-    # -------------------------------------------------------------------------
-    TEST "-MD"
-
-    $CCACHE_COMPILE -c -MD test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_equal_files test.d expected.d
-
-    $UNCACHED_COMPILE -c -MD test.c -o reference_test.o
-    expect_equal_object_files reference_test.o test.o
-
-    rm -f test.d
-    $CCACHE_COMPILE -c -MD test.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_equal_files test.d expected.d
-    expect_equal_object_files reference_test.o test.o
-
-    # -------------------------------------------------------------------------
-    TEST "-ftest-coverage"
-
-    cat <<EOF >code.c
-int test() { return 0; }
-EOF
-
-    $CCACHE_COMPILE -c -fprofile-arcs -ftest-coverage code.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    test -r code.gcno || test_failed "code.gcno missing"
-
-    rm code.gcno
-
-    $CCACHE_COMPILE -c -fprofile-arcs -ftest-coverage code.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    test -r code.gcno || test_failed "code.gcno missing"
-
-    # -------------------------------------------------------------------------
-    TEST "Direct mode on cache created by ccache without direct mode support"
-
-    CCACHE_NODIRECT=1 $CCACHE_COMPILE -c -MD test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_equal_files test.d expected.d
-    $UNCACHED_COMPILE -c -MD test.c -o reference_test.o
-    expect_equal_object_files reference_test.o test.o
-
-    rm -f test.d
-
-    CCACHE_NODIRECT=1 $CCACHE_COMPILE -c -MD test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-    expect_equal_files test.d expected.d
-    expect_equal_object_files reference_test.o test.o
-
-    rm -f test.d
-
-    $CCACHE_COMPILE -c -MD test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 2
-    expect_stat 'cache miss' 1
-    expect_equal_files test.d expected.d
-    expect_equal_object_files reference_test.o test.o
-
-    rm -f test.d
-
-    $CCACHE_COMPILE -c -MD test.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 2
-    expect_stat 'cache miss' 1
-    expect_equal_files test.d expected.d
-    expect_equal_object_files reference_test.o test.o
-
-    # -------------------------------------------------------------------------
-    TEST "-MF"
-
-    $CCACHE_COMPILE -c -MD -MF other.d test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_equal_files other.d expected.d
-    $UNCACHED_COMPILE -c -MD -MF other.d test.c -o reference_test.o
-    expect_equal_object_files reference_test.o test.o
-
-    rm -f other.d
-
-    $CCACHE_COMPILE -c -MD -MF other.d test.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_equal_files other.d expected.d
-    expect_equal_object_files reference_test.o test.o
-
-    $CCACHE_COMPILE -c -MD -MF different_name.d test.c
-    expect_stat 'cache hit (direct)' 2
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_equal_files different_name.d expected.d
-    expect_equal_object_files reference_test.o test.o
-
-    rm -f different_name.d
-
-    $CCACHE_COMPILE -c -MD -MFthird_name.d test.c
-    expect_stat 'cache hit (direct)' 3
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_equal_files third_name.d expected.d
-    expect_equal_object_files reference_test.o test.o
-
-    rm -f third_name.d
-
-    # -------------------------------------------------------------------------
-    TEST "Missing .d file"
-
-    $CCACHE_COMPILE -c -MD test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -c -MD test.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    expect_equal_files test.d expected.d
-
-    find $CCACHE_DIR -name '*.d' -delete
-
-    $CCACHE_COMPILE -c -MD test.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-    expect_equal_files test.d expected.d
-
-    # -------------------------------------------------------------------------
-    TEST "stderr from both preprocessor and compiler"
-
-    cat <<EOF >cpp-warning.c
-#if FOO
-// Trigger preprocessor warning about extra token after #endif.
-#endif FOO
-int stderr(void)
-{
-  // Trigger compiler warning by having no return statement.
-}
-EOF
-    $CCACHE_COMPILE -Wall -W -c cpp-warning.c 2>stderr-orig.txt
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_NODIRECT=1 $CCACHE_COMPILE -Wall -W -c cpp-warning.c 2>stderr-cpp.txt
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-    expect_file_content stderr-cpp.txt "`cat stderr-orig.txt`"
-
-    $CCACHE_COMPILE -Wall -W -c cpp-warning.c 2>stderr-mf.txt
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-    expect_file_content stderr-mf.txt "`cat stderr-orig.txt`"
-
-    # -------------------------------------------------------------------------
-    TEST "Empty source file"
-
-    touch empty.c
-
-    $CCACHE_COMPILE -c empty.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -c empty.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Empty include file"
-
-    touch empty.h
-    cat <<EOF >include_empty.c
-#include "empty.h"
-EOF
-    backdate empty.h
-    $CCACHE_COMPILE -c include_empty.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    $CCACHE_COMPILE -c include_empty.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "__FILE__ in source file disables direct mode"
-
-    cat <<EOF >file.c
-#define file __FILE__
-int test;
-EOF
-
-    $CCACHE_COMPILE -c file.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -c file.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -c `pwd`/file.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "__FILE__ in include file disables direct mode"
-
-    cat <<EOF >file.h
-#define file __FILE__
-int test;
-EOF
-    backdate file.h
-    cat <<EOF >file_h.c
-#include "file.h"
-EOF
-
-    $CCACHE_COMPILE -c file_h.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -c file_h.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    mv file_h.c file2_h.c
-
-    $CCACHE_COMPILE -c `pwd`/file2_h.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "__FILE__ in source file ignored if sloppy"
-
-    cat <<EOF >file.c
-#define file __FILE__
-int test;
-EOF
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c file.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c file.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c `pwd`/file.c
-    expect_stat 'cache hit (direct)' 2
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "__FILE__ in include file ignored if sloppy"
-
-    cat <<EOF >file.h
-#define file __FILE__
-int test;
-EOF
-    backdate file.h
-    cat <<EOF >file_h.c
-#include "file.h"
-EOF
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c file_h.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c file_h.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    mv file_h.c file2_h.c
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c `pwd`/file2_h.c
-    expect_stat 'cache hit (direct)' 2
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "__TIME__ in source file disables direct mode"
-
-    cat <<EOF >time.c
-#define time __TIME__
-int test;
-EOF
-
-    $CCACHE_COMPILE -c time.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -c time.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "__TIME__ in include file disables direct mode"
-
-    cat <<EOF >time.h
-#define time __TIME__
-int test;
-EOF
-    backdate time.h
-
-    cat <<EOF >time_h.c
-#include "time.h"
-EOF
-
-    $CCACHE_COMPILE -c time_h.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -c time_h.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "__TIME__ in source file ignored if sloppy"
-
-    cat <<EOF >time.c
-#define time __TIME__
-int test;
-EOF
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE -c time.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE -c time.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "__TIME__ in include file ignored if sloppy"
-
-    cat <<EOF >time.h
-#define time __TIME__
-int test;
-EOF
-    backdate time.h
-    cat <<EOF >time_h.c
-#include "time.h"
-EOF
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE -c time_h.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE -c time_h.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Too new include file disables direct mode"
-
-    cat <<EOF >new.c
-#include "new.h"
-EOF
-    cat <<EOF >new.h
-int test;
-EOF
-    touch -t 203801010000 new.h
-
-    $CCACHE_COMPILE -c new.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -c new.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "New include file ignored if sloppy"
-
-    cat <<EOF >new.c
-#include "new.h"
-EOF
-    cat <<EOF >new.h
-int test;
-EOF
-    touch -t 203801010000 new.h
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS include_file_mtime" $CCACHE_COMPILE -c new.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS include_file_mtime" $CCACHE_COMPILE -c new.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    # Check that environment variables that affect the preprocessor are taken
-    # into account.
-    TEST "CPATH included in hash"
-
-    rm -rf subdir1 subdir2
-    mkdir subdir1 subdir2
-    cat <<EOF >subdir1/foo.h
-int foo;
-EOF
-    cat <<EOF >subdir2/foo.h
-int foo;
-EOF
-    cat <<EOF >foo.c
-#include <foo.h>
-EOF
-    backdate subdir1/foo.h subdir2/foo.h
-
-    CPATH=subdir1 $CCACHE_COMPILE -c foo.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CPATH=subdir1 $CCACHE_COMPILE -c foo.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CPATH=subdir2 $CCACHE_COMPILE -c foo.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2 # subdir2 is part of the preprocessor output
-
-    CPATH=subdir2 $CCACHE_COMPILE -c foo.c
-    expect_stat 'cache hit (direct)' 2
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "Comment in strings"
-
-    echo 'char *comment = " /* \\\\u" "foo" " */";' >comment.c
-
-    $CCACHE_COMPILE -c comment.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -c comment.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    echo 'char *comment = " /* \\\\u" "goo" " */";' >comment.c
-
-    $CCACHE_COMPILE -c comment.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "#line directives with troublesome files"
-
-    cat <<EOF >strange.c
-int foo;
-EOF
-    for x in stdout tty sda hda; do
-        if [ -b /dev/$x ] || [ -c /dev/$x ]; then
-            echo "#line 1 \"/dev/$x\"" >>strange.c
-        fi
-    done
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS include_file_mtime" $CCACHE_COMPILE -c strange.c
-
-    manifest=`find $CCACHE_DIR -name '*.manifest'`
-    if [ -n "$manifest" ]; then
-        data="`$CCACHE --dump-manifest $manifest | egrep '/dev/(stdout|tty|sda|hda'`"
-        if [ -n "$data" ]; then
-            test_failed "$manifest contained troublesome file(s): $data"
-        fi
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "--dump-manifest"
-
-    $CCACHE_COMPILE test.c -c -o test.o
-
-    manifest=`find $CCACHE_DIR -name '*.manifest'`
-    $CCACHE --dump-manifest $manifest >manifest.dump
-
-    if grep 'Hash: d4de2f956b4a386c6660990a7a1ab13f' manifest.dump >/dev/null 2>&1 && \
-       grep 'Hash: e94ceb9f1b196c387d098a5f1f4fe862' manifest.dump >/dev/null 2>&1 && \
-       grep 'Hash: ba753bebf9b5eb99524bb7447095e2e6' manifest.dump >/dev/null 2>&1; then
-        : OK
-    else
-        test_failed "Unexpected output of --dump-manifest"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "Argument-less -B and -L"
-
-    cat <<EOF >test.c
-#include <stdio.h>
-int main(void)
-{
-#ifdef FOO
-    puts("FOO");
-#endif
-    return 0;
-}
-EOF
-
-    $CCACHE_COMPILE -B -L -DFOO -c test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -B -L -DBAR -c test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_IGNOREHEADERS with filename"
-
-    mkdir subdir
-    cat <<EOF >subdir/ignore.h
-// We don't want this header in the manifest.
-EOF
-    backdate subdir/ignore.h
-    cat <<EOF >ignore.c
-#include "subdir/ignore.h"
-int foo;
-EOF
-
-    CCACHE_IGNOREHEADERS="subdir/ignore.h" $CCACHE_COMPILE -c ignore.c
-    manifest=`find $CCACHE_DIR -name '*.manifest'`
-    data="`$CCACHE --dump-manifest $manifest | grep subdir/ignore.h`"
-    if [ -n "$data" ]; then
-        test_failed "$manifest contained ignored header: $data"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_IGNOREHEADERS with directory"
-
-    mkdir subdir
-    cat <<EOF >subdir/ignore.h
-// We don't want this header in the manifest.
-EOF
-    backdate subdir/ignore.h
-    cat <<EOF >ignore.c
-#include "subdir/ignore.h"
-int foo;
-EOF
-
-    CCACHE_IGNOREHEADERS="subdir" $CCACHE_COMPILE -c ignore.c
-    manifest=`find $CCACHE_DIR -name '*.manifest'`
-    data="`$CCACHE --dump-manifest $manifest | grep subdir/ignore.h`"
-    if [ -n "$data" ]; then
-        test_failed "$manifest contained ignored header: $data"
-    fi
-}
-
-# =============================================================================
-
-SUITE_basedir_SETUP() {
-    unset CCACHE_NODIRECT
-
-    mkdir -p dir1/src dir1/include
-    cat <<EOF >dir1/src/test.c
-#include <stdarg.h>
-#include <test.h>
-EOF
-    cat <<EOF >dir1/include/test.h
-int test;
-EOF
-    cp -r dir1 dir2
-    backdate dir1/include/test.h dir2/include/test.h
-}
-
-SUITE_basedir() {
-    # -------------------------------------------------------------------------
-    TEST "Enabled CCACHE_BASEDIR"
-
-    cd dir1
-    CCACHE_BASEDIR="`pwd`" $CCACHE_COMPILE -I`pwd`/include -c src/test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    cd ../dir2
-    CCACHE_BASEDIR="`pwd`" $CCACHE_COMPILE -I`pwd`/include -c src/test.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Disabled (default) CCACHE_BASEDIR"
-
-    cd dir1
-    CCACHE_BASEDIR="`pwd`" $CCACHE_COMPILE -I`pwd`/include -c src/test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    # CCACHE_BASEDIR="" is the default:
-    $CCACHE_COMPILE -I`pwd`/include -c src/test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "Path normalization"
-
-    cd dir1
-    CCACHE_BASEDIR="`pwd`" $CCACHE_COMPILE -I`pwd`/include -c src/test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    mkdir subdir
-    ln -s `pwd`/include subdir/symlink
-
-    # Rewriting triggered by CCACHE_BASEDIR should handle paths with multiple
-    # slashes, redundant "/." parts and "foo/.." parts correctly. Note that the
-    # ".." part of the path is resolved after the symlink has been resolved.
-    CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -I`pwd`//./subdir/symlink/../include -c `pwd`/src/test.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Rewriting in stderr"
-
-    cat <<EOF >stderr.h
-int stderr(void)
-{
-  // Trigger warning by having no return statement.
-}
-EOF
-    backdate stderr.h
-    cat <<EOF >stderr.c
-#include <stderr.h>
-EOF
-
-    CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -Wall -W -I`pwd` -c `pwd`/stderr.c -o `pwd`/stderr.o 2>stderr.txt
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    if grep `pwd` stderr.txt >/dev/null 2>&1; then
-        test_failed "Base dir (`pwd`) found in stderr:\n`cat stderr.txt`"
-    fi
-
-    CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -Wall -W -I`pwd` -c `pwd`/stderr.c -o `pwd`/stderr.o 2>stderr.txt
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    if grep `pwd` stderr.txt >/dev/null 2>&1; then
-        test_failed "Base dir (`pwd`) found in stderr:\n`cat stderr.txt`"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "-MF/-MQ/-MT with absolute paths"
-
-    for option in MF "MF " MQ "MQ " MT "MT "; do
-        clear_cache
-        cd dir1
-        CCACHE_BASEDIR="`pwd`" $CCACHE_COMPILE -I`pwd`/include -MD -${option}`pwd`/test.d -c src/test.c
-        expect_stat 'cache hit (direct)' 0
-        expect_stat 'cache hit (preprocessed)' 0
-        expect_stat 'cache miss' 1
-        cd ..
-
-        cd dir2
-        CCACHE_BASEDIR="`pwd`" $CCACHE_COMPILE -I`pwd`/include -MD -${option}`pwd`/test.d -c src/test.c
-        expect_stat 'cache hit (direct)' 1
-        expect_stat 'cache hit (preprocessed)' 0
-        expect_stat 'cache miss' 1
-        cd ..
-    done
-
-    # -------------------------------------------------------------------------
-    # When BASEDIR is set to /, check that -MF, -MQ and -MT arguments with
-    # absolute paths are rewritten to relative and that the dependency file
-    # only contains relative paths.
-    TEST "-MF/-MQ/-MT with absolute paths and BASEDIR set to /"
-
-    for option in MF "MF " MQ "MQ " MT "MT "; do
-        clear_cache
-        cd dir1
-        CCACHE_BASEDIR="/" $CCACHE_COMPILE -I`pwd`/include -MD -${option}`pwd`/test.d -c src/test.c
-        expect_stat 'cache hit (direct)' 0
-        expect_stat 'cache hit (preprocessed)' 0
-        expect_stat 'cache miss' 1
-        # Check that there is no absolute path in the dependency file:
-        while read line; do
-            for file in $line; do
-                case $file in /*)
-                    test_failed "Absolute file path '$file' found in dependency file '`pwd`/test.d'"
-                esac
-            done
-        done <test.d
-        cd ..
-
-        cd dir2
-        CCACHE_BASEDIR="/" $CCACHE_COMPILE -I`pwd`/include -MD -${option}`pwd`/test.d -c src/test.c
-        expect_stat 'cache hit (direct)' 1
-        expect_stat 'cache hit (preprocessed)' 0
-        expect_stat 'cache miss' 1
-        cd ..
-    done
-}
-
-# =============================================================================
-
-SUITE_compression_SETUP() {
-    generate_code 1 test.c
-}
-
-SUITE_compression() {
-    # -------------------------------------------------------------------------
-    TEST "Hash sum equal for compressed and uncompressed files"
-
-    CCACHE_COMPRESS=1 $CCACHE_COMPILE -c test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_COMPRESS=1 $CCACHE_COMPILE -c test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -c test.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 2
-    expect_stat 'cache miss' 1
-}
-
-# =============================================================================
-
-SUITE_readonly_SETUP() {
-    generate_code 1 test.c
-    generate_code 2 test2.c
-}
-
-SUITE_readonly() {
-    # -------------------------------------------------------------------------
-    TEST "Cache hit"
-
-    # Cache a compilation.
-    $CCACHE_COMPILE -c test.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    rm test.o
-
-    # Make the cache read-only.
-    chmod -R a-w $CCACHE_DIR
-
-    # Check that read-only mode finds the cached result.
-    CCACHE_READONLY=1 CCACHE_TEMPDIR=/tmp CCACHE_PREFIX=false $CCACHE_COMPILE -c test.c
-    status1=$?
-
-    # Check that fallback to the real compiler works for a cache miss.
-    CCACHE_READONLY=1 CCACHE_TEMPDIR=/tmp $CCACHE_COMPILE -c test2.c
-    status2=$?
-
-    # Leave test dir a nice state after test failure.
-    chmod -R +w $CCACHE_DIR
-
-    if [ $status1 -ne 0 ]; then
-        test_failed "Failure when compiling test.c read-only"
-    fi
-    if [ $status2 -ne 0 ]; then
-        test_failed "Failure when compiling test2.c read-only"
-    fi
-    if [ ! -f test.o ]; then
-        test_failed "test.o missing"
-    fi
-    if [ ! -f test2.o ]; then
-        test_failed "test2.o missing"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "Cache miss"
-
-    # Check that read-only mode doesn't try to store new results.
-    CCACHE_READONLY=1 CCACHE_TEMPDIR=/tmp $CCACHE_COMPILE -c test.c
-    if [ $? -ne 0 ]; then
-        test_failed "Failure when compiling test2.c read-only"
-    fi
-    if [ -d $CCACHE_DIR ]; then
-        test_failed "ccache dir was created"
-    fi
-
-    # -------------------------------------------------------------------------
-    # Check that read-only mode and direct mode work together.
-    TEST "Cache hit, direct"
-
-    # Cache a compilation.
-    $CCACHE_COMPILE -c test.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    rm test.o
-
-    # Make the cache read-only.
-    chmod -R a-w $CCACHE_DIR
-
-    # Direct mode should work:
-    files_before=`find $CCACHE_DIR -type f | wc -l`
-    CCACHE_DIRECT=1 CCACHE_READONLY=1 CCACHE_TEMPDIR=/tmp $CCACHE_COMPILE -c test.c
-    files_after=`find $CCACHE_DIR -type f | wc -l`
-
-    # Leave test dir a nice state after test failure.
-    chmod -R +w $CCACHE_DIR
-
-    if [ $? -ne 0 ]; then
-        test_failed "Failure when compiling test.c read-only"
-    fi
-    if [ $files_after -ne $files_before ]; then
-        test_failed "Read-only mode + direct mode stored files in the cache"
-    fi
-}
-
-# =============================================================================
-
-SUITE_readonly_direct_SETUP() {
-    unset CCACHE_NODIRECT
-
-    generate_code 1 test.c
-}
-
-SUITE_readonly_direct() {
-    # -------------------------------------------------------------------------
-    TEST "Direct hit"
-
-    $CCACHE_COMPILE -c test.c -o test.o
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_READONLY_DIRECT=1 $CCACHE_COMPILE -c test.c -o test.o
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Direct miss doesn't lead to preprocessed hit"
-
-    $CCACHE_COMPILE -c test.c -o test.o
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_READONLY_DIRECT=1 $CCACHE_COMPILE -DFOO -c test.c -o test.o
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-}
-
-# =============================================================================
-
-prepare_cleanup_test_dir() {
-    local dir=$1
-
-    rm -rf $dir
-    mkdir -p $dir
-    for i in $(seq 0 9); do
-        printf '%4017s' '' | tr ' ' 'A' >$dir/result$i-4017.o
-        touch $dir/result$i-4017.stderr
-        touch $dir/result$i-4017.d
-        if [ $i -gt 5 ]; then
-            backdate $dir/result$i-4017.stderr
-        fi
-    done
-    # NUMFILES: 30, TOTALSIZE: 40 KiB, MAXFILES: 0, MAXSIZE: 0
-    echo "0 0 0 0 0 0 0 0 0 0 0 30 40 0 0" >$dir/stats
-}
-
-SUITE_cleanup() {
-    # -------------------------------------------------------------------------
-    TEST "Clear cache"
-
-    prepare_cleanup_test_dir $CCACHE_DIR/a
-
-    $CCACHE -C >/dev/null
-    expect_file_count 0 '*.o' $CCACHE_DIR
-    expect_file_count 0 '*.d' $CCACHE_DIR
-    expect_file_count 0 '*.stderr' $CCACHE_DIR
-    expect_stat 'files in cache' 0
-    expect_stat 'cleanups performed' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Forced cache cleanup, no limits"
-
-    prepare_cleanup_test_dir $CCACHE_DIR/a
-
-    $CCACHE -F 0 -M 0 >/dev/null
-    $CCACHE -c >/dev/null
-    expect_file_count 10 '*.o' $CCACHE_DIR
-    expect_file_count 10 '*.d' $CCACHE_DIR
-    expect_file_count 10 '*.stderr' $CCACHE_DIR
-    expect_stat 'files in cache' 30
-    expect_stat 'cleanups performed' 0
-
-    # -------------------------------------------------------------------------
-    TEST "Forced cache cleanup, file limit"
-
-    prepare_cleanup_test_dir $CCACHE_DIR/a
-
-    # No cleanup needed.
-    #
-    # 30 * 16 = 480
-    $CCACHE -F 480 -M 0 >/dev/null
-    $CCACHE -c >/dev/null
-    expect_file_count 10 '*.o' $CCACHE_DIR
-    expect_file_count 10 '*.d' $CCACHE_DIR
-    expect_file_count 10 '*.stderr' $CCACHE_DIR
-    expect_stat 'files in cache' 30
-    expect_stat 'cleanups performed' 0
-
-    # Reduce file limit
-    #
-    # 21 * 16 = 336
-    $CCACHE -F 336 -M 0 >/dev/null
-    $CCACHE -c >/dev/null
-    expect_file_count 7 '*.o' $CCACHE_DIR
-    expect_file_count 7 '*.d' $CCACHE_DIR
-    expect_file_count 7 '*.stderr' $CCACHE_DIR
-    expect_stat 'files in cache' 21
-    expect_stat 'cleanups performed' 1
-    for i in 0 1 2 3 4 5 9; do
-        file=$CCACHE_DIR/a/result$i-4017.o
-        if [ ! -f $file ]; then
-            test_failed "File $file removed when it shouldn't"
-        fi
-    done
-    for i in 6 7 8; do
-        file=$CCACHE_DIR/a/result$i-4017.o
-        if [ -f $file ]; then
-            test_failed "File $file not removed when it should"
-        fi
-    done
-
-    # -------------------------------------------------------------------------
-    TEST "Forced cache cleanup, size limit"
-
-    # NOTE: This test is known to fail on filesystems that have unusual block
-    # sizes, including ecryptfs. The workaround is to place the test directory
-    # elsewhere:
-    #
-    #     cd /tmp
-    #     CCACHE=$DIR/ccache $DIR/test.sh
-
-    prepare_cleanup_test_dir $CCACHE_DIR/a
-
-    $CCACHE -F 0 -M 256K >/dev/null
-    CCACHE_LOGFILE=/tmp/foo $CCACHE -c >/dev/null
-    expect_file_count 3 '*.o' $CCACHE_DIR
-    expect_file_count 3 '*.d' $CCACHE_DIR
-    expect_file_count 3 '*.stderr' $CCACHE_DIR
-    expect_stat 'files in cache' 9
-    expect_stat 'cleanups performed' 1
-    for i in 3 4 5; do
-        file=$CCACHE_DIR/a/result$i-4017.o
-        if [ ! -f $file ]; then
-            test_failed "File $file removed when it shouldn't"
-        fi
-    done
-    for i in 0 1 2 6 7 8 9; do
-        file=$CCACHE_DIR/a/result$i-4017.o
-        if [ -f $file ]; then
-            test_failed "File $file not removed when it should"
-        fi
-    done
-
-    # -------------------------------------------------------------------------
-    TEST "Automatic cache cleanup, limit_multiple 0.9"
-
-    for x in 0 1 2 3 4 5 6 7 8 9 a b c d e f; do
-        prepare_cleanup_test_dir $CCACHE_DIR/$x
-    done
-
-    $CCACHE -F 480 -M 0 >/dev/null
-
-    expect_file_count 160 '*.o' $CCACHE_DIR
-    expect_file_count 160 '*.d' $CCACHE_DIR
-    expect_file_count 160 '*.stderr' $CCACHE_DIR
-    expect_stat 'files in cache' 480
-    expect_stat 'cleanups performed' 0
-
-    touch empty.c
-    CCACHE_LIMIT_MULTIPLE=0.9 $CCACHE_COMPILE -c empty.c -o empty.o
-    expect_file_count 159 '*.o' $CCACHE_DIR
-    expect_file_count 158 '*.d' $CCACHE_DIR
-    expect_file_count 158 '*.stderr' $CCACHE_DIR
-    expect_stat 'files in cache' 475
-    expect_stat 'cleanups performed' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Automatic cache cleanup, limit_multiple 0.7"
-
-    for x in 0 1 2 3 4 5 6 7 8 9 a b c d e f; do
-        prepare_cleanup_test_dir $CCACHE_DIR/$x
-    done
-
-    $CCACHE -F 480 -M 0 >/dev/null
-
-    expect_file_count 160 '*.o' $CCACHE_DIR
-    expect_file_count 160 '*.d' $CCACHE_DIR
-    expect_file_count 160 '*.stderr' $CCACHE_DIR
-    expect_stat 'files in cache' 480
-    expect_stat 'cleanups performed' 0
-
-    touch empty.c
-    CCACHE_LIMIT_MULTIPLE=0.7 $CCACHE_COMPILE -c empty.c -o empty.o
-    expect_file_count 157 '*.o' $CCACHE_DIR
-    expect_file_count 156 '*.d' $CCACHE_DIR
-    expect_file_count 156 '*.stderr' $CCACHE_DIR
-    expect_stat 'files in cache' 469
-    expect_stat 'cleanups performed' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Cleanup of sibling files"
-
-    prepare_cleanup_test_dir $CCACHE_DIR/a
-
-    $CCACHE -F 336 -M 0 >/dev/null
-    backdate $CCACHE_DIR/a/result2-4017.stderr
-    $CCACHE -c >/dev/null
-    # floor(0.8 * 9) = 7
-    expect_file_count 7 '*.o' $CCACHE_DIR
-    expect_file_count 7 '*.d' $CCACHE_DIR
-    expect_file_count 7 '*.stderr' $CCACHE_DIR
-    expect_stat 'files in cache' 21
-    for i in 0 1 3 4 5 8 9; do
-        file=$CCACHE_DIR/a/result$i-4017.o
-        if [ ! -f $file ]; then
-            test_failed "File $file removed when it shouldn't"
-        fi
-    done
-    for i in 2 6 7; do
-        file=$CCACHE_DIR/a/result$i-4017.o
-        if [ -f $file ]; then
-            test_failed "File $file not removed when it should"
-        fi
-    done
-
-    # -------------------------------------------------------------------------
-    TEST "No cleanup of new unknown file"
-
-    prepare_cleanup_test_dir $CCACHE_DIR/a
-
-    touch $CCACHE_DIR/a/abcd.unknown
-    $CCACHE -F 0 -M 0 -c >/dev/null # update counters
-    expect_stat 'files in cache' 31
-
-    $CCACHE -F 480 -M 0 >/dev/null
-    $CCACHE -c >/dev/null
-    if [ ! -f $CCACHE_DIR/a/abcd.unknown ]; then
-        test_failed "$CCACHE_DIR/a/abcd.unknown removed"
-    fi
-    expect_stat 'files in cache' 28
-
-    # -------------------------------------------------------------------------
-    TEST "Cleanup of old unknown file"
-
-    prepare_cleanup_test_dir $CCACHE_DIR/a
-    $CCACHE -F 480 -M 0 >/dev/null
-    touch $CCACHE_DIR/a/abcd.unknown
-    backdate $CCACHE_DIR/a/abcd.unknown
-    $CCACHE -F 0 -M 0 -c >/dev/null # update counters
-    expect_stat 'files in cache' 31
-
-    $CCACHE -F 480 -M 0 -c >/dev/null
-    if [ -f $CCACHE_DIR/a/abcd.unknown ]; then
-        test_failed "$CCACHE_DIR/a/abcd.unknown not removed"
-    fi
-    expect_stat 'files in cache' 30
-
-    # -------------------------------------------------------------------------
-    TEST "Cleanup of tmp file"
-
-    mkdir -p $CCACHE_DIR/a
-    touch $CCACHE_DIR/a/abcd.tmp.efgh
-    $CCACHE -c >/dev/null # update counters
-    expect_stat 'files in cache' 1
-    backdate $CCACHE_DIR/a/abcd.tmp.efgh
-    $CCACHE -c >/dev/null
-    if [ -f $CCACHE_DIR/a/abcd.tmp.efgh ]; then
-        test_failed "$CCACHE_DIR/a/abcd.tmp.unknown not removed"
-    fi
-    expect_stat 'files in cache' 0
-
-    # -------------------------------------------------------------------------
-    TEST "No cleanup of .nfs* files"
-
-    prepare_cleanup_test_dir $CCACHE_DIR/a
-
-    touch $CCACHE_DIR/a/.nfs0123456789
-    $CCACHE -F 0 -M 0 >/dev/null
-    $CCACHE -c >/dev/null
-    expect_file_count 1 '.nfs*' $CCACHE_DIR
-    expect_stat 'files in cache' 30
-}
-
-# =============================================================================
-
-SUITE_pch_PROBE() {
-    touch pch.h
-    if ! $UNCACHED_COMPILE $SYSROOT -fpch-preprocess pch.h 2>/dev/null \
-            || [ ! -f pch.h.gch ]; then
-        echo "compiler ($($COMPILER --version | head -1)) doesn't support precompiled headers"
-    fi
-}
-
-SUITE_pch_SETUP() {
-    unset CCACHE_NODIRECT
-
-    cat <<EOF >pch.c
-#include "pch.h"
-int main()
-{
-  void *p = NULL;
-  return 0;
-}
-EOF
-    cat <<EOF >pch.h
-#include <stdlib.h>
-EOF
-    backdate pch.h
-    cat <<EOF >pch2.c
-int main()
-{
-  void *p = NULL;
-  return 0;
-}
-EOF
-}
-
-SUITE_pch() {
-    # Clang and GCC handle precompiled headers similarly, but GCC is much more
-    # forgiving with precompiled headers. Both GCC and Clang keep an absolute
-    # path reference to the original file except that Clang uses that reference
-    # to validate the pch and GCC ignores the reference. Also, Clang has an
-    # additional feature: pre-tokenized headers. For these reasons, Clang
-    # should be tested differently from GCC. Clang can only use pch or pth
-    # headers on the command line and not as an #include statement inside a
-    # source file.
-
-    if $COMPILER_TYPE_CLANG; then
-        pch_suite_clang
-    else
-        pch_suite_gcc
-    fi
-}
-
-pch_suite_gcc() {
-    # -------------------------------------------------------------------------
-    TEST "Create .gch, -c, no -o, without opt-in"
-
-    $CCACHE_COMPILE $SYSROOT -c pch.h
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    expect_stat "can't use precompiled header" 1
-
-    # -------------------------------------------------------------------------
-    TEST "Create .gch, no -c, -o, without opt-in"
-
-    $CCACHE_COMPILE pch.h -o pch.gch
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    expect_stat "can't use precompiled header" 1
-
-    # -------------------------------------------------------------------------
-    TEST "Create .gch, -c, no -o, with opt-in"
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines" $CCACHE_COMPILE $SYSROOT -c pch.h
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    rm pch.h.gch
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines" $CCACHE_COMPILE $SYSROOT -c pch.h
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    if [ ! -f pch.h.gch ]; then
-        test_failed "pch.h.gch missing"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "Create .gch, no -c, -o, with opt-in"
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT pch.h -o pch.gch
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT pch.h -o pch.gch
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    if [ ! -f pch.gch ]; then
-        test_failed "pch.gch missing"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, no -fpch-preprocess, #include"
-
-    $UNCACHED_COMPILE $SYSROOT -c pch.h
-    backdate pch.h.gch
-    rm pch.h
-
-    $CCACHE_COMPILE $SYSROOT -c pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    # Preprocessor error because GCC can't find the real include file when
-    # trying to preprocess:
-    expect_stat 'preprocessor error' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, no -fpch-preprocess, -include, no sloppiness"
-
-    $UNCACHED_COMPILE $SYSROOT -c pch.h
-    backdate pch.h.gch
-    rm pch.h
-
-    $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    # Must enable sloppy time macros:
-    expect_stat "can't use precompiled header" 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, no -fpch-preprocess, -include, sloppiness"
-
-    $UNCACHED_COMPILE $SYSROOT -c pch.h
-    backdate pch.h.gch
-    rm pch.h
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, -fpch-preprocess, #include, no sloppiness"
-
-    $UNCACHED_COMPILE $SYSROOT -c pch.h
-    backdate pch.h.gch
-    rm pch.h
-
-    $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    # Must enable sloppy time macros:
-    expect_stat "can't use precompiled header" 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, -fpch-preprocess, #include, sloppiness"
-
-    $UNCACHED_COMPILE $SYSROOT -c pch.h
-    backdate pch.h.gch
-    rm pch.h
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, -fpch-preprocess, #include, file changed"
-
-    $UNCACHED_COMPILE $SYSROOT -c pch.h
-    backdate pch.h.gch
-    rm pch.h
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    echo "updated" >>pch.h.gch # GCC seems to cope with this...
-    backdate pch.h.gch
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 2
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, preprocessor mode"
-
-    $UNCACHED_COMPILE $SYSROOT -c pch.h
-    backdate pch.h.gch
-    rm pch.h
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, preprocessor mode, file changed"
-
-    $UNCACHED_COMPILE $SYSROOT -c pch.h
-    backdate pch.h.gch
-    rm pch.h
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    echo "updated" >>pch.h.gch # GCC seems to cope with this...
-    backdate pch.h.gch
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 2
-}
-
-pch_suite_clang() {
-    # -------------------------------------------------------------------------
-    TEST "Create .gch, -c, no -o, without opt-in"
-
-    $CCACHE_COMPILE $SYSROOT -c pch.h
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    expect_stat "can't use precompiled header" 1
-
-    # -------------------------------------------------------------------------
-    TEST "Create .gch, no -c, -o, without opt-in"
-
-    $CCACHE_COMPILE pch.h -o pch.gch
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    expect_stat "can't use precompiled header" 1
-
-    # -------------------------------------------------------------------------
-    TEST "Create .gch, -c, no -o, with opt-in"
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch.h
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    rm pch.h.gch
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch.h
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    if [ ! -f pch.h.gch ]; then
-        test_failed "pch.h.gch missing"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "Create .gch, no -c, -o, with opt-in"
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT pch.h -o pch.gch
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT pch.h -o pch.gch
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    if [ ! -f pch.gch ]; then
-        test_failed "pch.gch missing"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "Create .gch, include file mtime changed"
-
-    backdate test.h
-    cat <<EOF >pch2.h
-    #include <stdlib.h>
-    #include "test.h"
-EOF
-
-    # Make sure time_of_compilation is at least one second larger than the ctime
-    # of the test.h include, otherwise we might not cache its ctime/mtime.
-    sleep 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch2.h
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    touch test.h
-    sleep 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch2.h
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    $UNCACHED_COMPILE $SYSROOT -c -include pch2.h pch2.c
-    if [ ! -f pch2.o ]; then
-        test_failed "pch.o missing"
-    fi
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch2.h
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, no -fpch-preprocess, -include, no sloppiness"
-
-    $UNCACHED_COMPILE $SYSROOT -c pch.h
-    backdate pch.h.gch
-
-    $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c 2>/dev/null
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    # Must enable sloppy time macros:
-    expect_stat "can't use precompiled header" 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, no -fpch-preprocess, -include, sloppiness"
-
-    $UNCACHED_COMPILE $SYSROOT -c pch.h
-    backdate pch.h.gch
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, -fpch-preprocess, -include, file changed"
-
-    $UNCACHED_COMPILE $SYSROOT -c pch.h
-    backdate pch.h.gch
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    echo "updated" >>pch.h.gch # clang seems to cope with this...
-    backdate pch.h.gch
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, preprocessor mode"
-
-    $UNCACHED_COMPILE $SYSROOT -c pch.h
-    backdate pch.h.gch
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, preprocessor mode, file changed"
-
-    $UNCACHED_COMPILE $SYSROOT -c pch.h
-    backdate pch.h.gch
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    echo "updated" >>pch.h.gch # clang seems to cope with this...
-    backdate pch.h.gch
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "Create .pth, -c, -o"
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch.h -o pch.h.pth
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    rm -f pch.h.pth
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch.h -o pch.h.pth
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    if [ ! -f pch.h.pth ]; then
-        test_failed "pch.h.pth missing"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "Use .pth, no -fpch-preprocess, -include, no sloppiness"
-
-    $UNCACHED_COMPILE $SYSROOT -c pch.h -o pch.h.pth
-    backdate pch.h.pth
-
-    $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    # Must enable sloppy time macros:
-    expect_stat "can't use precompiled header" 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .pth, no -fpch-preprocess, -include, sloppiness"
-
-    $UNCACHED_COMPILE $SYSROOT -c pch.h -o pch.h.pth
-    backdate pch.h.pth
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .pth, -fpch-preprocess, -include, file changed"
-
-    $UNCACHED_COMPILE $SYSROOT -c pch.h -o pch.h.pth
-    backdate pch.h.pth
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    echo "updated" >>pch.h.pth # clang seems to cope with this...
-    backdate pch.h.pth
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "Use .pth, preprocessor mode"
-
-    $UNCACHED_COMPILE $SYSROOT -c pch.h -o pch.h.pth
-    backdate pch.h.pth
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .pth, preprocessor mode, file changed"
-
-    $UNCACHED_COMPILE $SYSROOT -c pch.h -o pch.h.pth
-    backdate pch.h.pth
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    echo "updated" >>pch.h.pth # clang seems to cope with this...
-    backdate pch.h.pth
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 2
-}
-
-# =============================================================================
-
-SUITE_upgrade() {
-    TEST "Keep maxfiles and maxsize settings"
-
-    rm $CCACHE_CONFIGPATH
-    mkdir -p $CCACHE_DIR/0
-    echo "0 0 0 0 0 0 0 0 0 0 0 0 0 2000 131072" >$CCACHE_DIR/0/stats
-    expect_stat 'max files' 32000
-    expect_stat 'max cache size' '2.1 GB'
-}
-
-# =============================================================================
-
-SUITE_input_charset_PROBE() {
-    touch test.c
-    if ! $UNCACHED_COMPILE -c -finput-charset=latin1 test.c >/dev/null 2>&1; then
-        echo "compiler doesn't support -finput-charset"
-    fi
-}
-
-SUITE_input_charset() {
-    # -------------------------------------------------------------------------
-    TEST "-finput-charset"
-
-    printf '#include <wchar.h>\nwchar_t foo[] = L"\xbf";\n' >latin1.c
-
-    $CCACHE_COMPILE -c -finput-charset=latin1 latin1.c
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    $CCACHE_COMPILE -c -finput-charset=latin1 latin1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    CCACHE_NOCPP2=1 $CCACHE_COMPILE -c -finput-charset=latin1 latin1.c
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 2
-
-    CCACHE_NOCPP2=1 $CCACHE_COMPILE -c -finput-charset=latin1 latin1.c
-    expect_stat 'cache hit (preprocessed)' 2
-    expect_stat 'cache miss' 2
-}
-
-# =============================================================================
-# main program
-
-if pwd | grep '[^A-Za-z0-9/.,=_%+-]' >/dev/null 2>&1; then
-    cat <<EOF
-Error: The test suite doesn't work in directories with whitespace or other
-funny characters in the name. Sorry.
-EOF
-    exit 1
-fi
-
-if [ -n "$CC" ]; then
-    COMPILER="$CC"
-else
-    COMPILER=gcc
-fi
-if [ -z "$CCACHE" ]; then
-    CCACHE=`pwd`/ccache
-fi
-
-COMPILER_TYPE_CLANG=false
-COMPILER_TYPE_GCC=false
-
-COMPILER_USES_LLVM=false
-COMPILER_USES_MINGW=false
-
-HOST_OS_APPLE=false
-HOST_OS_LINUX=false
-HOST_OS_WINDOWS=false
-
-compiler_version="`$COMPILER --version 2>&1 | head -1`"
-case $compiler_version in
-    *gcc*|*g++*|2.95*)
-        COMPILER_TYPE_GCC=true
-        ;;
-    *clang*)
-        COMPILER_TYPE_CLANG=true
-        ;;
-    *)
-        echo "WARNING: Compiler $COMPILER not supported (version: $compiler_version) -- not running tests" >&2
-        exit 0
-        ;;
-esac
-
-case $compiler_version in
-    *llvm*|*LLVM*)
-        COMPILER_USES_LLVM=true
-        ;;
-    *MINGW*|*mingw*)
-        COMPILER_USES_MINGW=true
-        ;;
-esac
-
-case $(uname -s) in
-    *MINGW*|*mingw*)
-        HOST_OS_WINDOWS=true
-        ;;
-    *Darwin*)
-        HOST_OS_APPLE=true
-        ;;
-    *Linux*)
-        HOST_OS_LINUX=true
-        ;;
-esac
-
-if $HOST_OS_WINDOWS; then
-    PATH_DELIM=";"
-else
-    PATH_DELIM=":"
-fi
-
-if $HOST_OS_APPLE; then
-    # Grab the developer directory from the environment or try xcode-select
-    if [ "$XCODE_DEVELOPER_DIR" = "" ]; then
-      XCODE_DEVELOPER_DIR=`xcode-select --print-path`
-      if [ "$XCODE_DEVELOPER_DIR" = "" ]; then
-        echo "Error: XCODE_DEVELOPER_DIR environment variable not set and xcode-select path not set"
-        exit 1
-      fi
-    fi
-
-    # Choose the latest SDK if an SDK root is not set
-    MAC_PLATFORM_DIR=$XCODE_DEVELOPER_DIR/Platforms/MacOSX.platform
-    if [ "$SDKROOT" = "" ]; then
-        SDKROOT="`eval ls -f -1 -d \"$MAC_PLATFORM_DIR/Developer/SDKs/\"*.sdk | tail -1`"
-        if [ "$SDKROOT" = "" ]; then
-            echo "Error: Cannot find a valid SDK root directory"
-            exit 1
-        fi
-    fi
-
-    SYSROOT="-isysroot `echo \"$SDKROOT\" | sed 's/ /\\ /g'`"
-else
-    SYSROOT=
-fi
-
-# ---------------------------------------
-
-TESTDIR=testdir.$$
-ABS_TESTDIR=$PWD/$TESTDIR
-rm -rf $TESTDIR
-mkdir $TESTDIR
-cd $TESTDIR || exit 1
-
-# ---------------------------------------
-
-all_suites="
-base
-nocpp2
-multi_arch
-serialize_diagnostics
-debug_prefix_map
-masquerading
-hardlink
-direct
-basedir
-compression
-readonly
-readonly_direct
-cleanup
-pch
-upgrade
-input_charset
-"
-
-compiler_location=$(which $(echo "$COMPILER" | awk '{print $1}'))
-if [ "$compiler_location" = "$COMPILER" ]; then
-    echo "Compiler:         $COMPILER"
-else
-    echo "Compiler:         $COMPILER ($compiler_location)"
-fi
-echo "Compiler version: $($COMPILER --version | head -n 1)"
-echo
-
-VERBOSE=false
-[ "$1" = "-v" ] && { VERBOSE=true; shift; }
-
-suites="$*"
-if [ -z "$suites" ]; then
-    suites="$all_suites"
-fi
-
-for suite in $suites; do
-    run_suite $suite
-done
-
-cd /
-rm -rf $ABS_TESTDIR
-green PASSED
-exit 0
diff --git a/test/run b/test/run
new file mode 100755 (executable)
index 0000000..f33237b
--- /dev/null
+++ b/test/run
@@ -0,0 +1,415 @@
+#!/bin/bash
+#
+# A simple test suite for ccache.
+#
+# Copyright (C) 2002-2007 Andrew Tridgell
+# Copyright (C) 2009-2018 Joel Rosdahl
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3 of the License, or (at your option) any later
+# version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+green() {
+    printf "\033[1;32m$*\033[0;0m\n"
+}
+
+red() {
+    printf "\033[1;31m$*\033[0;0m\n"
+}
+
+bold() {
+    printf "\033[1;37m$*\033[0;0m\n"
+}
+
+test_failed() {
+    echo
+    red FAILED
+    echo
+    echo "Test suite:     $(bold $CURRENT_SUITE)"
+    echo "Test case:      $(bold $CURRENT_TEST)"
+    echo "Failure reason: $(red "$1")"
+    echo
+    echo "ccache -s:"
+    $CCACHE -s
+    echo
+    echo "Test data and log file have been left in $TESTDIR"
+    exit 1
+}
+
+find_compiler() {
+    local name=$1
+    perl -e '
+        use File::Basename;
+        my $cc = $ARGV[0];
+        $cc = basename($cc) if readlink($cc) =~ "ccache";
+        if ($cc =~ m!^/!) {
+            print $cc;
+            exit;
+        }
+        foreach my $dir (split(/:/, $ENV{PATH})) {
+            $path = "$dir/$cc";
+            if (-x $path && readlink($path) !~ "ccache") {
+                print $path;
+                exit;
+            }
+        }' $name
+}
+
+generate_code() {
+    local nlines=$1
+    local outfile=$2
+
+    rm -f $outfile
+    for i in $(seq $nlines); do
+        echo "int foo_$i(int x) { return x; }" >>$outfile
+    done
+}
+
+remove_cache() {
+    if [ -d $CCACHE_DIR ]; then
+        chmod -R +w $CCACHE_DIR
+        rm -rf $CCACHE_DIR
+    fi
+}
+
+clear_cache() {
+    $CCACHE -Cz >/dev/null
+}
+
+sed_in_place() {
+    local expr=$1
+    shift
+
+    for file in $*; do
+        sed "$expr" $file >$file.sed
+        mv $file.sed $file
+    done
+}
+
+backdate() {
+    touch -t 199901010000 "$@"
+}
+
+expect_stat() {
+    local stat="$1"
+    local expected_value="$2"
+    local value="$(echo $($CCACHE -s | fgrep "$stat" | cut -c34-))"
+
+    if [ "$expected_value" != "$value" ]; then
+        test_failed "Expected \"$stat\" to be $expected_value, actual $value"
+    fi
+}
+
+expect_equal_files() {
+    if [ ! -e "$1" ]; then
+        test_failed "compare_files: $1 missing"
+    fi
+    if [ ! -e "$2" ]; then
+        test_failed "compare_files: $2 missing"
+    fi
+    if ! cmp -s "$1" "$2"; then
+        test_failed "compare_files: $1 and $2 differ"
+    fi
+}
+
+expect_different_files() {
+    if [ ! -e "$1" ]; then
+        test_failed "compare_files: $1 missing"
+    fi
+    if [ ! -e "$2" ]; then
+        test_failed "compare_files: $2 missing"
+    fi
+    if cmp -s "$1" "$2"; then
+        test_failed "compare_files: $1 and $2 are identical"
+    fi
+}
+
+expect_equal_object_files() {
+    if $HOST_OS_LINUX && $COMPILER_TYPE_CLANG; then
+        if ! which eu-elfcmp >/dev/null 2>&1; then
+            test_failed "Please install elfutils to get eu-elfcmp"
+        fi
+        eu-elfcmp -q "$1" "$2"
+    else
+        cmp -s "$1" "$2"
+    fi
+    if [ $? -ne 0 ]; then
+        test_failed "Objects differ: $1 != $2"
+    fi
+}
+
+expect_file_content() {
+    local file="$1"
+    local content="$2"
+
+    if [ ! -f "$file" ]; then
+        test_failed "$file not found"
+    fi
+    if [ "$(cat $file)" != "$content" ]; then
+        test_failed "Bad content of $file.\nExpected: $content\nActual: $(cat $file)"
+    fi
+}
+
+expect_file_count() {
+    local expected=$1
+    local pattern=$2
+    local dir=$3
+    local actual=`find $dir -name "$pattern" | wc -l`
+    if [ $actual -ne $expected ]; then
+        test_failed "Found $actual (expected $expected) $pattern files in $dir"
+    fi
+}
+
+run_suite() {
+    local suite_name=$1
+
+    CURRENT_SUITE=$suite_name
+
+    cd $ABS_TESTDIR
+    rm -rf $ABS_TESTDIR/fixture
+
+    if type SUITE_${suite_name}_PROBE >/dev/null 2>&1; then
+        mkdir $ABS_TESTDIR/probe
+        cd $ABS_TESTDIR/probe
+        local skip_reason="$(SUITE_${suite_name}_PROBE)"
+        cd $ABS_TESTDIR
+        rm -rf $ABS_TESTDIR/probe
+        if [ -n "$skip_reason" ]; then
+            echo "Skipped test suite $suite_name [$skip_reason]"
+            return
+        fi
+    fi
+
+    printf "Running test suite %s" "$(bold $suite_name)"
+    SUITE_$suite_name
+    echo
+}
+
+TEST() {
+    CURRENT_TEST=$1
+
+    while read name; do
+        unset $name
+    done <<EOF
+$(env | sed -n 's/^\(CCACHE_[A-Z0-9_]*\)=.*$/\1/p')
+EOF
+    unset GCC_COLORS
+
+    export CCACHE_CONFIGPATH=$ABS_TESTDIR/ccache.conf
+    export CCACHE_DETECT_SHEBANG=1
+    export CCACHE_DIR=$ABS_TESTDIR/.ccache
+    export CCACHE_LOGFILE=$ABS_TESTDIR/ccache.log
+    export CCACHE_NODIRECT=1
+
+    # Many tests backdate files, which updates their ctimes. In those tests, we
+    # must ignore ctimes. Might as well do so everywhere.
+    DEFAULT_SLOPPINESS=include_file_ctime
+    export CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS"
+
+    CCACHE_COMPILE="$CCACHE $COMPILER"
+
+    if $VERBOSE; then
+        printf "\n  %s" "$CURRENT_TEST"
+    else
+        printf .
+    fi
+
+    cd /
+    remove_cache
+    rm -rf $ABS_TESTDIR/run
+    mkdir $ABS_TESTDIR/run
+    cd $ABS_TESTDIR/run
+    if type SUITE_${suite_name}_SETUP >/dev/null 2>&1; then
+        SUITE_${suite_name}_SETUP
+    fi
+}
+
+# =============================================================================
+# main program
+
+if pwd | grep '[^A-Za-z0-9/.,=_%+-]' >/dev/null 2>&1; then
+    cat <<EOF
+Error: The test suite doesn't work in directories with whitespace or other
+funny characters in the name. Sorry.
+EOF
+    exit 1
+fi
+
+# Remove common ccache directories on host from PATH variable
+HOST_CCACHE_DIRS="/usr/lib/ccache/bin
+/usr/lib/ccache"
+for HOST_CCACHE_DIR in $HOST_CCACHE_DIRS; do
+    PATH=$(echo -n $PATH | awk -v RS=: -v ORS=: '$0 != "'$HOST_CCACHE_DIR'"' | sed 's/:$//')
+done
+export PATH
+
+if [ -n "$CC" ]; then
+    COMPILER="$CC"
+else
+    COMPILER=gcc
+fi
+if [ -z "$CCACHE" ]; then
+    CCACHE=`pwd`/ccache
+fi
+
+COMPILER_TYPE_CLANG=false
+COMPILER_TYPE_GCC=false
+
+COMPILER_USES_LLVM=false
+COMPILER_USES_MINGW=false
+
+HOST_OS_APPLE=false
+HOST_OS_LINUX=false
+HOST_OS_WINDOWS=false
+
+compiler_version="`$COMPILER --version 2>&1 | head -1`"
+case $compiler_version in
+    *gcc*|*g++*|2.95*)
+        COMPILER_TYPE_GCC=true
+        ;;
+    *clang*)
+        COMPILER_TYPE_CLANG=true
+        ;;
+    *)
+        echo "WARNING: Compiler $COMPILER not supported (version: $compiler_version) -- not running tests" >&2
+        exit 0
+        ;;
+esac
+
+case $compiler_version in
+    *llvm*|*LLVM*)
+        COMPILER_USES_LLVM=true
+        ;;
+    *MINGW*|*mingw*)
+        COMPILER_USES_MINGW=true
+        ;;
+esac
+
+case $(uname -s) in
+    *MINGW*|*mingw*)
+        HOST_OS_WINDOWS=true
+        ;;
+    *Darwin*)
+        HOST_OS_APPLE=true
+        ;;
+    *Linux*)
+        HOST_OS_LINUX=true
+        ;;
+esac
+
+if $HOST_OS_WINDOWS; then
+    PATH_DELIM=";"
+else
+    PATH_DELIM=":"
+fi
+
+if $HOST_OS_APPLE; then
+    # Grab the developer directory from the environment or try xcode-select
+    if [ "$XCODE_DEVELOPER_DIR" = "" ]; then
+      XCODE_DEVELOPER_DIR=`xcode-select --print-path`
+      if [ "$XCODE_DEVELOPER_DIR" = "" ]; then
+        echo "Error: XCODE_DEVELOPER_DIR environment variable not set and xcode-select path not set"
+        exit 1
+      fi
+    fi
+
+    # Choose the latest SDK if an SDK root is not set
+    MAC_PLATFORM_DIR=$XCODE_DEVELOPER_DIR/Platforms/MacOSX.platform
+    if [ "$SDKROOT" = "" ]; then
+        SDKROOT="`eval ls -f -1 -d \"$MAC_PLATFORM_DIR/Developer/SDKs/\"*.sdk | tail -1`"
+        if [ "$SDKROOT" = "" ]; then
+            echo "Error: Cannot find a valid SDK root directory"
+            exit 1
+        fi
+    fi
+
+    SYSROOT="-isysroot `echo \"$SDKROOT\" | sed 's/ /\\ /g'`"
+else
+    SYSROOT=
+fi
+
+# ---------------------------------------
+
+all_suites="
+base
+nocpp2
+cpp1
+multi_arch
+serialize_diagnostics
+debug_prefix_map
+masquerading
+hardlink
+direct
+basedir
+compression
+readonly
+readonly_direct
+cleanup
+pch
+upgrade
+input_charset
+nvcc
+nvcc_direct
+nvcc_ldir
+nvcc_nocpp2
+"
+
+for suite in $all_suites; do
+    . $(dirname $0)/suites/$suite.bash
+done
+
+# ---------------------------------------
+
+TESTDIR=testdir.$$
+ABS_TESTDIR=$PWD/$TESTDIR
+rm -rf $TESTDIR
+mkdir $TESTDIR
+cd $TESTDIR || exit 1
+
+compiler_bin=$(echo $COMPILER | awk '{print $1}')
+compiler_args=$(echo $COMPILER | awk '{$1 = ""; print}')
+REAL_COMPILER_BIN=$(find_compiler $compiler_bin)
+REAL_COMPILER="$REAL_COMPILER_BIN$compiler_args"
+
+if [ "$REAL_COMPILER" = "$COMPILER" ]; then
+    echo "Compiler:         $COMPILER"
+else
+    echo "Compiler:         $COMPILER ($REAL_COMPILER)"
+fi
+echo "Compiler version: $($COMPILER --version | head -n 1)"
+
+REAL_NVCC=$(find_compiler nvcc)
+REAL_CUOBJDUMP=$(find_compiler cuobjdump)
+if [ -n "$REAL_NVCC" ]; then
+    echo "CUDA compiler:    $($REAL_NVCC --version | tail -n 1) ($REAL_NVCC)"
+else
+    echo "CUDA compiler:    not available"
+fi
+echo
+
+VERBOSE=false
+[ "$1" = "-v" ] && { VERBOSE=true; shift; }
+
+suites="$*"
+if [ -z "$suites" ]; then
+    suites="$all_suites"
+fi
+
+for suite in $suites; do
+    run_suite $suite
+done
+
+cd /
+rm -rf $ABS_TESTDIR
+green PASSED
+exit 0
diff --git a/test/suites/base.bash b/test/suites/base.bash
new file mode 100644 (file)
index 0000000..5ff9ab4
--- /dev/null
@@ -0,0 +1,936 @@
+base_tests() {
+    # -------------------------------------------------------------------------
+    TEST "Base case"
+
+    $REAL_COMPILER -c -o reference_test1.o test1.c
+
+    $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_object_files reference_test1.o test1.o
+
+    $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_object_files reference_test1.o test1.o
+
+    # -------------------------------------------------------------------------
+    TEST "Debug option"
+
+    $CCACHE_COMPILE -c test1.c -g
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+
+    $CCACHE_COMPILE -c test1.c -g
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    $REAL_COMPILER -c -o reference_test1.o test1.c -g
+    expect_equal_object_files reference_test1.o reference_test1.o
+
+    # -------------------------------------------------------------------------
+    TEST "Output option"
+
+    $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -c test1.c -o foo.o
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    $REAL_COMPILER -c -o reference_test1.o test1.c
+    expect_equal_object_files reference_test1.o foo.o
+
+    # -------------------------------------------------------------------------
+    TEST "Output option without space"
+
+    $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -c test1.c -odir
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -c test1.c -optf
+    expect_stat 'cache hit (preprocessed)' 2
+    expect_stat 'cache miss' 1
+
+    $REAL_COMPILER -c -o reference_test1.o test1.c
+    expect_equal_object_files reference_test1.o dir
+    expect_equal_object_files reference_test1.o ptf
+
+    # -------------------------------------------------------------------------
+    TEST "Called for link"
+
+    $CCACHE_COMPILE test1.c -o test 2>/dev/null
+    expect_stat 'called for link' 1
+
+    $CCACHE_COMPILE -c test1.c
+    $CCACHE_COMPILE test1.o -o test 2>/dev/null
+    expect_stat 'called for link' 2
+
+    # -------------------------------------------------------------------------
+    TEST "No input file"
+
+    $CCACHE_COMPILE -c foo.c 2>/dev/null
+    expect_stat 'no input file' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Called for preprocessing"
+
+    $CCACHE_COMPILE -E -c test1.c >/dev/null 2>&1
+    expect_stat 'called for preprocessing' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Multiple source files"
+
+    touch test2.c
+    $CCACHE_COMPILE -c test1.c test2.c
+    expect_stat 'multiple source files' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Couldn't find the compiler"
+
+    $CCACHE blahblah -c test1.c 2>/dev/null
+    expect_stat "couldn't find the compiler" 1
+
+    # -------------------------------------------------------------------------
+    TEST "Bad compiler arguments"
+
+    $CCACHE_COMPILE -c test1.c -I 2>/dev/null
+    expect_stat 'bad compiler arguments' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Unsupported source language"
+
+    ln -f test1.c test1.ccc
+    $CCACHE_COMPILE -c test1.ccc 2>/dev/null
+    expect_stat 'unsupported source language' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Unsupported compiler option"
+
+    $CCACHE_COMPILE -M foo -c test1.c >/dev/null 2>&1
+    expect_stat 'unsupported compiler option' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Compiler produced stdout"
+
+    $CCACHE echo foo -c test1.c >/dev/null
+    expect_stat 'compiler produced stdout' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Output to a non-regular file"
+
+    mkdir testd
+    $CCACHE_COMPILE -o testd -c test1.c >/dev/null 2>&1
+    rmdir testd >/dev/null 2>&1
+    expect_stat 'output to a non-regular file' 1
+
+    # -------------------------------------------------------------------------
+    TEST "No input file"
+
+    $CCACHE_COMPILE -c -O2 2>/dev/null
+    expect_stat 'no input file' 1
+
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_DISABLE"
+
+    CCACHE_DISABLE=1 $CCACHE_COMPILE -c test1.c 2>/dev/null
+    if [ -d $CCACHE_DIR ]; then
+        test_failed "$CCACHE_DIR created despite CCACHE_DISABLE being set"
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_COMMENTS"
+
+    $REAL_COMPILER -c -o reference_test1.o test1.c
+
+    mv test1.c test1-saved.c
+    echo '// initial comment' >test1.c
+    cat test1-saved.c >>test1.c
+    CCACHE_COMMENTS=1 $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    echo '// different comment' >test1.c
+    cat test1-saved.c >>test1.c
+    CCACHE_COMMENTS=1 $CCACHE_COMPILE -c test1.c
+    mv test1-saved.c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    $REAL_COMPILER -c -o reference_test1.o test1.c
+    expect_equal_object_files reference_test1.o test1.o
+
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_NOSTATS"
+
+    CCACHE_NOSTATS=1 $CCACHE_COMPILE -c test1.c -O -O
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 0
+
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_RECACHE"
+
+    $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_RECACHE=1 $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    $REAL_COMPILER -c -o reference_test1.o test1.c
+    expect_equal_object_files reference_test1.o test1.o
+
+    expect_stat 'files in cache' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Directory is hashed if using -g"
+
+    mkdir dir1 dir2
+    cp test1.c dir1
+    cp test1.c dir2
+
+    cd dir1
+    $CCACHE_COMPILE -c test1.c -g
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    $CCACHE_COMPILE -c test1.c -g
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    cd ../dir2
+    $CCACHE_COMPILE -c test1.c -g
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 2
+    $CCACHE_COMPILE -c test1.c -g
+    expect_stat 'cache hit (preprocessed)' 2
+    expect_stat 'cache miss' 2
+
+    # -------------------------------------------------------------------------
+    TEST "Directory is not hashed if not using -g"
+
+    mkdir dir1 dir2
+    cp test1.c dir1
+    cp test1.c dir2
+
+    cd dir1
+    $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    cd ../dir2
+    $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 2
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_NOHASHDIR"
+
+    mkdir dir1 dir2
+    cp test1.c dir1
+    cp test1.c dir2
+
+    cd dir1
+    CCACHE_NOHASHDIR=1 $CCACHE_COMPILE -c test1.c -g
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    CCACHE_NOHASHDIR=1 $CCACHE_COMPILE -c test1.c -g
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    cd ../dir2
+    CCACHE_NOHASHDIR=1 $CCACHE_COMPILE -c test1.c -g
+    expect_stat 'cache hit (preprocessed)' 2
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_UNIFY"
+
+    echo '// a silly comment' >>test1.c
+    CCACHE_UNIFY=1 $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    echo '// another silly comment' >>test1.c
+    CCACHE_UNIFY=1 $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    $REAL_COMPILER -c -o reference_test1.o test1.c
+    expect_equal_object_files reference_test1.o test1.o
+
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_NLEVELS"
+
+    CCACHE_NLEVELS=4 $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+
+    CCACHE_NLEVELS=4 $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+
+    # Directories in $CCACHE_DIR:
+    # - .
+    # - tmp
+    # - a
+    # - a/b
+    # - a/b/c
+    # - a/b/c/d
+    actual_dirs=$(find $CCACHE_DIR -type d | wc -l)
+    expected_dirs=6
+    if [ $actual_dirs -ne $expected_dirs ]; then
+        test_failed "Expected $expected_dirs directories, found $actual_dirs"
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_EXTRAFILES"
+
+    echo a >a
+    echo b >b
+
+    $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    CCACHE_EXTRAFILES="a${PATH_DELIM}b" $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 2
+
+    CCACHE_EXTRAFILES="a${PATH_DELIM}b" $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 2
+    expect_stat 'cache miss' 2
+
+    echo b2 >b
+
+    CCACHE_EXTRAFILES="a${PATH_DELIM}b" $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 2
+    expect_stat 'cache miss' 3
+
+    CCACHE_EXTRAFILES="a${PATH_DELIM}b" $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 3
+    expect_stat 'cache miss' 3
+
+    CCACHE_EXTRAFILES="doesntexist" $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 3
+    expect_stat 'cache miss' 3
+    expect_stat 'error hashing extra file' 1
+
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_PREFIX"
+
+    cat <<'EOF' >prefix-a
+#!/bin/sh
+echo a >>prefix.result
+exec "$@"
+EOF
+    cat <<'EOF' >prefix-b
+#!/bin/sh
+echo b >>prefix.result
+exec "$@"
+EOF
+    chmod +x prefix-a prefix-b
+    cat <<'EOF' >file.c
+int foo;
+EOF
+    PATH=.:$PATH CCACHE_PREFIX="prefix-a prefix-b" $CCACHE_COMPILE -c file.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_file_content prefix.result "a
+b"
+
+    PATH=.:$PATH CCACHE_PREFIX="prefix-a prefix-b" $CCACHE_COMPILE -c file.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_file_content prefix.result "a
+b"
+
+    rm -f prefix.result
+    PATH=.:$PATH CCACHE_PREFIX_CPP="prefix-a prefix-b" $CCACHE_COMPILE -c file.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 2
+    expect_stat 'cache miss' 1
+    expect_file_content prefix.result "a
+b"
+
+    # -------------------------------------------------------------------------
+    TEST "Files in cache"
+
+    for i in $(seq 32); do
+        generate_code $i test$i.c
+        $CCACHE_COMPILE -c test$i.c
+    done
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 32
+    expect_stat 'files in cache' 32
+
+    # -------------------------------------------------------------------------
+    TEST "Called for preprocessing"
+
+    $CCACHE_COMPILE -c test1.c -E >test1.i
+    expect_stat 'called for preprocessing' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Direct .i compile"
+
+    $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $REAL_COMPILER -c test1.c -E >test1.i
+    $CCACHE_COMPILE -c test1.i
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "-x c"
+
+    ln -f test1.c test1.ccc
+
+    $CCACHE_COMPILE -x c -c test1.ccc
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -x c -c test1.ccc
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "-xc"
+
+    ln -f test1.c test1.ccc
+
+    $CCACHE_COMPILE -xc -c test1.ccc
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -xc -c test1.ccc
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "-x none"
+
+    $CCACHE_COMPILE -x assembler -x none -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -x assembler -x none -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "-x unknown"
+
+    $CCACHE_COMPILE -x unknown -c test1.c 2>/dev/null
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 0
+    expect_stat 'unsupported source language' 1
+
+    # -------------------------------------------------------------------------
+    TEST "-D not hashed"
+
+    $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -DNOT_AFFECTING=1 -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "-S"
+
+    $CCACHE_COMPILE -S test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -S test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -c test1.s
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 2
+
+    $CCACHE_COMPILE -c test1.s
+    expect_stat 'cache hit (preprocessed)' 2
+    expect_stat 'cache miss' 2
+
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_PATH"
+
+    override_path=`pwd`/override_path
+    mkdir $override_path
+    cat >$override_path/cc <<EOF
+#!/bin/sh
+touch override_path_compiler_executed
+EOF
+    chmod +x $override_path/cc
+    CCACHE_PATH=$override_path $CCACHE cc -c test1.c
+    if [ ! -f override_path_compiler_executed ]; then
+        test_failed "CCACHE_PATH had no effect"
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_COMPILERCHECK=mtime"
+
+    cat >compiler.sh <<EOF
+#!/bin/sh
+export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink...
+exec $COMPILER "\$@"
+# A comment
+EOF
+    chmod +x compiler.sh
+    backdate compiler.sh
+    CCACHE_COMPILERCHECK=mtime $CCACHE ./compiler.sh -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    sed_in_place 's/comment/yoghurt/' compiler.sh # Don't change the size
+    chmod +x compiler.sh
+    backdate compiler.sh # Don't change the timestamp
+
+    CCACHE_COMPILERCHECK=mtime $CCACHE ./compiler.sh -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    touch compiler.sh
+    CCACHE_COMPILERCHECK=mtime $CCACHE ./compiler.sh -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 2
+
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_COMPILERCHECK=content"
+
+    cat >compiler.sh <<EOF
+#!/bin/sh
+export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink...
+exec $COMPILER "\$@"
+EOF
+    chmod +x compiler.sh
+
+    CCACHE_COMPILERCHECK=content $CCACHE ./compiler.sh -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_COMPILERCHECK=content $CCACHE ./compiler.sh -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    echo "# Compiler upgrade" >>compiler.sh
+
+    CCACHE_COMPILERCHECK=content $CCACHE ./compiler.sh -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 2
+
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_COMPILERCHECK=none"
+
+    cat >compiler.sh <<EOF
+#!/bin/sh
+export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink...
+exec $COMPILER "\$@"
+EOF
+    chmod +x compiler.sh
+
+    CCACHE_COMPILERCHECK=none $CCACHE ./compiler.sh -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_COMPILERCHECK=none $CCACHE ./compiler.sh -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    echo "# Compiler upgrade" >>compiler.sh
+    CCACHE_COMPILERCHECK=none $CCACHE ./compiler.sh -c test1.c
+    expect_stat 'cache hit (preprocessed)' 2
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_COMPILERCHECK=string"
+
+    cat >compiler.sh <<EOF
+#!/bin/sh
+export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink...
+exec $COMPILER "\$@"
+EOF
+    chmod +x compiler.sh
+
+    CCACHE_COMPILERCHECK=string:foo $CCACHE ./compiler.sh -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_COMPILERCHECK=string:foo $CCACHE ./compiler.sh -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    CCACHE_COMPILERCHECK=string:bar $CCACHE ./compiler.sh -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 2
+
+    CCACHE_COMPILERCHECK=string:bar $CCACHE ./compiler.sh -c test1.c
+    expect_stat 'cache hit (preprocessed)' 2
+    expect_stat 'cache miss' 2
+
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_COMPILERCHECK=command"
+
+    cat >compiler.sh <<EOF
+#!/bin/sh
+export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink...
+exec $COMPILER "\$@"
+EOF
+    chmod +x compiler.sh
+
+    CCACHE_COMPILERCHECK='echo %compiler%' $CCACHE ./compiler.sh -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    echo "# Compiler upgrade" >>compiler.sh
+    CCACHE_COMPILERCHECK="echo ./compiler.sh" $CCACHE ./compiler.sh -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    cat <<EOF >foobar.sh
+#!/bin/sh
+echo foo
+echo bar
+EOF
+    chmod +x foobar.sh
+    CCACHE_COMPILERCHECK='./foobar.sh' $CCACHE ./compiler.sh -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 2
+
+    CCACHE_COMPILERCHECK='echo foo; echo bar' $CCACHE ./compiler.sh -c test1.c
+    expect_stat 'cache hit (preprocessed)' 2
+    expect_stat 'cache miss' 2
+
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_COMPILERCHECK=unknown_command"
+
+    cat >compiler.sh <<EOF
+#!/bin/sh
+export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink...
+exec $COMPILER "\$@"
+EOF
+    chmod +x compiler.sh
+
+    CCACHE_COMPILERCHECK="unknown_command" $CCACHE ./compiler.sh -c test1.c 2>/dev/null
+    if [ "$?" -eq 0 ]; then
+        test_failed "Expected failure running unknown_command to verify compiler but was success"
+    fi
+    expect_stat 'compiler check failed' 1
+
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_RECACHE should remove previous .stderr"
+
+    $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    num=`find $CCACHE_DIR -name '*.stderr' | wc -l`
+    if [ $num -ne 0 ]; then
+        test_failed "$num stderr files found, expected 0 (#1)"
+    fi
+
+    obj_file=`find $CCACHE_DIR -name '*.o'`
+    stderr_file=`echo $obj_file | sed 's/..$/.stderr/'`
+    echo "Warning: foo" >$stderr_file
+    CCACHE_RECACHE=1 $CCACHE_COMPILE -c test1.c
+    num=`find $CCACHE_DIR -name '*.stderr' | wc -l`
+    if [ $num -ne 0 ]; then
+        test_failed "$num stderr files found, expected 0 (#2)"
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST "No object file"
+
+    cat <<'EOF' >test_no_obj.c
+int test_no_obj;
+EOF
+    cat <<'EOF' >prefix-remove.sh
+#!/bin/sh
+"$@"
+[ x$2 = x-fcolor-diagnostics ] && shift
+[ x$2 = x-fdiagnostics-color ] && shift
+[ x$2 = x-std=gnu99 ] && shift
+[ x$3 = x-o ] && rm $4
+EOF
+    chmod +x prefix-remove.sh
+    CCACHE_PREFIX=`pwd`/prefix-remove.sh $CCACHE_COMPILE -c test_no_obj.c
+    expect_stat 'compiler produced no output' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Empty object file"
+
+    cat <<'EOF' >test_empty_obj.c
+int test_empty_obj;
+EOF
+    cat <<'EOF' >prefix-empty.sh
+#!/bin/sh
+"$@"
+[ x$2 = x-fcolor-diagnostics ] && shift
+[ x$2 = x-fdiagnostics-color ] && shift
+[ x$2 = x-std=gnu99 ] && shift
+[ x$3 = x-o ] && cp /dev/null $4
+EOF
+    chmod +x prefix-empty.sh
+    CCACHE_PREFIX=`pwd`/prefix-empty.sh $CCACHE_COMPILE -c test_empty_obj.c
+    expect_stat 'compiler produced empty output' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Caching stderr"
+
+    cat <<EOF >stderr.c
+int stderr(void)
+{
+  // Trigger warning by having no return statement.
+}
+EOF
+    $CCACHE_COMPILE -Wall -W -c stderr.c 2>/dev/null
+    num=`find $CCACHE_DIR -name '*.stderr' | wc -l`
+    if [ $num -ne 1 ]; then
+        test_failed "$num stderr files found, expected 1"
+    fi
+    expect_stat 'files in cache' 2
+
+    # -------------------------------------------------------------------------
+    TEST "--zero-stats"
+
+    $CCACHE_COMPILE -c test1.c
+    $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+
+    $CCACHE -z >/dev/null
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 0
+    expect_stat 'files in cache' 1
+
+    # -------------------------------------------------------------------------
+    TEST "--clear"
+
+    $CCACHE_COMPILE -c test1.c
+    $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+
+    $CCACHE -C >/dev/null
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 0
+
+    # -------------------------------------------------------------------------
+    TEST "-P"
+
+    # Check that -P disables ccache. (-P removes preprocessor information in
+    # such a way that the object file from compiling the preprocessed file will
+    # not be equal to the object file produced when compiling without ccache.)
+
+    $CCACHE_COMPILE -c -P test1.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 0
+    expect_stat 'unsupported compiler option' 1
+
+    # -------------------------------------------------------------------------
+    TEST "-Wp,-P"
+
+    # Check that -Wp,-P disables ccache. (-P removes preprocessor information
+    # in such a way that the object file from compiling the preprocessed file
+    # will not be equal to the object file produced when compiling without
+    # ccache.)
+
+    $CCACHE_COMPILE -c -Wp,-P test1.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 0
+    expect_stat 'unsupported compiler option' 1
+
+    $CCACHE_COMPILE -c -Wp,-P,-DFOO test1.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 0
+    expect_stat 'unsupported compiler option' 2
+
+    $CCACHE_COMPILE -c -Wp,-DFOO,-P test1.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 0
+    expect_stat 'unsupported compiler option' 3
+
+    # -------------------------------------------------------------------------
+    TEST "-Wp,-D"
+
+    $CCACHE_COMPILE -c -Wp,-DFOO test1.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -c -DFOO test1.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Buggy GCC 6 cpp"
+
+    cat >buggy-cpp <<EOF
+#!/bin/sh
+export CCACHE_DISABLE=1 # If $COMPILER happens to be a ccache symlink...
+if echo "\$*" | grep -- -D >/dev/null; then
+  $COMPILER "\$@"
+else
+  # Mistreat the preprocessor output in the same way as GCC 6 does.
+  $COMPILER "\$@" |
+    sed -e '/^# 1 "<command-line>"\$/ a\\
+# 31 "<command-line>"' \\
+        -e 's/^# 1 "<command-line>" 2\$/# 32 "<command-line>" 2/'
+fi
+exit 0
+EOF
+    cat <<'EOF' >file.c
+int foo;
+EOF
+    chmod +x buggy-cpp
+
+    $CCACHE ./buggy-cpp -c file.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE ./buggy-cpp -DNOT_AFFECTING=1 -c file.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Symlink to source directory"
+
+    mkdir dir
+    cd dir
+    mkdir -p d1/d2
+    echo '#define A "OK"' >d1/h.h
+    cat <<EOF >d1/d2/c.c
+#include <stdio.h>
+#include "../h.h"
+int main() { printf("%s\n", A); }
+EOF
+    echo '#define A "BUG"' >h.h
+    ln -s d1/d2 d3
+
+    CCACHE_BASEDIR=/ $CCACHE_COMPILE -c $PWD/d3/c.c
+    $REAL_COMPILER c.o -o c
+    if [ "$(./c)" != OK ]; then
+        test_failed "Incorrect header file used"
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST "Symlink to source file"
+
+    mkdir dir
+    cd dir
+    mkdir d
+    echo '#define A "BUG"' >d/h.h
+    cat <<EOF >d/c.c
+#include <stdio.h>
+#include "h.h"
+int main() { printf("%s\n", A); }
+EOF
+    echo '#define A "OK"' >h.h
+    ln -s d/c.c c.c
+
+    CCACHE_BASEDIR=/ $CCACHE_COMPILE -c $PWD/c.c
+    $REAL_COMPILER c.o -o c
+    if [ "$(./c)" != OK ]; then
+        test_failed "Incorrect header file used"
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST ".incbin"
+
+    cat <<EOF >incbin.c
+char x[] = ".incbin";
+EOF
+
+    $CCACHE_COMPILE -c incbin.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 0
+    expect_stat 'unsupported code directive' 1
+
+    # -------------------------------------------------------------------------
+    TEST "UNCACHED_ERR_FD"
+
+    cat >compiler.sh <<'EOF'
+#!/bin/sh
+if [ "$1" = "-E" ]; then
+    echo preprocessed
+    printf ${N}Pu >&$UNCACHED_ERR_FD
+else
+    echo compiled >test1.o
+    printf ${N}Cc >&2
+    printf ${N}Cu >&$UNCACHED_ERR_FD
+fi
+EOF
+    chmod +x compiler.sh
+
+    N=1 $CCACHE ./compiler.sh -c test1.c 2>stderr.txt
+    stderr=$(cat stderr.txt)
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    if [ "$stderr" != "1Pu1Cu1Cc" ]; then
+        test_failed "Unexpected stderr: $stderr != 1Pu1Cu1Cc"
+    fi
+
+    N=2 $CCACHE ./compiler.sh -c test1.c 2>stderr.txt
+    stderr=$(cat stderr.txt)
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    if [ "$stderr" != "2Pu1Cc" ]; then
+        test_failed "Unexpected stderr: $stderr != 2Pu1Cc"
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST "Invalid boolean environment configuration options"
+
+    for invalid_val in 0 false FALSE disable DISABLE no NO; do
+        CCACHE_DISABLE=$invalid_val $CCACHE $COMPILER --version >&/dev/null
+        if [ $? -eq 0 ] ; then
+            test_failed "boolean env var '$invalid_val' should be rejected"
+        fi
+        CCACHE_NODISABLE=$invalid_val $CCACHE $COMPILER --version >&/dev/null
+        if [ $? -eq 0 ] ; then
+            test_failed "boolean env var '$invalid_val' should be rejected"
+        fi
+    done
+}
+
+# =============================================================================
+
+SUITE_base_SETUP() {
+    generate_code 1 test1.c
+}
+
+SUITE_base() {
+    base_tests
+}
diff --git a/test/suites/basedir.bash b/test/suites/basedir.bash
new file mode 100644 (file)
index 0000000..4660dc2
--- /dev/null
@@ -0,0 +1,147 @@
+SUITE_basedir_SETUP() {
+    unset CCACHE_NODIRECT
+
+    mkdir -p dir1/src dir1/include
+    cat <<EOF >dir1/src/test.c
+#include <stdarg.h>
+#include <test.h>
+EOF
+    cat <<EOF >dir1/include/test.h
+int test;
+EOF
+    cp -r dir1 dir2
+    backdate dir1/include/test.h dir2/include/test.h
+}
+
+SUITE_basedir() {
+    # -------------------------------------------------------------------------
+    TEST "Enabled CCACHE_BASEDIR"
+
+    cd dir1
+    CCACHE_BASEDIR="`pwd`" $CCACHE_COMPILE -I`pwd`/include -c src/test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    cd ../dir2
+    CCACHE_BASEDIR="`pwd`" $CCACHE_COMPILE -I`pwd`/include -c src/test.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Disabled (default) CCACHE_BASEDIR"
+
+    cd dir1
+    CCACHE_BASEDIR="`pwd`" $CCACHE_COMPILE -I`pwd`/include -c src/test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    # CCACHE_BASEDIR="" is the default:
+    $CCACHE_COMPILE -I`pwd`/include -c src/test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    # -------------------------------------------------------------------------
+    TEST "Path normalization"
+
+    cd dir1
+    CCACHE_BASEDIR="`pwd`" $CCACHE_COMPILE -I`pwd`/include -c src/test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    mkdir subdir
+    ln -s `pwd`/include subdir/symlink
+
+    # Rewriting triggered by CCACHE_BASEDIR should handle paths with multiple
+    # slashes, redundant "/." parts and "foo/.." parts correctly. Note that the
+    # ".." part of the path is resolved after the symlink has been resolved.
+    CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -I`pwd`//./subdir/symlink/../include -c `pwd`/src/test.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Rewriting in stderr"
+
+    cat <<EOF >stderr.h
+int stderr(void)
+{
+  // Trigger warning by having no return statement.
+}
+EOF
+    backdate stderr.h
+    cat <<EOF >stderr.c
+#include <stderr.h>
+EOF
+
+    CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -Wall -W -I`pwd` -c `pwd`/stderr.c -o `pwd`/stderr.o 2>stderr.txt
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    if grep `pwd` stderr.txt >/dev/null 2>&1; then
+        test_failed "Base dir (`pwd`) found in stderr:\n`cat stderr.txt`"
+    fi
+
+    CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -Wall -W -I`pwd` -c `pwd`/stderr.c -o `pwd`/stderr.o 2>stderr.txt
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    if grep `pwd` stderr.txt >/dev/null 2>&1; then
+        test_failed "Base dir (`pwd`) found in stderr:\n`cat stderr.txt`"
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST "-MF/-MQ/-MT with absolute paths"
+
+    for option in MF "MF " MQ "MQ " MT "MT "; do
+        clear_cache
+        cd dir1
+        CCACHE_BASEDIR="`pwd`" $CCACHE_COMPILE -I`pwd`/include -MD -${option}`pwd`/test.d -c src/test.c
+        expect_stat 'cache hit (direct)' 0
+        expect_stat 'cache hit (preprocessed)' 0
+        expect_stat 'cache miss' 1
+        cd ..
+
+        cd dir2
+        CCACHE_BASEDIR="`pwd`" $CCACHE_COMPILE -I`pwd`/include -MD -${option}`pwd`/test.d -c src/test.c
+        expect_stat 'cache hit (direct)' 1
+        expect_stat 'cache hit (preprocessed)' 0
+        expect_stat 'cache miss' 1
+        cd ..
+    done
+
+    # -------------------------------------------------------------------------
+    # When BASEDIR is set to /, check that -MF, -MQ and -MT arguments with
+    # absolute paths are rewritten to relative and that the dependency file
+    # only contains relative paths.
+    TEST "-MF/-MQ/-MT with absolute paths and BASEDIR set to /"
+
+    for option in MF "MF " MQ "MQ " MT "MT "; do
+        clear_cache
+        cd dir1
+        CCACHE_BASEDIR="/" $CCACHE_COMPILE -I`pwd`/include -MD -${option}`pwd`/test.d -c src/test.c
+        expect_stat 'cache hit (direct)' 0
+        expect_stat 'cache hit (preprocessed)' 0
+        expect_stat 'cache miss' 1
+        # Check that there is no absolute path in the dependency file:
+        while read line; do
+            for file in $line; do
+                case $file in /*)
+                    test_failed "Absolute file path '$file' found in dependency file '`pwd`/test.d'"
+                esac
+            done
+        done <test.d
+        cd ..
+
+        cd dir2
+        CCACHE_BASEDIR="/" $CCACHE_COMPILE -I`pwd`/include -MD -${option}`pwd`/test.d -c src/test.c
+        expect_stat 'cache hit (direct)' 1
+        expect_stat 'cache hit (preprocessed)' 0
+        expect_stat 'cache miss' 1
+        cd ..
+    done
+}
diff --git a/test/suites/cleanup.bash b/test/suites/cleanup.bash
new file mode 100644 (file)
index 0000000..989c96f
--- /dev/null
@@ -0,0 +1,243 @@
+prepare_cleanup_test_dir() {
+    local dir=$1
+
+    rm -rf $dir
+    mkdir -p $dir
+    for i in $(seq 0 9); do
+        printf '%4017s' '' | tr ' ' 'A' >$dir/result$i-4017.o
+        touch $dir/result$i-4017.stderr
+        touch $dir/result$i-4017.d
+        if [ $i -gt 5 ]; then
+            backdate $dir/result$i-4017.stderr
+        fi
+    done
+    # NUMFILES: 30, TOTALSIZE: 40 KiB, MAXFILES: 0, MAXSIZE: 0
+    echo "0 0 0 0 0 0 0 0 0 0 0 30 40 0 0" >$dir/stats
+}
+
+SUITE_cleanup() {
+    # -------------------------------------------------------------------------
+    TEST "Clear cache"
+
+    prepare_cleanup_test_dir $CCACHE_DIR/a
+
+    $CCACHE -C >/dev/null
+    expect_file_count 0 '*.o' $CCACHE_DIR
+    expect_file_count 0 '*.d' $CCACHE_DIR
+    expect_file_count 0 '*.stderr' $CCACHE_DIR
+    expect_stat 'files in cache' 0
+    expect_stat 'cleanups performed' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Forced cache cleanup, no limits"
+
+    prepare_cleanup_test_dir $CCACHE_DIR/a
+
+    $CCACHE -F 0 -M 0 >/dev/null
+    $CCACHE -c >/dev/null
+    expect_file_count 10 '*.o' $CCACHE_DIR
+    expect_file_count 10 '*.d' $CCACHE_DIR
+    expect_file_count 10 '*.stderr' $CCACHE_DIR
+    expect_stat 'files in cache' 30
+    expect_stat 'cleanups performed' 0
+
+    # -------------------------------------------------------------------------
+    TEST "Forced cache cleanup, file limit"
+
+    prepare_cleanup_test_dir $CCACHE_DIR/a
+
+    # No cleanup needed.
+    #
+    # 30 * 16 = 480
+    $CCACHE -F 480 -M 0 >/dev/null
+    $CCACHE -c >/dev/null
+    expect_file_count 10 '*.o' $CCACHE_DIR
+    expect_file_count 10 '*.d' $CCACHE_DIR
+    expect_file_count 10 '*.stderr' $CCACHE_DIR
+    expect_stat 'files in cache' 30
+    expect_stat 'cleanups performed' 0
+
+    # Reduce file limit
+    #
+    # 21 * 16 = 336
+    $CCACHE -F 336 -M 0 >/dev/null
+    $CCACHE -c >/dev/null
+    expect_file_count 7 '*.o' $CCACHE_DIR
+    expect_file_count 7 '*.d' $CCACHE_DIR
+    expect_file_count 7 '*.stderr' $CCACHE_DIR
+    expect_stat 'files in cache' 21
+    expect_stat 'cleanups performed' 1
+    for i in 0 1 2 3 4 5 9; do
+        file=$CCACHE_DIR/a/result$i-4017.o
+        if [ ! -f $file ]; then
+            test_failed "File $file removed when it shouldn't"
+        fi
+    done
+    for i in 6 7 8; do
+        file=$CCACHE_DIR/a/result$i-4017.o
+        if [ -f $file ]; then
+            test_failed "File $file not removed when it should"
+        fi
+    done
+
+    # -------------------------------------------------------------------------
+    TEST "Forced cache cleanup, size limit"
+
+    # NOTE: This test is known to fail on filesystems that have unusual block
+    # sizes, including ecryptfs. The workaround is to place the test directory
+    # elsewhere:
+    #
+    #     cd /tmp
+    #     CCACHE=$DIR/ccache $DIR/test.sh
+
+    prepare_cleanup_test_dir $CCACHE_DIR/a
+
+    $CCACHE -F 0 -M 256K >/dev/null
+    CCACHE_LOGFILE=/tmp/foo $CCACHE -c >/dev/null
+    expect_file_count 3 '*.o' $CCACHE_DIR
+    expect_file_count 3 '*.d' $CCACHE_DIR
+    expect_file_count 3 '*.stderr' $CCACHE_DIR
+    expect_stat 'files in cache' 9
+    expect_stat 'cleanups performed' 1
+    for i in 3 4 5; do
+        file=$CCACHE_DIR/a/result$i-4017.o
+        if [ ! -f $file ]; then
+            test_failed "File $file removed when it shouldn't"
+        fi
+    done
+    for i in 0 1 2 6 7 8 9; do
+        file=$CCACHE_DIR/a/result$i-4017.o
+        if [ -f $file ]; then
+            test_failed "File $file not removed when it should"
+        fi
+    done
+
+    # -------------------------------------------------------------------------
+    TEST "Automatic cache cleanup, limit_multiple 0.9"
+
+    for x in 0 1 2 3 4 5 6 7 8 9 a b c d e f; do
+        prepare_cleanup_test_dir $CCACHE_DIR/$x
+    done
+
+    $CCACHE -F 480 -M 0 >/dev/null
+
+    expect_file_count 160 '*.o' $CCACHE_DIR
+    expect_file_count 160 '*.d' $CCACHE_DIR
+    expect_file_count 160 '*.stderr' $CCACHE_DIR
+    expect_stat 'files in cache' 480
+    expect_stat 'cleanups performed' 0
+
+    touch empty.c
+    CCACHE_LIMIT_MULTIPLE=0.9 $CCACHE_COMPILE -c empty.c -o empty.o
+    expect_file_count 159 '*.o' $CCACHE_DIR
+    expect_file_count 158 '*.d' $CCACHE_DIR
+    expect_file_count 158 '*.stderr' $CCACHE_DIR
+    expect_stat 'files in cache' 475
+    expect_stat 'cleanups performed' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Automatic cache cleanup, limit_multiple 0.7"
+
+    for x in 0 1 2 3 4 5 6 7 8 9 a b c d e f; do
+        prepare_cleanup_test_dir $CCACHE_DIR/$x
+    done
+
+    $CCACHE -F 480 -M 0 >/dev/null
+
+    expect_file_count 160 '*.o' $CCACHE_DIR
+    expect_file_count 160 '*.d' $CCACHE_DIR
+    expect_file_count 160 '*.stderr' $CCACHE_DIR
+    expect_stat 'files in cache' 480
+    expect_stat 'cleanups performed' 0
+
+    touch empty.c
+    CCACHE_LIMIT_MULTIPLE=0.7 $CCACHE_COMPILE -c empty.c -o empty.o
+    expect_file_count 157 '*.o' $CCACHE_DIR
+    expect_file_count 156 '*.d' $CCACHE_DIR
+    expect_file_count 156 '*.stderr' $CCACHE_DIR
+    expect_stat 'files in cache' 469
+    expect_stat 'cleanups performed' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Cleanup of sibling files"
+
+    prepare_cleanup_test_dir $CCACHE_DIR/a
+
+    $CCACHE -F 336 -M 0 >/dev/null
+    backdate $CCACHE_DIR/a/result2-4017.stderr
+    $CCACHE -c >/dev/null
+    # floor(0.8 * 9) = 7
+    expect_file_count 7 '*.o' $CCACHE_DIR
+    expect_file_count 7 '*.d' $CCACHE_DIR
+    expect_file_count 7 '*.stderr' $CCACHE_DIR
+    expect_stat 'files in cache' 21
+    for i in 0 1 3 4 5 8 9; do
+        file=$CCACHE_DIR/a/result$i-4017.o
+        if [ ! -f $file ]; then
+            test_failed "File $file removed when it shouldn't"
+        fi
+    done
+    for i in 2 6 7; do
+        file=$CCACHE_DIR/a/result$i-4017.o
+        if [ -f $file ]; then
+            test_failed "File $file not removed when it should"
+        fi
+    done
+
+    # -------------------------------------------------------------------------
+    TEST "No cleanup of new unknown file"
+
+    prepare_cleanup_test_dir $CCACHE_DIR/a
+
+    touch $CCACHE_DIR/a/abcd.unknown
+    $CCACHE -F 0 -M 0 -c >/dev/null # update counters
+    expect_stat 'files in cache' 31
+
+    $CCACHE -F 480 -M 0 >/dev/null
+    $CCACHE -c >/dev/null
+    if [ ! -f $CCACHE_DIR/a/abcd.unknown ]; then
+        test_failed "$CCACHE_DIR/a/abcd.unknown removed"
+    fi
+    expect_stat 'files in cache' 28
+
+    # -------------------------------------------------------------------------
+    TEST "Cleanup of old unknown file"
+
+    prepare_cleanup_test_dir $CCACHE_DIR/a
+    $CCACHE -F 480 -M 0 >/dev/null
+    touch $CCACHE_DIR/a/abcd.unknown
+    backdate $CCACHE_DIR/a/abcd.unknown
+    $CCACHE -F 0 -M 0 -c >/dev/null # update counters
+    expect_stat 'files in cache' 31
+
+    $CCACHE -F 480 -M 0 -c >/dev/null
+    if [ -f $CCACHE_DIR/a/abcd.unknown ]; then
+        test_failed "$CCACHE_DIR/a/abcd.unknown not removed"
+    fi
+    expect_stat 'files in cache' 30
+
+    # -------------------------------------------------------------------------
+    TEST "Cleanup of tmp file"
+
+    mkdir -p $CCACHE_DIR/a
+    touch $CCACHE_DIR/a/abcd.tmp.efgh
+    $CCACHE -c >/dev/null # update counters
+    expect_stat 'files in cache' 1
+    backdate $CCACHE_DIR/a/abcd.tmp.efgh
+    $CCACHE -c >/dev/null
+    if [ -f $CCACHE_DIR/a/abcd.tmp.efgh ]; then
+        test_failed "$CCACHE_DIR/a/abcd.tmp.unknown not removed"
+    fi
+    expect_stat 'files in cache' 0
+
+    # -------------------------------------------------------------------------
+    TEST "No cleanup of .nfs* files"
+
+    prepare_cleanup_test_dir $CCACHE_DIR/a
+
+    touch $CCACHE_DIR/a/.nfs0123456789
+    $CCACHE -F 0 -M 0 >/dev/null
+    $CCACHE -c >/dev/null
+    expect_file_count 1 '.nfs*' $CCACHE_DIR
+    expect_stat 'files in cache' 30
+}
diff --git a/test/suites/compression.bash b/test/suites/compression.bash
new file mode 100644 (file)
index 0000000..c5f4df3
--- /dev/null
@@ -0,0 +1,23 @@
+SUITE_compression_SETUP() {
+    generate_code 1 test.c
+}
+
+SUITE_compression() {
+    # -------------------------------------------------------------------------
+    TEST "Hash sum equal for compressed and uncompressed files"
+
+    CCACHE_COMPRESS=1 $CCACHE_COMPILE -c test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_COMPRESS=1 $CCACHE_COMPILE -c test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -c test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 2
+    expect_stat 'cache miss' 1
+}
diff --git a/test/suites/cpp1.bash b/test/suites/cpp1.bash
new file mode 100644 (file)
index 0000000..965d466
--- /dev/null
@@ -0,0 +1,65 @@
+SUITE_cpp1_PROBE() {
+    touch test.c
+    if $COMPILER_TYPE_GCC; then
+        if ! $REAL_COMPILER -E -fdirectives-only test.c >&/dev/null; then
+            echo "-fdirectives-only not supported by compiler"
+            return
+        fi
+    elif $COMPILER_TYPE_CLANG; then
+        if ! $REAL_COMPILER -E -frewrite-includes test.c >&/dev/null; then
+            echo "-frewrite-includes not supported by compiler"
+            return
+        fi
+    else
+        echo "Unknown compiler: $COMPILER"
+        return
+    fi
+}
+
+SUITE_cpp1_SETUP() {
+    export CCACHE_NOCPP2=1
+    echo "#define FOO 1" >test1.h
+    backdate test1.h
+    echo '#include "test1.h"' >test1.c
+    echo '#define BAR 2' >>test1.c
+    echo 'int foo(int x) { return FOO; }' >>test1.c
+    echo 'int bar(int x) { return BAR; }' >>test1.c
+    echo 'int baz(int x) { return BAZ; }' >>test1.c
+}
+
+SUITE_cpp1() {
+    if $COMPILER_TYPE_GCC; then
+        cpp_flag="-fdirectives-only"
+    elif $COMPILER_TYPE_CLANG; then
+        cpp_flag="-frewrite-includes"
+    fi
+    cpp_flag+=" -DBAZ=3"
+
+    # -------------------------------------------------------------------------
+    TEST "Base case"
+
+    $REAL_COMPILER $cpp_flag -c -o reference_test1.o test1.c
+
+    $CCACHE_COMPILE $cpp_flag -c test1.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_object_files reference_test1.o test1.o
+
+    unset CCACHE_NODIRECT
+
+    $CCACHE_COMPILE $cpp_flag -c test1.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 2
+    expect_equal_object_files reference_test1.o test1.o
+
+    $CCACHE_COMPILE $cpp_flag -c test1.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 2
+    expect_equal_object_files reference_test1.o test1.o
+}
diff --git a/test/suites/debug_prefix_map.bash b/test/suites/debug_prefix_map.bash
new file mode 100644 (file)
index 0000000..a3a22a8
--- /dev/null
@@ -0,0 +1,71 @@
+SUITE_debug_prefix_map_PROBE() {
+    if $COMPILER_USES_MINGW; then
+        echo "-fdebug-prefix-map not supported by compiler"
+    fi
+}
+
+SUITE_debug_prefix_map_SETUP() {
+    unset CCACHE_NODIRECT
+
+    mkdir -p dir1/src dir1/include
+    cat <<EOF >dir1/src/test.c
+#include <stdarg.h>
+#include <test.h>
+EOF
+    cat <<EOF >dir1/include/test.h
+int test;
+EOF
+    cp -r dir1 dir2
+    backdate dir1/include/test.h dir2/include/test.h
+}
+
+SUITE_debug_prefix_map() {
+    # -------------------------------------------------------------------------
+    TEST "Mapping of debug info CWD"
+
+    cd dir1
+    CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -I`pwd`/include -g -fdebug-prefix-map=`pwd`=dir -c `pwd`/src/test.c -o `pwd`/test.o
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 2
+    if grep -E "[^=]`pwd`[^=]" test.o >/dev/null 2>&1; then
+        test_failed "Source dir (`pwd`) found in test.o"
+    fi
+
+    cd ../dir2
+    CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -I`pwd`/include -g -fdebug-prefix-map=`pwd`=dir -c `pwd`/src/test.c -o `pwd`/test.o
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 2
+    if grep -E "[^=]`pwd`[^=]" test.o >/dev/null 2>&1; then
+        test_failed "Source dir (`pwd`) found in test.o"
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST "Multiple -fdebug-prefix-map"
+
+    cd dir1
+    CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -I`pwd`/include -g -fdebug-prefix-map=`pwd`=name -fdebug-prefix-map=foo=bar -c `pwd`/src/test.c -o `pwd`/test.o
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 2
+    if grep -E "[^=]`pwd`[^=]" test.o >/dev/null 2>&1; then
+        test_failed "Source dir (`pwd`) found in test.o"
+    fi
+    if ! grep "name" test.o >/dev/null 2>&1; then
+        test_failed "Relocation (name) not found in test.o"
+    fi
+
+    cd ../dir2
+    CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -I`pwd`/include -g -fdebug-prefix-map=`pwd`=name -fdebug-prefix-map=foo=bar -c `pwd`/src/test.c -o `pwd`/test.o
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 2
+    if grep -E "[^=]`pwd`[^=]" test.o >/dev/null 2>&1; then
+        test_failed "Source dir (`pwd`) found in test.o"
+    fi
+}
diff --git a/test/suites/direct.bash b/test/suites/direct.bash
new file mode 100644 (file)
index 0000000..0b2b3c8
--- /dev/null
@@ -0,0 +1,910 @@
+SUITE_direct_SETUP() {
+    unset CCACHE_NODIRECT
+
+    cat <<EOF >test.c
+// test.c
+#include "test1.h"
+#include "test2.h"
+EOF
+    cat <<EOF >test1.h
+#include "test3.h"
+int test1;
+EOF
+    cat <<EOF >test2.h
+int test2;
+EOF
+    cat <<EOF >test3.h
+int test3;
+EOF
+    backdate test1.h test2.h test3.h
+
+    $REAL_COMPILER -c -Wp,-MD,expected.d test.c
+    $REAL_COMPILER -c -Wp,-MMD,expected_mmd.d test.c
+    rm test.o
+}
+
+SUITE_direct() {
+    # -------------------------------------------------------------------------
+    TEST "Base case"
+
+    $REAL_COMPILER -c -o reference_test.o test.c
+
+    $CCACHE_COMPILE -c test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 2 # .o + .manifest
+    expect_equal_object_files reference_test.o test.o
+
+    $CCACHE_COMPILE -c test.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 2
+    expect_equal_object_files reference_test.o test.o
+
+    # -------------------------------------------------------------------------
+    TEST "Corrupt manifest file"
+
+    $CCACHE_COMPILE -c test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    manifest_file=`find $CCACHE_DIR -name '*.manifest'`
+    rm $manifest_file
+    touch $manifest_file
+
+    $CCACHE_COMPILE -c test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -c test.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_NODIRECT"
+
+    CCACHE_NODIRECT=1 $CCACHE_COMPILE -c test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_NODIRECT=1 $CCACHE_COMPILE -c test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Modified include file"
+
+    $CCACHE_COMPILE -c test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    echo "int test3_2;" >>test3.h
+    backdate test3.h
+    $CCACHE_COMPILE -c test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    $CCACHE_COMPILE -c test.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    # -------------------------------------------------------------------------
+    TEST "Removed but previously compiled header file"
+
+    $CCACHE_COMPILE -c test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    rm test3.h
+    cat <<EOF >test1.h
+// No more include of test3.h
+int test1;
+EOF
+    backdate test1.h
+
+    $CCACHE_COMPILE -c test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    $CCACHE_COMPILE -c test.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    # -------------------------------------------------------------------------
+    TEST "Calculation of dependency file names"
+
+    mkdir test.dir
+    for ext in .o .obj "" . .foo.bar; do
+        dep_file=test.dir/`echo test$ext | sed 's/\.[^.]*\$//'`.d
+
+        $CCACHE_COMPILE -MD -c test.c -o test.dir/test$ext
+        rm -f $dep_file
+        $CCACHE_COMPILE -MD -c test.c -o test.dir/test$ext
+        if [ ! -f $dep_file ]; then
+            test_failed "$dep_file missing"
+        fi
+        if ! grep "test$ext:" $dep_file >/dev/null 2>&1; then
+            test_failed "$dep_file does not contain test$ext"
+        fi
+
+        dep_target=foo.bar
+        $CCACHE_COMPILE -MD -MQ $dep_target -c test.c -o test.dir/test$ext
+        rm -f $dep_target
+        $CCACHE_COMPILE -MD -MQ $dep_target -c test.c -o test.dir/test$ext
+        if [ ! -f $dep_file ]; then
+            test_failed "$dep_file missing"
+        fi
+        if ! grep $dep_target $dep_file >/dev/null 2>&1; then
+            test_failed "$dep_file does not contain $dep_target"
+        fi
+    done
+    expect_stat 'files in cache' 18
+
+    # -------------------------------------------------------------------------
+    TEST "-MMD for different source files"
+
+    mkdir a b
+    touch a/source.c b/source.c
+    backdate a/source.h b/source.h
+    $CCACHE_COMPILE -MMD -c a/source.c
+    expect_file_content source.d "source.o: a/source.c"
+
+    $CCACHE_COMPILE -MMD -c b/source.c
+    expect_file_content source.d "source.o: b/source.c"
+
+    $CCACHE_COMPILE -MMD -c a/source.c
+    expect_file_content source.d "source.o: a/source.c"
+
+    # -------------------------------------------------------------------------
+    TEST "-MMD for different include file paths"
+
+    mkdir a b
+    touch a/source.h b/source.h
+    backdate a/source.h b/source.h
+    echo '#include <source.h>' >source.c
+    $CCACHE_COMPILE -MMD -Ia -c source.c
+    expect_file_content source.d "source.o: source.c a/source.h"
+
+    $CCACHE_COMPILE -MMD -Ib -c source.c
+    expect_file_content source.d "source.o: source.c b/source.h"
+
+    $CCACHE_COMPILE -MMD -Ia -c source.c
+    expect_file_content source.d "source.o: source.c a/source.h"
+
+    # -------------------------------------------------------------------------
+    TEST "-Wp,-MD"
+
+    $CCACHE_COMPILE -c -Wp,-MD,other.d test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_equal_files other.d expected.d
+
+    $REAL_COMPILER -c -Wp,-MD,other.d test.c -o reference_test.o
+    expect_equal_object_files reference_test.o test.o
+
+    rm -f other.d
+    $CCACHE_COMPILE -c -Wp,-MD,other.d test.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_equal_files other.d expected.d
+    expect_equal_object_files reference_test.o test.o
+
+    $CCACHE_COMPILE -c -Wp,-MD,different_name.d test.c
+    expect_stat 'cache hit (direct)' 2
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_equal_files different_name.d expected.d
+    expect_equal_object_files reference_test.o test.o
+
+    # -------------------------------------------------------------------------
+    TEST "-Wp,-MMD"
+
+    $CCACHE_COMPILE -c -Wp,-MMD,other.d test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_equal_files other.d expected_mmd.d
+
+    $REAL_COMPILER -c -Wp,-MMD,other.d test.c -o reference_test.o
+    expect_equal_object_files reference_test.o test.o
+
+    rm -f other.d
+    $CCACHE_COMPILE -c -Wp,-MMD,other.d test.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_equal_files other.d expected_mmd.d
+    expect_equal_object_files reference_test.o test.o
+
+    $CCACHE_COMPILE -c -Wp,-MMD,different_name.d test.c
+    expect_stat 'cache hit (direct)' 2
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_equal_files different_name.d expected_mmd.d
+    expect_equal_object_files reference_test.o test.o
+
+    # -------------------------------------------------------------------------
+    TEST "-Wp,-D"
+
+    $CCACHE_COMPILE -c -Wp,-DFOO test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -c -DFOO test.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "-Wp, with multiple arguments"
+
+    # ccache could try to parse and make sense of -Wp, with multiple arguments,
+    # but it currently doesn't, so we have to disable direct mode.
+
+    touch source.c
+
+    $CCACHE_COMPILE -c -Wp,-MMD,source.d,-MT,source.o source.c 2>/dev/null
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_file_content source.d "source.o: source.c"
+
+    $CCACHE_COMPILE -c -Wp,-MMD,source.d,-MT,source.o source.c 2>/dev/null
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_file_content source.d "source.o: source.c"
+
+    # -------------------------------------------------------------------------
+    TEST "-MMD for different source files"
+
+    mkdir a b
+    touch a/source.c b/source.c
+    $CCACHE_COMPILE -MMD -c a/source.c
+    expect_file_content source.d "source.o: a/source.c"
+
+    $CCACHE_COMPILE -MMD -c b/source.c
+    expect_file_content source.d "source.o: b/source.c"
+
+    $CCACHE_COMPILE -MMD -c a/source.c
+    expect_file_content source.d "source.o: a/source.c"
+
+    # -------------------------------------------------------------------------
+    TEST "Multiple object entries in manifest"
+
+    for i in 0 1 2 3 4; do
+        echo "int test1_$i;" >>test1.h
+        backdate test1.h
+        $CCACHE_COMPILE -c test.c
+        $CCACHE_COMPILE -c test.c
+    done
+    expect_stat 'cache hit (direct)' 5
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 5
+
+    # -------------------------------------------------------------------------
+    TEST "-MD"
+
+    $CCACHE_COMPILE -c -MD test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_equal_files test.d expected.d
+
+    $REAL_COMPILER -c -MD test.c -o reference_test.o
+    expect_equal_object_files reference_test.o test.o
+
+    rm -f test.d
+    $CCACHE_COMPILE -c -MD test.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_equal_files test.d expected.d
+    expect_equal_object_files reference_test.o test.o
+
+    # -------------------------------------------------------------------------
+    TEST "-ftest-coverage"
+
+    cat <<EOF >code.c
+int test() { return 0; }
+EOF
+
+    $CCACHE_COMPILE -c -fprofile-arcs -ftest-coverage code.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    test -r code.gcno || test_failed "code.gcno missing"
+
+    rm code.gcno
+
+    $CCACHE_COMPILE -c -fprofile-arcs -ftest-coverage code.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    test -r code.gcno || test_failed "code.gcno missing"
+
+    # -------------------------------------------------------------------------
+    TEST "-fstack-usage"
+
+    cat <<EOF >code.c
+int test() { return 0; }
+EOF
+
+    if $COMPILER_TYPE_GCC; then
+        $CCACHE_COMPILE -c -fstack-usage code.c
+        expect_stat 'cache hit (direct)' 0
+        expect_stat 'cache hit (preprocessed)' 0
+        expect_stat 'cache miss' 1
+        test -r code.su || test_failed "code.su missing"
+
+        rm code.su
+
+        $CCACHE_COMPILE -c -fstack-usage code.c
+        expect_stat 'cache hit (direct)' 1
+        expect_stat 'cache hit (preprocessed)' 0
+        expect_stat 'cache miss' 1
+        test -r code.su || test_failed "code.su missing"
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST "Direct mode on cache created by ccache without direct mode support"
+
+    CCACHE_NODIRECT=1 $CCACHE_COMPILE -c -MD test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_equal_files test.d expected.d
+    $REAL_COMPILER -c -MD test.c -o reference_test.o
+    expect_equal_object_files reference_test.o test.o
+
+    rm -f test.d
+
+    CCACHE_NODIRECT=1 $CCACHE_COMPILE -c -MD test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_equal_files test.d expected.d
+    expect_equal_object_files reference_test.o test.o
+
+    rm -f test.d
+
+    $CCACHE_COMPILE -c -MD test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 2
+    expect_stat 'cache miss' 1
+    expect_equal_files test.d expected.d
+    expect_equal_object_files reference_test.o test.o
+
+    rm -f test.d
+
+    $CCACHE_COMPILE -c -MD test.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 2
+    expect_stat 'cache miss' 1
+    expect_equal_files test.d expected.d
+    expect_equal_object_files reference_test.o test.o
+
+    # -------------------------------------------------------------------------
+    TEST "-MF"
+
+    $CCACHE_COMPILE -c -MD -MF other.d test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_equal_files other.d expected.d
+    $REAL_COMPILER -c -MD -MF other.d test.c -o reference_test.o
+    expect_equal_object_files reference_test.o test.o
+
+    rm -f other.d
+
+    $CCACHE_COMPILE -c -MD -MF other.d test.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_equal_files other.d expected.d
+    expect_equal_object_files reference_test.o test.o
+
+    $CCACHE_COMPILE -c -MD -MF different_name.d test.c
+    expect_stat 'cache hit (direct)' 2
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_equal_files different_name.d expected.d
+    expect_equal_object_files reference_test.o test.o
+
+    rm -f different_name.d
+
+    $CCACHE_COMPILE -c -MD -MFthird_name.d test.c
+    expect_stat 'cache hit (direct)' 3
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_equal_files third_name.d expected.d
+    expect_equal_object_files reference_test.o test.o
+
+    rm -f third_name.d
+
+    # -------------------------------------------------------------------------
+    TEST "Missing .d file"
+
+    $CCACHE_COMPILE -c -MD test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -c -MD test.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_equal_files test.d expected.d
+
+    find $CCACHE_DIR -name '*.d' -delete
+
+    # Missing file -> consider the cached result broken.
+    $CCACHE_COMPILE -c -MD test.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'cache file missing' 1
+
+    # -------------------------------------------------------------------------
+    TEST "stderr from both preprocessor and compiler"
+
+    cat <<EOF >cpp-warning.c
+#if FOO
+// Trigger preprocessor warning about extra token after #endif.
+#endif FOO
+int stderr(void)
+{
+  // Trigger compiler warning by having no return statement.
+}
+EOF
+    $CCACHE_COMPILE -Wall -W -c cpp-warning.c 2>stderr-orig.txt
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_NODIRECT=1 $CCACHE_COMPILE -Wall -W -c cpp-warning.c 2>stderr-cpp.txt
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_file_content stderr-cpp.txt "`cat stderr-orig.txt`"
+
+    $CCACHE_COMPILE -Wall -W -c cpp-warning.c 2>stderr-mf.txt
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_file_content stderr-mf.txt "`cat stderr-orig.txt`"
+
+    # -------------------------------------------------------------------------
+    TEST "Empty source file"
+
+    touch empty.c
+
+    $CCACHE_COMPILE -c empty.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -c empty.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Empty include file"
+
+    touch empty.h
+    cat <<EOF >include_empty.c
+#include "empty.h"
+EOF
+    backdate empty.h
+    $CCACHE_COMPILE -c include_empty.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    $CCACHE_COMPILE -c include_empty.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "__FILE__ in source file disables direct mode"
+
+    cat <<EOF >file.c
+#define file __FILE__
+int test;
+EOF
+
+    $CCACHE_COMPILE -c file.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -c file.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -c `pwd`/file.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    # -------------------------------------------------------------------------
+    TEST "__FILE__ in include file disables direct mode"
+
+    cat <<EOF >file.h
+#define file __FILE__
+int test;
+EOF
+    backdate file.h
+    cat <<EOF >file_h.c
+#include "file.h"
+EOF
+
+    $CCACHE_COMPILE -c file_h.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -c file_h.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    mv file_h.c file2_h.c
+
+    $CCACHE_COMPILE -c `pwd`/file2_h.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    # -------------------------------------------------------------------------
+    TEST "__FILE__ in source file ignored if sloppy"
+
+    cat <<EOF >file.c
+#define file __FILE__
+int test;
+EOF
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c file.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c file.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c `pwd`/file.c
+    expect_stat 'cache hit (direct)' 2
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "__FILE__ in include file ignored if sloppy"
+
+    cat <<EOF >file.h
+#define file __FILE__
+int test;
+EOF
+    backdate file.h
+    cat <<EOF >file_h.c
+#include "file.h"
+EOF
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c file_h.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c file_h.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    mv file_h.c file2_h.c
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c `pwd`/file2_h.c
+    expect_stat 'cache hit (direct)' 2
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "__TIME__ in source file disables direct mode"
+
+    cat <<EOF >time.c
+#define time __TIME__
+int test;
+EOF
+
+    $CCACHE_COMPILE -c time.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -c time.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "__TIME__ in include file disables direct mode"
+
+    cat <<EOF >time.h
+#define time __TIME__
+int test;
+EOF
+    backdate time.h
+
+    cat <<EOF >time_h.c
+#include "time.h"
+EOF
+
+    $CCACHE_COMPILE -c time_h.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -c time_h.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "__TIME__ in source file ignored if sloppy"
+
+    cat <<EOF >time.c
+#define time __TIME__
+int test;
+EOF
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE -c time.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE -c time.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "__TIME__ in include file ignored if sloppy"
+
+    cat <<EOF >time.h
+#define time __TIME__
+int test;
+EOF
+    backdate time.h
+    cat <<EOF >time_h.c
+#include "time.h"
+EOF
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE -c time_h.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE -c time_h.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Too new include file disables direct mode"
+
+    cat <<EOF >new.c
+#include "new.h"
+EOF
+    cat <<EOF >new.h
+int test;
+EOF
+    touch -t 203801010000 new.h
+
+    $CCACHE_COMPILE -c new.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -c new.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "New include file ignored if sloppy"
+
+    cat <<EOF >new.c
+#include "new.h"
+EOF
+    cat <<EOF >new.h
+int test;
+EOF
+    touch -t 203801010000 new.h
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS include_file_mtime" $CCACHE_COMPILE -c new.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS include_file_mtime" $CCACHE_COMPILE -c new.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    # Check that environment variables that affect the preprocessor are taken
+    # into account.
+    TEST "CPATH included in hash"
+
+    rm -rf subdir1 subdir2
+    mkdir subdir1 subdir2
+    cat <<EOF >subdir1/foo.h
+int foo;
+EOF
+    cat <<EOF >subdir2/foo.h
+int foo;
+EOF
+    cat <<EOF >foo.c
+#include <foo.h>
+EOF
+    backdate subdir1/foo.h subdir2/foo.h
+
+    CPATH=subdir1 $CCACHE_COMPILE -c foo.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CPATH=subdir1 $CCACHE_COMPILE -c foo.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CPATH=subdir2 $CCACHE_COMPILE -c foo.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2 # subdir2 is part of the preprocessor output
+
+    CPATH=subdir2 $CCACHE_COMPILE -c foo.c
+    expect_stat 'cache hit (direct)' 2
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    # -------------------------------------------------------------------------
+    TEST "Comment in strings"
+
+    echo 'char *comment = " /* \\\\u" "foo" " */";' >comment.c
+
+    $CCACHE_COMPILE -c comment.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -c comment.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    echo 'char *comment = " /* \\\\u" "goo" " */";' >comment.c
+
+    $CCACHE_COMPILE -c comment.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    # -------------------------------------------------------------------------
+    TEST "#line directives with troublesome files"
+
+    cat <<EOF >strange.c
+int foo;
+EOF
+    for x in stdout tty sda hda; do
+        if [ -b /dev/$x ] || [ -c /dev/$x ]; then
+            echo "#line 1 \"/dev/$x\"" >>strange.c
+        fi
+    done
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS include_file_mtime" $CCACHE_COMPILE -c strange.c
+
+    manifest=`find $CCACHE_DIR -name '*.manifest'`
+    if [ -n "$manifest" ]; then
+        data="`$CCACHE --dump-manifest $manifest | egrep '/dev/(stdout|tty|sda|hda'`"
+        if [ -n "$data" ]; then
+            test_failed "$manifest contained troublesome file(s): $data"
+        fi
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST "--dump-manifest"
+
+    $CCACHE_COMPILE test.c -c -o test.o
+
+    manifest=`find $CCACHE_DIR -name '*.manifest'`
+    $CCACHE --dump-manifest $manifest >manifest.dump
+
+    if grep 'Hash: d4de2f956b4a386c6660990a7a1ab13f' manifest.dump >/dev/null 2>&1 && \
+       grep 'Hash: e94ceb9f1b196c387d098a5f1f4fe862' manifest.dump >/dev/null 2>&1 && \
+       grep 'Hash: ba753bebf9b5eb99524bb7447095e2e6' manifest.dump >/dev/null 2>&1; then
+        : OK
+    else
+        test_failed "Unexpected output of --dump-manifest"
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST "Argument-less -B and -L"
+
+    cat <<EOF >test.c
+#include <stdio.h>
+int main(void)
+{
+#ifdef FOO
+    puts("FOO");
+#endif
+    return 0;
+}
+EOF
+
+    $CCACHE_COMPILE -B -L -DFOO -c test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -B -L -DBAR -c test.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache miss' 2
+
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_IGNOREHEADERS with filename"
+
+    mkdir subdir
+    cat <<EOF >subdir/ignore.h
+// We don't want this header in the manifest.
+EOF
+    backdate subdir/ignore.h
+    cat <<EOF >ignore.c
+#include "subdir/ignore.h"
+int foo;
+EOF
+
+    CCACHE_IGNOREHEADERS="subdir/ignore.h" $CCACHE_COMPILE -c ignore.c
+    manifest=`find $CCACHE_DIR -name '*.manifest'`
+    data="`$CCACHE --dump-manifest $manifest | grep subdir/ignore.h`"
+    if [ -n "$data" ]; then
+        test_failed "$manifest contained ignored header: $data"
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_IGNOREHEADERS with directory"
+
+    mkdir subdir
+    cat <<EOF >subdir/ignore.h
+// We don't want this header in the manifest.
+EOF
+    backdate subdir/ignore.h
+    cat <<EOF >ignore.c
+#include "subdir/ignore.h"
+int foo;
+EOF
+
+    CCACHE_IGNOREHEADERS="subdir" $CCACHE_COMPILE -c ignore.c
+    manifest=`find $CCACHE_DIR -name '*.manifest'`
+    data="`$CCACHE --dump-manifest $manifest | grep subdir/ignore.h`"
+    if [ -n "$data" ]; then
+        test_failed "$manifest contained ignored header: $data"
+    fi
+}
diff --git a/test/suites/hardlink.bash b/test/suites/hardlink.bash
new file mode 100644 (file)
index 0000000..8e7e8b0
--- /dev/null
@@ -0,0 +1,32 @@
+SUITE_hardlink_PROBE() {
+    touch file1
+    if ! ln file1 file2 >/dev/null 2>&1; then
+        echo "file system doesn't support hardlinks"
+    fi
+}
+
+SUITE_hardlink() {
+    # -------------------------------------------------------------------------
+    TEST "CCACHE_HARDLINK"
+
+    generate_code 1 test1.c
+
+    $REAL_COMPILER -c -o reference_test1.o test1.c
+
+    $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_object_files reference_test1.o test1.o
+
+    CCACHE_HARDLINK=1 $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_object_files reference_test1.o test1.o
+
+    local obj_in_cache=$(find $CCACHE_DIR -name '*.o')
+    if [ ! $obj_in_cache -ef test1.o ]; then
+        test_failed "Object file not hard-linked to cached object file"
+    fi
+}
diff --git a/test/suites/input_charset.bash b/test/suites/input_charset.bash
new file mode 100644 (file)
index 0000000..4d527fb
--- /dev/null
@@ -0,0 +1,29 @@
+SUITE_input_charset_PROBE() {
+    touch test.c
+    if ! $REAL_COMPILER -c -finput-charset=latin1 test.c >/dev/null 2>&1; then
+        echo "compiler doesn't support -finput-charset"
+    fi
+}
+
+SUITE_input_charset() {
+    # -------------------------------------------------------------------------
+    TEST "-finput-charset"
+
+    printf '#include <wchar.h>\nwchar_t foo[] = L"\xbf";\n' >latin1.c
+
+    $CCACHE_COMPILE -c -finput-charset=latin1 latin1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -c -finput-charset=latin1 latin1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    CCACHE_NOCPP2=1 $CCACHE_COMPILE -c -finput-charset=latin1 latin1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 2
+
+    CCACHE_NOCPP2=1 $CCACHE_COMPILE -c -finput-charset=latin1 latin1.c
+    expect_stat 'cache hit (preprocessed)' 2
+    expect_stat 'cache miss' 2
+}
diff --git a/test/suites/masquerading.bash b/test/suites/masquerading.bash
new file mode 100644 (file)
index 0000000..0b42eef
--- /dev/null
@@ -0,0 +1,34 @@
+SUITE_masquerading_PROBE() {
+    local compiler_binary=$(echo $COMPILER | cut -d' ' -f1)
+    if [ "$(dirname $compiler_binary)" != . ]; then
+        echo "compiler ($compiler_binary) not taken from PATH"
+    fi
+}
+
+SUITE_masquerading_SETUP() {
+    local compiler_binary=$(echo $COMPILER | cut -d' ' -f1)
+    local compiler_args=$(echo $COMPILER | cut -s -d' ' -f2-)
+
+    ln -s "$CCACHE" $compiler_binary
+    CCACHE_COMPILE="./$compiler_binary $compiler_args"
+    generate_code 1 test1.c
+}
+
+SUITE_masquerading() {
+    # -------------------------------------------------------------------------
+    TEST "Masquerading via symlink"
+
+    $REAL_COMPILER -c -o reference_test1.o test1.c
+
+    $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_object_files reference_test1.o test1.o
+
+    $CCACHE_COMPILE -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_object_files reference_test1.o test1.o
+}
diff --git a/test/suites/multi_arch.bash b/test/suites/multi_arch.bash
new file mode 100644 (file)
index 0000000..786b71b
--- /dev/null
@@ -0,0 +1,64 @@
+SUITE_multi_arch_PROBE() {
+    if ! $HOST_OS_APPLE; then
+        echo "multiple -arch options not supported on $(uname -s)"
+        return
+    fi
+}
+
+SUITE_multi_arch_SETUP() {
+    generate_code 1 test1.c
+    unset CCACHE_NODIRECT
+}
+
+SUITE_multi_arch() {
+    # -------------------------------------------------------------------------
+    TEST "cache hit, direct mode"
+
+    # Different arches shouldn't affect each other
+    $CCACHE_COMPILE -arch i386 -c test1.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -arch x86_64 -c test1.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache miss' 2
+
+    $CCACHE_COMPILE -arch i386 -c test1.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache miss' 2
+
+    # Multiple arches should be cached too
+    $CCACHE_COMPILE -arch i386 -arch x86_64 -c test1.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache miss' 3
+
+    $CCACHE_COMPILE -arch i386 -arch x86_64 -c test1.c
+    expect_stat 'cache hit (direct)' 2
+    expect_stat 'cache miss' 3
+
+    # -------------------------------------------------------------------------
+    TEST "cache hit, preprocessor mode"
+
+    export CCACHE_NODIRECT=1
+
+    $CCACHE_COMPILE -arch i386 -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -arch x86_64 -c test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    $CCACHE_COMPILE -arch i386 -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 2
+
+    # Multiple arches should be cached too
+    $CCACHE_COMPILE -arch i386 -arch x86_64 -c test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 3
+
+    $CCACHE_COMPILE -arch i386 -arch x86_64 -c test1.c
+    expect_stat 'cache hit (preprocessed)' 2
+    expect_stat 'cache miss' 3
+}
diff --git a/test/suites/nocpp2.bash b/test/suites/nocpp2.bash
new file mode 100644 (file)
index 0000000..4187c3f
--- /dev/null
@@ -0,0 +1,8 @@
+SUITE_nocpp2_SETUP() {
+    export CCACHE_NOCPP2=1
+    generate_code 1 test1.c
+}
+
+SUITE_nocpp2() {
+    base_tests
+}
diff --git a/test/suites/nvcc.bash b/test/suites/nvcc.bash
new file mode 100644 (file)
index 0000000..3b713c0
--- /dev/null
@@ -0,0 +1,281 @@
+nvcc_PROBE() {
+    if [ -z "$REAL_NVCC" ]; then
+        echo "nvcc is not available"
+    elif [ -z "$REAL_CUOBJDUMP" ]; then
+        echo "cuobjdump is not available"
+    fi
+}
+
+nvcc_SETUP() {
+    # Test code using only c++ (option --x c++). Faster than compiling cuda.
+    cat <<EOF > test_cpp.cu
+#ifndef NUM
+#define NUM 10000
+#endif
+
+void caller() {
+  for (int i = 0; i < NUM; ++i);
+}
+EOF
+
+    # Option files to modify the define.
+    cat <<EOF >test1.optf
+-DNUM=1
+EOF
+    cat <<EOF >test2.optf
+-DNUM=2
+EOF
+
+    # Test code using cuda.
+    cat <<EOF >test_cuda.cu
+#ifndef NUM
+#define NUM 10000
+#endif
+
+__global__
+void add(int *a, int *b) {
+  int i = blockIdx.x;
+  if (i < NUM) {
+    b[i] = 2 * a[i];
+  }
+}
+
+void caller() {
+  add<<<NUM, 1>>>(NULL,NULL);
+}
+EOF
+}
+
+nvcc_tests() {
+    # Reference file testing was not successful due to different "fatbin" data.
+    # Another source of differences are the temporary files created by nvcc;
+    # that can be avoided by using the options "--keep --keep-dir ./keep". So
+    # instead of comparing the binary object files, we compare the dumps of
+    # "cuobjdump -all -elf -symbols -ptx -sass test1.o".
+    nvcc_opts_cpp="-Wno-deprecated-gpu-targets -c --x c++"
+    nvcc_opts_cuda="-Wno-deprecated-gpu-targets -c"
+    nvcc_opts_gpu1="--generate-code arch=compute_50,code=compute_50"
+    nvcc_opts_gpu2="--generate-code arch=compute_52,code=sm_52"
+    ccache_nvcc_cpp="$CCACHE $REAL_NVCC $nvcc_opts_cpp"
+    ccache_nvcc_cuda="$CCACHE $REAL_NVCC $nvcc_opts_cuda"
+    cuobjdump="$REAL_CUOBJDUMP -all -elf -symbols -ptx -sass"
+
+    # -------------------------------------------------------------------------
+    TEST "Simple mode"
+
+    $REAL_NVCC $nvcc_opts_cpp -o reference_test1.o test_cpp.cu
+
+    # First compile.
+    $ccache_nvcc_cpp test_cpp.cu
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_files reference_test1.o test_cpp.o
+
+    $ccache_nvcc_cpp test_cpp.cu
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_files reference_test1.o test_cpp.o
+
+    # -------------------------------------------------------------------------
+    TEST "Different GPU architectures"
+
+    $REAL_NVCC $nvcc_opts_cuda                 -o reference_test1.o test_cuda.cu
+    $REAL_NVCC $nvcc_opts_cuda $nvcc_opts_gpu1 -o reference_test2.o test_cuda.cu
+    $REAL_NVCC $nvcc_opts_cuda $nvcc_opts_gpu2 -o reference_test3.o test_cuda.cu
+    $cuobjdump reference_test1.o > reference_test1.dump
+    $cuobjdump reference_test2.o > reference_test2.dump
+    $cuobjdump reference_test3.o > reference_test3.dump
+    expect_different_files reference_test1.dump reference_test2.dump
+    expect_different_files reference_test1.dump reference_test3.dump
+    expect_different_files reference_test2.dump reference_test3.dump
+
+    $ccache_nvcc_cuda test_cuda.cu
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    $cuobjdump test_cuda.o > test1.dump
+    expect_equal_files reference_test1.dump test1.dump
+
+    # Other GPU.
+    $ccache_nvcc_cuda $nvcc_opts_gpu1 test_cuda.cu
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+    expect_stat 'files in cache' 2
+    $cuobjdump test_cuda.o > test1.dump
+    expect_equal_files reference_test2.dump test1.dump
+
+    $ccache_nvcc_cuda $nvcc_opts_gpu1 test_cuda.cu
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 2
+    expect_stat 'files in cache' 2
+    $cuobjdump test_cuda.o > test1.dump
+    expect_equal_files reference_test2.dump test1.dump
+
+    # Another GPU.
+    $ccache_nvcc_cuda $nvcc_opts_gpu2 test_cuda.cu
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 3
+    expect_stat 'files in cache' 3
+    $cuobjdump test_cuda.o > test1.dump
+    expect_equal_files reference_test3.dump test1.dump
+
+    $ccache_nvcc_cuda $nvcc_opts_gpu2 test_cuda.cu
+    expect_stat 'cache hit (preprocessed)' 2
+    expect_stat 'cache miss' 3
+    expect_stat 'files in cache' 3
+    $cuobjdump test_cuda.o > test1.dump
+    expect_equal_files reference_test3.dump test1.dump
+
+    # -------------------------------------------------------------------------
+    TEST "Different defines"
+
+    $REAL_NVCC $nvcc_opts_cpp            -o reference_test1.o test_cpp.cu
+    $REAL_NVCC $nvcc_opts_cpp -DNUM=10   -o reference_test2.o test_cpp.cu
+    expect_different_files reference_test1.o reference_test2.o
+
+    $ccache_nvcc_cpp test_cpp.cu
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_files reference_test1.o test_cpp.o
+
+    # Specified define, but unused. Can only be found by preprocessed mode.
+    $ccache_nvcc_cpp -DDUMMYENV=1 test_cpp.cu
+    expect_stat "cache hit (preprocessed)" 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_files reference_test1.o test_cpp.o
+
+    # Specified used define.
+    $ccache_nvcc_cpp -DNUM=10 test_cpp.cu
+    expect_stat "cache hit (preprocessed)" 1
+    expect_stat 'cache miss' 2
+    expect_stat 'files in cache' 2
+    expect_equal_files reference_test2.o test_cpp.o
+
+    $ccache_nvcc_cpp -DNUM=10 test_cpp.cu
+    expect_stat 'cache hit (preprocessed)' 2
+    expect_stat 'cache miss' 2
+    expect_stat 'files in cache' 2
+    expect_equal_files reference_test2.o test_cpp.o
+
+    # -------------------------------------------------------------------------
+    TEST "Option file"
+
+    $REAL_NVCC $nvcc_opts_cpp -optf test1.optf -o reference_test1.o test_cpp.cu
+    $REAL_NVCC $nvcc_opts_cpp -optf test2.optf -o reference_test2.o test_cpp.cu
+    expect_different_files reference_test1.o reference_test2.o
+
+    $ccache_nvcc_cpp -optf test1.optf test_cpp.cu
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_files reference_test1.o test_cpp.o
+
+    $ccache_nvcc_cpp -optf test1.optf test_cpp.cu
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_files reference_test1.o test_cpp.o
+
+    $ccache_nvcc_cpp -optf test2.optf test_cpp.cu
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 2
+    expect_stat 'files in cache' 2
+    expect_equal_files reference_test2.o test_cpp.o
+
+    $ccache_nvcc_cpp -optf test2.optf test_cpp.cu
+    expect_stat 'cache hit (preprocessed)' 2
+    expect_stat 'cache miss' 2
+    expect_stat 'files in cache' 2
+    expect_equal_files reference_test2.o test_cpp.o
+
+    # -------------------------------------------------------------------------
+    TEST "Option --compiler-bindir"
+
+    $REAL_NVCC $nvcc_opts_cpp --compiler-bindir $REAL_COMPILER_BIN \
+      -o reference_test1.o test_cpp.cu
+
+    # First compile.
+    $ccache_nvcc_cpp --compiler-bindir $REAL_COMPILER_BIN test_cpp.cu
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_files reference_test1.o test_cpp.o
+
+    $ccache_nvcc_cpp --compiler-bindir $REAL_COMPILER_BIN test_cpp.cu
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_files reference_test1.o test_cpp.o
+
+    # -------------------------------------------------------------------------
+    TEST "Option -ccbin"
+
+    $REAL_NVCC $nvcc_opts_cpp -ccbin $REAL_COMPILER_BIN \
+      -o reference_test1.o test_cpp.cu
+
+    # First compile.
+    $ccache_nvcc_cpp -ccbin $REAL_COMPILER_BIN test_cpp.cu
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_files reference_test1.o test_cpp.o
+
+    $ccache_nvcc_cpp -ccbin $REAL_COMPILER_BIN test_cpp.cu
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_files reference_test1.o test_cpp.o
+
+    # -------------------------------------------------------------------------
+    TEST "Option --output-directory"
+
+    $REAL_NVCC $nvcc_opts_cpp --output-directory . \
+      -o reference_test1.o test_cpp.cu
+
+    # First compile.
+    $ccache_nvcc_cpp --output-directory . test_cpp.cu
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_files reference_test1.o test_cpp.o
+
+    $ccache_nvcc_cpp --output-directory . test_cpp.cu
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_files reference_test1.o test_cpp.o
+
+    # -------------------------------------------------------------------------
+    TEST "Option -odir"
+
+    $REAL_NVCC $nvcc_opts_cpp -odir . -o reference_test1.o test_cpp.cu
+
+    # First compile.
+    $ccache_nvcc_cpp -odir . test_cpp.cu
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_files reference_test1.o test_cpp.o
+
+    $ccache_nvcc_cpp -odir . test_cpp.cu
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    expect_equal_files reference_test1.o test_cpp.o
+}
+
+SUITE_nvcc_PROBE() {
+    nvcc_PROBE
+}
+
+SUITE_nvcc_SETUP() {
+    nvcc_SETUP
+}
+
+SUITE_nvcc() {
+    nvcc_tests
+}
diff --git a/test/suites/nvcc_direct.bash b/test/suites/nvcc_direct.bash
new file mode 100644 (file)
index 0000000..613579f
--- /dev/null
@@ -0,0 +1,157 @@
+SUITE_nvcc_direct_PROBE() {
+    nvcc_PROBE
+}
+
+SUITE_nvcc_direct_SETUP() {
+    unset CCACHE_NODIRECT
+
+    nvcc_SETUP
+}
+
+SUITE_nvcc_direct() {
+    # Reference file testing was not successful due to different "fatbin" data.
+    # Another source of differences are the temporary files created by nvcc;
+    # that can be avoided by using the options "--keep --keep-dir ./keep". So
+    # instead of comparing the binary object files, we compare the dumps of
+    # cuobjdump -all -elf -symbols -ptx -sass test1.o
+    nvcc_opts_cpp="-Wno-deprecated-gpu-targets -c --x c++"
+    nvcc_opts_cuda="-Wno-deprecated-gpu-targets -c"
+    nvcc_opts_gpu1="--generate-code arch=compute_50,code=compute_50"
+    nvcc_opts_gpu2="--generate-code arch=compute_52,code=sm_52"
+    ccache_nvcc_cpp="$CCACHE $REAL_NVCC $nvcc_opts_cpp"
+    ccache_nvcc_cuda="$CCACHE $REAL_NVCC $nvcc_opts_cuda"
+    cuobjdump="$REAL_CUOBJDUMP -all -elf -symbols -ptx -sass"
+
+    # -------------------------------------------------------------------------
+    TEST "Simple mode"
+
+    $REAL_NVCC $nvcc_opts_cpp -o reference_test1.o test_cpp.cu
+
+    # First compile.
+    $ccache_nvcc_cpp test_cpp.cu
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 2
+    expect_equal_files reference_test1.o test_cpp.o
+
+    $ccache_nvcc_cpp test_cpp.cu
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 2
+    expect_equal_files reference_test1.o test_cpp.o
+
+    # -------------------------------------------------------------------------
+    TEST "Different GPU architectures"
+
+    $REAL_NVCC $nvcc_opts_cuda                 -o reference_test1.o test_cuda.cu
+    $REAL_NVCC $nvcc_opts_cuda $nvcc_opts_gpu1 -o reference_test2.o test_cuda.cu
+    $REAL_NVCC $nvcc_opts_cuda $nvcc_opts_gpu2 -o reference_test3.o test_cuda.cu
+    $cuobjdump reference_test1.o > reference_test1.dump
+    $cuobjdump reference_test2.o > reference_test2.dump
+    $cuobjdump reference_test3.o > reference_test3.dump
+    expect_different_files reference_test1.dump reference_test2.dump
+    expect_different_files reference_test1.dump reference_test3.dump
+    expect_different_files reference_test2.dump reference_test3.dump
+
+    $ccache_nvcc_cuda test_cuda.cu
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 2
+    $cuobjdump test_cuda.o > test1.dump
+    expect_equal_files reference_test1.dump test1.dump
+
+    # Other GPU.
+    $ccache_nvcc_cuda $nvcc_opts_gpu1 test_cuda.cu
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache miss' 2
+    expect_stat 'files in cache' 4
+    $cuobjdump test_cuda.o > test1.dump
+    expect_equal_files reference_test2.dump test1.dump
+
+    $ccache_nvcc_cuda $nvcc_opts_gpu1 test_cuda.cu
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache miss' 2
+    expect_stat 'files in cache' 4
+    $cuobjdump test_cuda.o > test1.dump
+    expect_equal_files reference_test2.dump test1.dump
+
+    # Another GPU.
+    $ccache_nvcc_cuda $nvcc_opts_gpu2 test_cuda.cu
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache miss' 3
+    expect_stat 'files in cache' 6
+    $cuobjdump test_cuda.o > test1.dump
+    expect_equal_files reference_test3.dump test1.dump
+
+    $ccache_nvcc_cuda $nvcc_opts_gpu2 test_cuda.cu
+    expect_stat 'cache hit (direct)' 2
+    expect_stat 'cache miss' 3
+    expect_stat 'files in cache' 6
+    $cuobjdump test_cuda.o > test1.dump
+    expect_equal_files reference_test3.dump test1.dump
+
+    # -------------------------------------------------------------------------
+    TEST "Different defines"
+
+    $REAL_NVCC $nvcc_opts_cpp            -o reference_test1.o test_cpp.cu
+    $REAL_NVCC $nvcc_opts_cpp -DNUM=10   -o reference_test2.o test_cpp.cu
+    expect_different_files reference_test1.o reference_test2.o
+
+    $ccache_nvcc_cpp test_cpp.cu
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 2
+    expect_equal_files reference_test1.o test_cpp.o
+
+    # Specified define, but unused. Can only be found by preprocessed mode.
+    $ccache_nvcc_cpp -DDUMMYENV=1 test_cpp.cu
+    expect_stat "cache hit (preprocessed)" 1
+    expect_stat "cache hit (direct)" 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 3
+    expect_equal_files reference_test1.o test_cpp.o
+
+    # Specified used define.
+    $ccache_nvcc_cpp -DNUM=10 test_cpp.cu
+    expect_stat "cache hit (direct)" 0
+    expect_stat 'cache miss' 2
+    expect_stat 'files in cache' 5
+    expect_equal_files reference_test2.o test_cpp.o
+
+    $ccache_nvcc_cpp -DNUM=10 test_cpp.cu
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache miss' 2
+    expect_stat 'files in cache' 5
+    expect_equal_files reference_test2.o test_cpp.o
+
+    # -------------------------------------------------------------------------
+    TEST "Option file"
+
+    $REAL_NVCC $nvcc_opts_cpp -optf test1.optf -o reference_test1.o test_cpp.cu
+    $REAL_NVCC $nvcc_opts_cpp -optf test2.optf -o reference_test2.o test_cpp.cu
+    expect_different_files reference_test1.o reference_test2.o
+
+    $ccache_nvcc_cpp -optf test1.optf test_cpp.cu
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 2
+    expect_equal_files reference_test1.o test_cpp.o
+
+    $ccache_nvcc_cpp -optf test1.optf test_cpp.cu
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 2
+    expect_equal_files reference_test1.o test_cpp.o
+
+    $ccache_nvcc_cpp -optf test2.optf test_cpp.cu
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache miss' 2
+    expect_stat 'files in cache' 4
+    expect_equal_files reference_test2.o test_cpp.o
+
+    $ccache_nvcc_cpp -optf test2.optf test_cpp.cu
+    expect_stat 'cache hit (direct)' 2
+    expect_stat 'cache miss' 2
+    expect_stat 'files in cache' 4
+    expect_equal_files reference_test2.o test_cpp.o
+}
diff --git a/test/suites/nvcc_ldir.bash b/test/suites/nvcc_ldir.bash
new file mode 100644 (file)
index 0000000..132684d
--- /dev/null
@@ -0,0 +1,92 @@
+SUITE_nvcc_ldir_PROBE() {
+    if [ -z "$REAL_NVCC" ]; then
+        echo "nvcc is not available"
+        return
+    elif [ -z "$REAL_CUOBJDUMP" ]; then
+        echo "cuobjdump is not available"
+        return
+    fi
+
+    nvcc_dir=$(dirname $REAL_NVCC)
+    nvcc_ldir=$nvcc_dir/../nvvm/libdevice
+    cicc_path=$nvcc_dir/../nvvm/bin
+    nvcc_idir=$nvcc_dir/../include
+    # Workaround for Canonical's Ubuntu package.
+    [ ! -d $nvcc_ldir ] && nvcc_ldir=/usr/lib/nvidia-cuda-toolkit/libdevice
+    [ ! -d $cicc_path ] && cicc_path=/usr/lib/nvidia-cuda-toolkit/bin
+    [ ! -d $nvcc_idir ] && nvcc_idir=/usr/include
+    if [ ! -d $nvcc_ldir ]; then
+        echo "libdevice directory $nvcc_ldir not found"
+    elif [ ! -d $cicc_path ]; then
+        echo "path $cicc_path not found"
+    elif [ ! -d $nvcc_idir ]; then
+        echo "include directory $nvcc_idir not found"
+    fi
+}
+
+SUITE_nvcc_ldir_SETUP() {
+    nvcc_SETUP
+}
+
+SUITE_nvcc_ldir() {
+    nvcc_opts_cuda="-Wno-deprecated-gpu-targets -c -ccbin $REAL_COMPILER_BIN"
+    ccache_nvcc_cuda="$CCACHE $REAL_NVCC $nvcc_opts_cuda"
+    cuobjdump="$REAL_CUOBJDUMP -all -elf -symbols -ptx -sass"
+    nvcc_dir=$(dirname $REAL_NVCC)
+    nvcc_ldir=$nvcc_dir/../nvvm/libdevice
+    cicc_path=$nvcc_dir/../nvvm/bin
+    nvcc_idir=$nvcc_dir/../include
+    # Workaround for Canonical's Ubuntu package.
+    [ ! -d $nvcc_ldir ] && nvcc_ldir=/usr/lib/nvidia-cuda-toolkit/libdevice
+    [ ! -d $cicc_path ] && cicc_path=/usr/lib/nvidia-cuda-toolkit/bin
+    [ ! -d $nvcc_idir ] && nvcc_idir=/usr/include
+
+    # ---------------------------------------------------------------------
+    TEST "Option --libdevice-directory"
+
+    OLD_PATH=$PATH
+    TEST_OPTS="--libdevice-directory $nvcc_ldir -I $nvcc_idir --dont-use-profile"
+    export PATH=$PATH:$cicc_path
+
+    $REAL_NVCC $nvcc_opts_cuda $TEST_OPTS -o reference_test1.o test_cuda.cu
+    $cuobjdump reference_test1.o > reference_test1.dump
+
+    # First compile.
+    $ccache_nvcc_cuda $TEST_OPTS test_cuda.cu
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    $cuobjdump test_cuda.o > test1.dump
+    expect_equal_files reference_test1.dump test1.dump
+
+    $ccache_nvcc_cuda $TEST_OPTS test_cuda.cu
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    $cuobjdump test_cuda.o > test1.dump
+    expect_equal_files reference_test1.dump test1.dump
+
+    # ---------------------------------------------------------------------
+    TEST "Option -ldir"
+
+    TEST_OPTS="-ldir $nvcc_ldir -I $nvcc_idir --dont-use-profile"
+    $REAL_NVCC $nvcc_opts_cuda $TEST_OPTS -o reference_test1.o test_cuda.cu
+    $cuobjdump reference_test1.o > reference_test1.dump
+
+    # First compile.
+    $ccache_nvcc_cuda $TEST_OPTS test_cuda.cu
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    $cuobjdump test_cuda.o > test1.dump
+    expect_equal_files reference_test1.dump test1.dump
+
+    $ccache_nvcc_cuda $TEST_OPTS test_cuda.cu
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 1
+    $cuobjdump test_cuda.o > test1.dump
+    expect_equal_files reference_test1.dump test1.dump
+
+    export PATH=$OLD_PATH
+}
diff --git a/test/suites/nvcc_nocpp2.bash b/test/suites/nvcc_nocpp2.bash
new file mode 100644 (file)
index 0000000..8af57f7
--- /dev/null
@@ -0,0 +1,12 @@
+SUITE_nvcc_nocpp2_PROBE() {
+    nvcc_PROBE
+}
+
+SUITE_nvcc_nocpp2_SETUP() {
+    export CCACHE_NOCPP2=1
+    nvcc_SETUP
+}
+
+SUITE_nvcc_nocpp2() {
+    nvcc_tests
+}
diff --git a/test/suites/pch.bash b/test/suites/pch.bash
new file mode 100644 (file)
index 0000000..34c225b
--- /dev/null
@@ -0,0 +1,541 @@
+SUITE_pch_PROBE() {
+    touch pch.h
+    if ! $REAL_COMPILER $SYSROOT -fpch-preprocess pch.h 2>/dev/null \
+            || [ ! -f pch.h.gch ]; then
+        echo "compiler ($($COMPILER --version | head -1)) doesn't support precompiled headers"
+    fi
+}
+
+SUITE_pch_SETUP() {
+    unset CCACHE_NODIRECT
+
+    cat <<EOF >pch.c
+#include "pch.h"
+int main()
+{
+  void *p = NULL;
+  return 0;
+}
+EOF
+    cat <<EOF >pch.h
+#include <stdlib.h>
+EOF
+    backdate pch.h
+    cat <<EOF >pch2.c
+int main()
+{
+  void *p = NULL;
+  return 0;
+}
+EOF
+}
+
+SUITE_pch() {
+    # Clang and GCC handle precompiled headers similarly, but GCC is much more
+    # forgiving with precompiled headers. Both GCC and Clang keep an absolute
+    # path reference to the original file except that Clang uses that reference
+    # to validate the pch and GCC ignores the reference. Also, Clang has an
+    # additional feature: pre-tokenized headers. For these reasons, Clang
+    # should be tested differently from GCC. Clang can only use pch or pth
+    # headers on the command line and not as an #include statement inside a
+    # source file.
+
+    if $COMPILER_TYPE_CLANG; then
+        pch_suite_clang
+    else
+        pch_suite_gcc
+    fi
+}
+
+pch_suite_gcc() {
+    # -------------------------------------------------------------------------
+    TEST "Create .gch, -c, no -o, without opt-in"
+
+    $CCACHE_COMPILE $SYSROOT -c pch.h
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 0
+    expect_stat "can't use precompiled header" 1
+
+    # -------------------------------------------------------------------------
+    TEST "Create .gch, no -c, -o, without opt-in"
+
+    $CCACHE_COMPILE pch.h -o pch.gch
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 0
+    expect_stat "can't use precompiled header" 1
+
+    # -------------------------------------------------------------------------
+    TEST "Create .gch, -c, no -o, with opt-in"
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines" $CCACHE_COMPILE $SYSROOT -c pch.h
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    rm pch.h.gch
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines" $CCACHE_COMPILE $SYSROOT -c pch.h
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    if [ ! -f pch.h.gch ]; then
+        test_failed "pch.h.gch missing"
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST "Create .gch, no -c, -o, with opt-in"
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT pch.h -o pch.gch
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT pch.h -o pch.gch
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    if [ ! -f pch.gch ]; then
+        test_failed "pch.gch missing"
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST "Use .gch, no -fpch-preprocess, #include"
+
+    $REAL_COMPILER $SYSROOT -c pch.h
+    backdate pch.h.gch
+    rm pch.h
+
+    $CCACHE_COMPILE $SYSROOT -c pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 0
+    # Preprocessor error because GCC can't find the real include file when
+    # trying to preprocess:
+    expect_stat 'preprocessor error' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Use .gch, no -fpch-preprocess, -include, no sloppiness"
+
+    $REAL_COMPILER $SYSROOT -c pch.h
+    backdate pch.h.gch
+    rm pch.h
+
+    $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 0
+    # Must enable sloppy time macros:
+    expect_stat "can't use precompiled header" 1
+
+    # -------------------------------------------------------------------------
+    TEST "Use .gch, no -fpch-preprocess, -include, sloppiness"
+
+    $REAL_COMPILER $SYSROOT -c pch.h
+    backdate pch.h.gch
+    rm pch.h
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Use .gch, -fpch-preprocess, #include, no sloppiness"
+
+    $REAL_COMPILER $SYSROOT -c pch.h
+    backdate pch.h.gch
+    rm pch.h
+
+    $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    # Must enable sloppy time macros:
+    expect_stat "can't use precompiled header" 1
+
+    # -------------------------------------------------------------------------
+    TEST "Use .gch, -fpch-preprocess, #include, sloppiness"
+
+    $REAL_COMPILER $SYSROOT -c pch.h
+    backdate pch.h.gch
+    rm pch.h
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Use .gch, -fpch-preprocess, #include, file changed"
+
+    $REAL_COMPILER $SYSROOT -c pch.h
+    backdate pch.h.gch
+    rm pch.h
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    echo "updated" >>pch.h.gch # GCC seems to cope with this...
+    backdate pch.h.gch
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 2
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    # -------------------------------------------------------------------------
+    TEST "Use .gch, preprocessor mode"
+
+    $REAL_COMPILER $SYSROOT -c pch.h
+    backdate pch.h.gch
+    rm pch.h
+
+    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Use .gch, preprocessor mode, file changed"
+
+    $REAL_COMPILER $SYSROOT -c pch.h
+    backdate pch.h.gch
+    rm pch.h
+
+    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    echo "updated" >>pch.h.gch # GCC seems to cope with this...
+    backdate pch.h.gch
+
+    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 2
+}
+
+pch_suite_clang() {
+    # -------------------------------------------------------------------------
+    TEST "Create .gch, -c, no -o, without opt-in"
+
+    $CCACHE_COMPILE $SYSROOT -c pch.h
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 0
+    expect_stat "can't use precompiled header" 1
+
+    # -------------------------------------------------------------------------
+    TEST "Create .gch, no -c, -o, without opt-in"
+
+    $CCACHE_COMPILE pch.h -o pch.gch
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 0
+    expect_stat "can't use precompiled header" 1
+
+    # -------------------------------------------------------------------------
+    TEST "Create .gch, -c, no -o, with opt-in"
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch.h
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    rm pch.h.gch
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch.h
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    if [ ! -f pch.h.gch ]; then
+        test_failed "pch.h.gch missing"
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST "Create .gch, no -c, -o, with opt-in"
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT pch.h -o pch.gch
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT pch.h -o pch.gch
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    if [ ! -f pch.gch ]; then
+        test_failed "pch.gch missing"
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST "Create .gch, include file mtime changed"
+
+    backdate test.h
+    cat <<EOF >pch2.h
+    #include <stdlib.h>
+    #include "test.h"
+EOF
+
+    # Make sure time_of_compilation is at least one second larger than the ctime
+    # of the test.h include, otherwise we might not cache its ctime/mtime.
+    sleep 1
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch2.h
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    touch test.h
+    sleep 1
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch2.h
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    $REAL_COMPILER $SYSROOT -c -include pch2.h pch2.c
+    if [ ! -f pch2.o ]; then
+        test_failed "pch.o missing"
+    fi
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch2.h
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    # -------------------------------------------------------------------------
+    TEST "Use .gch, no -fpch-preprocess, -include, no sloppiness"
+
+    $REAL_COMPILER $SYSROOT -c pch.h
+    backdate pch.h.gch
+
+    $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c 2>/dev/null
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 0
+    # Must enable sloppy time macros:
+    expect_stat "can't use precompiled header" 1
+
+    # -------------------------------------------------------------------------
+    TEST "Use .gch, no -fpch-preprocess, -include, sloppiness"
+
+    $REAL_COMPILER $SYSROOT -c pch.h
+    backdate pch.h.gch
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Use .gch, -fpch-preprocess, -include, file changed"
+
+    $REAL_COMPILER $SYSROOT -c pch.h
+    backdate pch.h.gch
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    echo "updated" >>pch.h.gch # clang seems to cope with this...
+    backdate pch.h.gch
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    # -------------------------------------------------------------------------
+    TEST "Use .gch, preprocessor mode"
+
+    $REAL_COMPILER $SYSROOT -c pch.h
+    backdate pch.h.gch
+
+    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Use .gch, preprocessor mode, file changed"
+
+    $REAL_COMPILER $SYSROOT -c pch.h
+    backdate pch.h.gch
+
+    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    echo "updated" >>pch.h.gch # clang seems to cope with this...
+    backdate pch.h.gch
+
+    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 2
+
+    # -------------------------------------------------------------------------
+    TEST "Create .pth, -c, -o"
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch.h -o pch.h.pth
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    rm -f pch.h.pth
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch.h -o pch.h.pth
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    if [ ! -f pch.h.pth ]; then
+        test_failed "pch.h.pth missing"
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST "Use .pth, no -fpch-preprocess, -include, no sloppiness"
+
+    $REAL_COMPILER $SYSROOT -c pch.h -o pch.h.pth
+    backdate pch.h.pth
+
+    $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 0
+    # Must enable sloppy time macros:
+    expect_stat "can't use precompiled header" 1
+
+    # -------------------------------------------------------------------------
+    TEST "Use .pth, no -fpch-preprocess, -include, sloppiness"
+
+    $REAL_COMPILER $SYSROOT -c pch.h -o pch.h.pth
+    backdate pch.h.pth
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Use .pth, -fpch-preprocess, -include, file changed"
+
+    $REAL_COMPILER $SYSROOT -c pch.h -o pch.h.pth
+    backdate pch.h.pth
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    echo "updated" >>pch.h.pth # clang seems to cope with this...
+    backdate pch.h.pth
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    # -------------------------------------------------------------------------
+    TEST "Use .pth, preprocessor mode"
+
+    $REAL_COMPILER $SYSROOT -c pch.h -o pch.h.pth
+    backdate pch.h.pth
+
+    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Use .pth, preprocessor mode, file changed"
+
+    $REAL_COMPILER $SYSROOT -c pch.h -o pch.h.pth
+    backdate pch.h.pth
+
+    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    echo "updated" >>pch.h.pth # clang seems to cope with this...
+    backdate pch.h.pth
+
+    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+
+    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 2
+}
diff --git a/test/suites/readonly.bash b/test/suites/readonly.bash
new file mode 100644 (file)
index 0000000..d44c88f
--- /dev/null
@@ -0,0 +1,82 @@
+SUITE_readonly_SETUP() {
+    generate_code 1 test.c
+    generate_code 2 test2.c
+}
+
+SUITE_readonly() {
+    # -------------------------------------------------------------------------
+    TEST "Cache hit"
+
+    # Cache a compilation.
+    $CCACHE_COMPILE -c test.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    rm test.o
+
+    # Make the cache read-only.
+    chmod -R a-w $CCACHE_DIR
+
+    # Check that read-only mode finds the cached result.
+    CCACHE_READONLY=1 CCACHE_TEMPDIR=/tmp CCACHE_PREFIX=false $CCACHE_COMPILE -c test.c
+    status1=$?
+
+    # Check that fallback to the real compiler works for a cache miss.
+    CCACHE_READONLY=1 CCACHE_TEMPDIR=/tmp $CCACHE_COMPILE -c test2.c
+    status2=$?
+
+    # Leave test dir a nice state after test failure.
+    chmod -R +w $CCACHE_DIR
+
+    if [ $status1 -ne 0 ]; then
+        test_failed "Failure when compiling test.c read-only"
+    fi
+    if [ $status2 -ne 0 ]; then
+        test_failed "Failure when compiling test2.c read-only"
+    fi
+    if [ ! -f test.o ]; then
+        test_failed "test.o missing"
+    fi
+    if [ ! -f test2.o ]; then
+        test_failed "test2.o missing"
+    fi
+
+    # -------------------------------------------------------------------------
+    TEST "Cache miss"
+
+    # Check that read-only mode doesn't try to store new results.
+    CCACHE_READONLY=1 CCACHE_TEMPDIR=/tmp $CCACHE_COMPILE -c test.c
+    if [ $? -ne 0 ]; then
+        test_failed "Failure when compiling test2.c read-only"
+    fi
+    if [ -d $CCACHE_DIR ]; then
+        test_failed "ccache dir was created"
+    fi
+
+    # -------------------------------------------------------------------------
+    # Check that read-only mode and direct mode work together.
+    TEST "Cache hit, direct"
+
+    # Cache a compilation.
+    $CCACHE_COMPILE -c test.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    rm test.o
+
+    # Make the cache read-only.
+    chmod -R a-w $CCACHE_DIR
+
+    # Direct mode should work:
+    files_before=`find $CCACHE_DIR -type f | wc -l`
+    CCACHE_DIRECT=1 CCACHE_READONLY=1 CCACHE_TEMPDIR=/tmp $CCACHE_COMPILE -c test.c
+    files_after=`find $CCACHE_DIR -type f | wc -l`
+
+    # Leave test dir a nice state after test failure.
+    chmod -R +w $CCACHE_DIR
+
+    if [ $? -ne 0 ]; then
+        test_failed "Failure when compiling test.c read-only"
+    fi
+    if [ $files_after -ne $files_before ]; then
+        test_failed "Read-only mode + direct mode stored files in the cache"
+    fi
+}
diff --git a/test/suites/readonly_direct.bash b/test/suites/readonly_direct.bash
new file mode 100644 (file)
index 0000000..b1ea4c6
--- /dev/null
@@ -0,0 +1,33 @@
+SUITE_readonly_direct_SETUP() {
+    unset CCACHE_NODIRECT
+
+    generate_code 1 test.c
+}
+
+SUITE_readonly_direct() {
+    # -------------------------------------------------------------------------
+    TEST "Direct hit"
+
+    $CCACHE_COMPILE -c test.c -o test.o
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_READONLY_DIRECT=1 $CCACHE_COMPILE -c test.c -o test.o
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Direct miss doesn't lead to preprocessed hit"
+
+    $CCACHE_COMPILE -c test.c -o test.o
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    CCACHE_READONLY_DIRECT=1 $CCACHE_COMPILE -DFOO -c test.c -o test.o
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+}
diff --git a/test/suites/serialize_diagnostics.bash b/test/suites/serialize_diagnostics.bash
new file mode 100644 (file)
index 0000000..1741adb
--- /dev/null
@@ -0,0 +1,85 @@
+SUITE_serialize_diagnostics_PROBE() {
+    touch test.c
+    if ! $REAL_COMPILER -c --serialize-diagnostics \
+         test1.dia test.c 2>/dev/null; then
+        echo "--serialize-diagnostics not supported by compiler"
+    fi
+}
+
+SUITE_serialize_diagnostics_SETUP() {
+    generate_code 1 test1.c
+}
+
+SUITE_serialize_diagnostics() {
+    # -------------------------------------------------------------------------
+    TEST "Compile OK"
+
+    $REAL_COMPILER -c --serialize-diagnostics expected.dia test1.c
+
+    $CCACHE_COMPILE -c --serialize-diagnostics test.dia test1.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 2
+    expect_equal_files expected.dia test.dia
+
+    rm test.dia
+
+    $CCACHE_COMPILE -c --serialize-diagnostics test.dia test1.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 2
+    expect_equal_files expected.dia test.dia
+
+    # -------------------------------------------------------------------------
+    TEST "Compile failed"
+
+    echo "bad source" >error.c
+    if $REAL_COMPILER -c --serialize-diagnostics expected.dia error.c 2>expected.stderr; then
+        test_failed "Expected an error compiling error.c"
+    fi
+
+    $CCACHE_COMPILE -c --serialize-diagnostics test.dia error.c 2>test.stderr
+    expect_stat 'compile failed' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 0
+    expect_stat 'files in cache' 0
+    expect_equal_files expected.dia test.dia
+    expect_equal_files expected.stderr test.stderr
+
+    # -------------------------------------------------------------------------
+    TEST "--serialize-diagnostics + CCACHE_BASEDIR"
+
+    mkdir -p dir1/src dir1/include
+    cat <<EOF >dir1/src/test.c
+#include <stdarg.h>
+#include <test.h>
+EOF
+    cat <<EOF >dir1/include/test.h
+int test;
+EOF
+    cp -r dir1 dir2
+    backdate dir1/include/test.h dir2/include/test.h
+
+    cat <<EOF >stderr.h
+int stderr(void)
+{
+  // Trigger warning by having no return statement.
+}
+EOF
+
+    unset CCACHE_NODIRECT
+
+    cd dir1
+    CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -w -MD -MF `pwd`/test.d -I`pwd`/include --serialize-diagnostics `pwd`/test.dia -c src/test.c -o `pwd`/test.o
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 4
+
+    cd ../dir2
+    CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -w -MD -MF `pwd`/test.d -I`pwd`/include --serialize-diagnostics `pwd`/test.dia -c src/test.c -o `pwd`/test.o
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 4
+}
diff --git a/test/suites/upgrade.bash b/test/suites/upgrade.bash
new file mode 100644 (file)
index 0000000..202dcd2
--- /dev/null
@@ -0,0 +1,9 @@
+SUITE_upgrade() {
+    TEST "Keep maxfiles and maxsize settings"
+
+    rm $CCACHE_CONFIGPATH
+    mkdir -p $CCACHE_DIR/0
+    echo "0 0 0 0 0 0 0 0 0 0 0 0 0 2000 131072" >$CCACHE_DIR/0/stats
+    expect_stat 'max files' 32000
+    expect_stat 'max cache size' '2.1 GB'
+}
similarity index 99%
rename from test/framework.c
rename to unittest/framework.c
index ccaa785..404367a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2016 Joel Rosdahl
+// Copyright (C) 2010-2018 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -14,7 +14,6 @@
 // this program; if not, write to the Free Software Foundation, Inc., 51
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
-#include "../ccache.h"
 #include "framework.h"
 #include "util.h"
 
similarity index 98%
rename from test/framework.h
rename to unittest/framework.h
index d1aa6a7..2f36c73 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2016 Joel Rosdahl
+// Copyright (C) 2010-2018 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -17,7 +17,7 @@
 #ifndef TEST_FRAMEWORK_H
 #define TEST_FRAMEWORK_H
 
-#include "../ccache.h"
+#include "../src/ccache.h"
 
 // ============================================================================
 
similarity index 96%
rename from test/main.c
rename to unittest/main.c
index 965ffed..7b59788 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2016 Joel Rosdahl
+// Copyright (C) 2010-2018 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -18,7 +18,7 @@
 #ifdef HAVE_GETOPT_LONG
 #include <getopt.h>
 #else
-#include "../getopt_long.h"
+#include "../src/getopt_long.h"
 #endif
 
 // *INDENT-OFF* disable uncrustify
similarity index 100%
rename from test/suites.h
rename to unittest/suites.h
similarity index 98%
rename from test/test_args.c
rename to unittest/test_args.c
index 6b11dc4..9815f14 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2016 Joel Rosdahl
+// Copyright (C) 2010-2018 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -16,7 +16,7 @@
 
 // This file contains tests for the functions operating on struct args.
 
-#include "../ccache.h"
+#include "../src/ccache.h"
 #include "framework.h"
 #include "util.h"
 
similarity index 94%
rename from test/test_argument_processing.c
rename to unittest/test_argument_processing.c
index c5ee96d..bb49913 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2017 Joel Rosdahl
+// Copyright (C) 2010-2018 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -16,8 +16,8 @@
 
 // This file contains tests for the processing of compiler arguments.
 
-#include "../ccache.h"
-#include "../conf.h"
+#include "../src/ccache.h"
+#include "../src/conf.h"
 #include "framework.h"
 #include "util.h"
 
@@ -196,6 +196,30 @@ TEST(sysroot_should_be_rewritten_if_basedir_is_used)
        args_free(act_cc);
 }
 
+TEST(sysroot_with_separate_argument_should_be_rewritten_if_basedir_is_used)
+{
+       extern char *current_working_dir;
+       char *arg_string;
+       struct args *orig;
+       struct args *act_cpp = NULL, *act_cc = NULL;
+
+       create_file("foo.c", "");
+       free(conf->base_dir);
+       conf->base_dir = get_root();
+       current_working_dir = get_cwd();
+       arg_string = format("cc --sysroot %s/foo -c foo.c", current_working_dir);
+       orig = args_init_from_string(arg_string);
+       free(arg_string);
+
+       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+       CHECK_STR_EQ(act_cpp->argv[1], "--sysroot");
+       CHECK_STR_EQ(act_cpp->argv[2], "./foo");
+
+       args_free(orig);
+       args_free(act_cpp);
+       args_free(act_cc);
+}
+
 TEST(MF_flag_with_immediate_argument_should_work_as_last_argument)
 {
        struct args *orig = args_init_from_string(
similarity index 92%
rename from test/test_compopt.c
rename to unittest/test_compopt.c
index dc1e74c..2efda50 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2016 Joel Rosdahl
+// Copyright (C) 2010-2018 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -16,8 +16,8 @@
 
 // This file contains tests for the compopt_* functions.
 
-#include "../ccache.h"
-#include "../compopt.h"
+#include "../src/ccache.h"
+#include "../src/compopt.h"
 #include "framework.h"
 
 TEST_SUITE(compopt)
@@ -70,6 +70,11 @@ TEST(dash_ftest_coverage_not_too_hard)
        CHECK(!compopt_too_hard("-ftest-coverage"));
 }
 
+TEST(dash_fstack_usage_not_too_hard)
+{
+       CHECK(!compopt_too_hard("-fstack-usage"));
+}
+
 TEST(dash_doesnexist_not_too_hard)
 {
        CHECK(!compopt_too_hard("-doesntexist"));
similarity index 98%
rename from test/test_conf.c
rename to unittest/test_conf.c
index ea43e2e..9f88133 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2016 Joel Rosdahl
+// Copyright (C) 2011-2018 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -14,7 +14,7 @@
 // this program; if not, write to the Free Software Foundation, Inc., 51
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
-#include "../conf.h"
+#include "../src/conf.h"
 #include "framework.h"
 #include "util.h"
 
@@ -342,7 +342,8 @@ TEST(conf_set_new_value)
        char *data;
 
        create_file("ccache.conf", "path = vanilla\n");
-       CHECK(conf_set_value_in_file("ccache.conf", "stats", "chocolate", &errmsg));
+       CHECKM(conf_set_value_in_file("ccache.conf", "stats", "chocolate", &errmsg),
+              errmsg);
        data = read_text_file("ccache.conf", 0);
        CHECK(data);
        CHECK_STR_EQ_FREE2("path = vanilla\nstats = chocolate\n", data);
@@ -354,7 +355,8 @@ TEST(conf_set_existing_value)
        char *data;
 
        create_file("ccache.conf", "path = chocolate\nstats = chocolate\n");
-       CHECK(conf_set_value_in_file("ccache.conf", "path", "vanilla", &errmsg));
+       CHECKM(conf_set_value_in_file("ccache.conf", "path", "vanilla", &errmsg),
+              errmsg);
        data = read_text_file("ccache.conf", 0);
        CHECK(data);
        CHECK_STR_EQ_FREE2("path = vanilla\nstats = chocolate\n", data);
similarity index 94%
rename from test/test_counters.c
rename to unittest/test_counters.c
index 1705b76..8ce4ab9 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2011 Joel Rosdahl
+// Copyright (C) 2010-2018 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -14,8 +14,8 @@
 // this program; if not, write to the Free Software Foundation, Inc., 51
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
-#include "../ccache.h"
-#include "../counters.h"
+#include "../src/ccache.h"
+#include "../src/counters.h"
 #include "framework.h"
 #include "util.h"
 
similarity index 96%
rename from test/test_hash.c
rename to unittest/test_hash.c
index 3fe3d69..674bca6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2016 Joel Rosdahl
+// Copyright (C) 2010-2018 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -16,7 +16,7 @@
 
 // This file contains tests for functions in hash.c.
 
-#include "../ccache.h"
+#include "../src/ccache.h"
 #include "framework.h"
 
 TEST_SUITE(hash)
similarity index 98%
rename from test/test_hashutil.c
rename to unittest/test_hashutil.c
index 22930c9..dcbaa84 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2016 Joel Rosdahl
+// Copyright (C) 2010-2018 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -16,8 +16,8 @@
 
 // This file contains tests for functions in hashutil.c.
 
-#include "../ccache.h"
-#include "../hashutil.h"
+#include "../src/ccache.h"
+#include "../src/hashutil.h"
 #include "framework.h"
 #include "util.h"
 
similarity index 96%
rename from test/test_lockfile.c
rename to unittest/test_lockfile.c
index cb76176..98811c6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2016 Joel Rosdahl
+// Copyright (C) 2010-2018 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -16,7 +16,7 @@
 
 // This file contains tests for functions in lockfile.c.
 
-#include "../ccache.h"
+#include "../src/ccache.h"
 #include "framework.h"
 #include "util.h"
 
similarity index 93%
rename from test/test_stats.c
rename to unittest/test_stats.c
index 2815b9e..73b39a0 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2011 Joel Rosdahl
+// Copyright (C) 2010-2018 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -16,8 +16,8 @@
 
 // This file contains tests for statistics handling.
 
-#include "../ccache.h"
-#include "../counters.h"
+#include "../src/ccache.h"
+#include "../src/counters.h"
 #include "framework.h"
 #include "util.h"
 
similarity index 98%
rename from test/test_util.c
rename to unittest/test_util.c
index dca718c..38b4419 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2016 Joel Rosdahl
+// Copyright (C) 2010-2018 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -16,7 +16,7 @@
 
 // This file contains tests for functions in util.c.
 
-#include "../ccache.h"
+#include "../src/ccache.h"
 #include "framework.h"
 
 TEST_SUITE(util)
@@ -193,7 +193,7 @@ TEST(parse_size_with_suffix)
 
        };
 
-       for (i = 0; i < sizeof(sizes) / sizeof(sizes[0]); ++i) {
+       for (i = 0; i < ARRAY_SIZE(sizes); ++i) {
                CHECKM(parse_size_with_suffix(sizes[i].size, &size), sizes[i].size);
                CHECK_INT_EQ(sizes[i].expected, size);
        }
similarity index 94%
rename from test/util.c
rename to unittest/util.c
index 826eebd..1e52c52 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2016 Joel Rosdahl
+// Copyright (C) 2010-2018 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -14,7 +14,7 @@
 // this program; if not, write to the Free Software Foundation, Inc., 51
 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
-#include "../system.h"
+#include "../src/system.h"
 #include "util.h"
 
 #ifdef _WIN32
similarity index 100%
rename from test/util.h
rename to unittest/util.h
diff --git a/version.c b/version.c
deleted file mode 100644 (file)
index 6bce7fa..0000000
--- a/version.c
+++ /dev/null
@@ -1 +0,0 @@
-const char CCACHE_VERSION[] = "3.3.6";