Imported Upstream version 3.3.5 upstream/3.3.5
authorJinWang An <jinwang.an@samsung.com>
Tue, 3 Aug 2021 07:18:15 +0000 (16:18 +0900)
committerJinWang An <jinwang.an@samsung.com>
Tue, 3 Aug 2021 07:18:15 +0000 (16:18 +0900)
20 files changed:
AUTHORS.html
AUTHORS.txt
LICENSE.html
LICENSE.txt
MANUAL.html
MANUAL.txt
NEWS.html
NEWS.txt
ccache.1
ccache.c
ccache.h
cleanup.c
getopt_long.c
manifest.c
murmurhashneutral2.c
stats.c
test.sh
test/test_argument_processing.c
util.c
version.c

index 5079e1ff197902c2a9cdee496547c6965b45f904..8894164517b8ab094e4dc7630fc6076302d14787 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.4</span>\r
+<span id="revnumber">version 3.3.5</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>
@@ -749,12 +749,17 @@ maintained by Joel Rosdahl.</p></div>
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
+Alexey Tourbin &lt;<a href="mailto:alexey.tourbin@gmail.com">alexey.tourbin@gmail.com</a>&gt;\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
 Alfred Landrum &lt;<a href="mailto:alfred.landrum@riverbed.com">alfred.landrum@riverbed.com</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Anders Björklund &lt;<a href="mailto:anders@psqr.se">anders@psqr.se</a>&gt;\r
+Anders F Björklund &lt;<a href="mailto:anders.f.bjorklund@gmail.com">anders.f.bjorklund@gmail.com</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
@@ -764,22 +769,27 @@ Andrea Bittau &lt;<a href="mailto:a.bittau@cs.ucl.ac.uk">a.bittau@cs.ucl.ac.uk</
 </li>\r
 <li>\r
 <p>\r
-Andrew P Boie &lt;<a href="mailto:andrew.p.boie@intel.com">andrew.p.boie@intel.com</a>&gt;\r
+Andreas Huber &lt;<a href="mailto:andreas.huber@deltaww.com">andreas.huber@deltaww.com</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Andrew Stubbs &lt;<a href="mailto:ams@codesourcery.com">ams@codesourcery.com</a>&gt;\r
+André Klitzing &lt;<a href="mailto:aklitzing@gmail.com">aklitzing@gmail.com</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Andrew Tridgell &lt;<a href="mailto:tridge@samba.org">tridge@samba.org</a>&gt;\r
+Andrew P Boie &lt;<a href="mailto:andrew.p.boie@intel.com">andrew.p.boie@intel.com</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-André Klitzing &lt;<a href="mailto:aklitzing@gmail.com">aklitzing@gmail.com</a>&gt;\r
+Andrew Stubbs &lt;<a href="mailto:ams@codesourcery.com">ams@codesourcery.com</a>&gt;\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Andrew Tridgell &lt;<a href="mailto:tridge@samba.org">tridge@samba.org</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
@@ -819,6 +829,11 @@ David Givone &lt;<a href="mailto:david@givone.net">david@givone.net</a>&gt;
 </li>\r
 <li>\r
 <p>\r
+Edward Z. Yang &lt;<a href="mailto:ezyang@fb.com">ezyang@fb.com</a>&gt;\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
 Eric Blau &lt;<a href="mailto:Eric.Blau@tekelec.com">Eric.Blau@tekelec.com</a>&gt;\r
 </p>\r
 </li>\r
@@ -829,6 +844,11 @@ Francois Marier &lt;<a href="mailto:francois@debian.org">francois@debian.org</a>
 </li>\r
 <li>\r
 <p>\r
+Geert Bosch &lt;<a href="mailto:geert@mongodb.com">geert@mongodb.com</a>&gt;\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
 Hongli Lai &lt;<a href="mailto:hongli@phusion.nl">hongli@phusion.nl</a>&gt;\r
 </p>\r
 </li>\r
@@ -864,12 +884,12 @@ Jon Bernard &lt;<a href="mailto:jbernard@tuxion.com">jbernard@tuxion.com</a>&gt;
 </li>\r
 <li>\r
 <p>\r
-Justin Lebar &lt;<a href="mailto:justin.lebar@gmail.com">justin.lebar@gmail.com</a>&gt;\r
+Jørgen P. Tjernø &lt;<a href="mailto:jorgen@valvesoftware.com">jorgen@valvesoftware.com</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Jørgen P. Tjernø &lt;<a href="mailto:jorgen@valvesoftware.com">jorgen@valvesoftware.com</a>&gt;\r
+Justin Lebar &lt;<a href="mailto:justin.lebar@gmail.com">justin.lebar@gmail.com</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
@@ -969,6 +989,16 @@ Norbert Lange &lt;<a href="mailto:nolange79@gmail.com">nolange79@gmail.com</a>&g
 </li>\r
 <li>\r
 <p>\r
+Oded Shimon &lt;<a href="mailto:oded@istraresearch.com">oded@istraresearch.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
+</p>\r
+</li>\r
+<li>\r
+<p>\r
 Orgad Shaneh &lt;<a href="mailto:orgad.shaneh@audiocodes.com">orgad.shaneh@audiocodes.com</a>&gt;\r
 </p>\r
 </li>\r
@@ -1004,22 +1034,22 @@ Philippe Proulx &lt;<a href="mailto:eeppeliteloop@gmail.com">eeppeliteloop@gmail
 </li>\r
 <li>\r
 <p>\r
-RW &lt;<a href="mailto:fbsd06@mlists.homeunix.com">fbsd06@mlists.homeunix.com</a>&gt;\r
+Ramiro Polla &lt;<a href="mailto:ramiro.polla@gmail.com">ramiro.polla@gmail.com</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Ramiro Polla &lt;<a href="mailto:ramiro.polla@gmail.com">ramiro.polla@gmail.com</a>&gt;\r
+Robin H. Johnson &lt;<a href="mailto:robbat2@gentoo.org">robbat2@gentoo.org</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Robin H. Johnson &lt;<a href="mailto:robbat2@gentoo.org">robbat2@gentoo.org</a>&gt;\r
+Rolf Bjarne Kvinge &lt;<a href="mailto:rolf@xamarin.com">rolf@xamarin.com</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Rolf Bjarne Kvinge &lt;<a href="mailto:rolf@xamarin.com">rolf@xamarin.com</a>&gt;\r
+RW &lt;<a href="mailto:fbsd06@mlists.homeunix.com">fbsd06@mlists.homeunix.com</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
@@ -1034,7 +1064,12 @@ Tim Potter &lt;<a href="mailto:tpot@samba.org">tpot@samba.org</a>&gt;
 </li>\r
 <li>\r
 <p>\r
-Tor Arne Vestbø &lt;<a href="mailto:torarnv@gmail.com">torarnv@gmail.com</a>&gt;\r
+Tom Hughes &lt;<a href="mailto:tomtheengineer@gmail.com">tomtheengineer@gmail.com</a>&gt;\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Tor Arne Vestbø &lt;<a href="mailto:tor.arne.vestbo@qt.io">tor.arne.vestbo@qt.io</a>&gt;\r
 </p>\r
 </li>\r
 <li>\r
@@ -1070,9 +1105,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.4<br />\r
+Version 3.3.5<br />\r
 Last updated\r
- 2017-02-17 22:27:14 CET\r
+ 2018-01-13 19:31:06 CET\r
 </div>\r
 </div>\r
 </body>\r
index ec52d852b9cb753849d789ddf8d8695347ede17b..0dc06706ebcb88222de3b07369ca6a605ec520b2 100644 (file)
@@ -6,13 +6,15 @@ maintained by Joel Rosdahl.
 
 ccache is a collective work with contributions from many people, including:
 
+* Alexey Tourbin <alexey.tourbin@gmail.com>
 * Alfred Landrum <alfred.landrum@riverbed.com>
-* Anders Björklund <anders@psqr.se>
+* Anders F Björklund <anders.f.bjorklund@gmail.com>
 * Andrea Bittau <a.bittau@cs.ucl.ac.uk>
+* Andreas Huber <andreas.huber@deltaww.com>
+* André Klitzing <aklitzing@gmail.com>
 * Andrew P Boie <andrew.p.boie@intel.com>
 * Andrew Stubbs <ams@codesourcery.com>
 * Andrew Tridgell <tridge@samba.org>
-* André Klitzing <aklitzing@gmail.com>
 * Bernhard Bauer <bauerb@chromium.org>
 * Björn Jacke <bj@sernet.de>
 * Bo Rydberg <bolry@hotmail.com>
@@ -20,8 +22,10 @@ ccache is a collective work with contributions from many people, including:
 * Chris AtLee <chris@atlee.ca>
 * 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>
 * Hongli Lai <hongli@phusion.nl>
 * Ivan Vaigult <i.vaigult@gmail.com>
 * Jiang Jiang <jiangj@opera.com>
@@ -29,8 +33,8 @@ ccache is a collective work with contributions from many people, including:
 * John Basila <jbasila@checkpoint.com>
 * John Coiner <john.coiner@amd.com>
 * Jon Bernard <jbernard@tuxion.com>
-* Justin Lebar <justin.lebar@gmail.com>
 * Jørgen P. Tjernø <jorgen@valvesoftware.com>
+* Justin Lebar <justin.lebar@gmail.com>
 * Karl Chen <quarl@cs.berkeley.edu>
 * KonaBlend <kona8lend@gmail.com>
 * Kovarththanan Rajaratnam <kovarththanan.rajaratnam@gmail.com>
@@ -50,6 +54,8 @@ ccache is a collective work with contributions from many people, including:
 * 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>
@@ -57,13 +63,14 @@ ccache is a collective work with contributions from many people, including:
 * Paul Griffith <paulg@cse.yorku.ca>
 * Pavel Boldin <pboldin@cloudlinux.com>
 * Philippe Proulx <eeppeliteloop@gmail.com>
-* RW <fbsd06@mlists.homeunix.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>
 * Tim Potter <tpot@samba.org>
-* Tor Arne Vestbø <torarnv@gmail.com>
+* Tom Hughes <tomtheengineer@gmail.com>
+* Tor Arne Vestbø <tor.arne.vestbo@qt.io>
 * Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
 * Ville Skyttä <ville.skytta@iki.fi>
 * William S Fulton <wsf@fultondesigns.co.uk>
index 6b43c897afebab3c882bcac694fcf8513d14feac..3f7ee3131901f48498f8266e6fdb192975f9fb67 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.4</span>\r
+<span id="revnumber">version 3.3.5</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>
@@ -776,7 +776,7 @@ copyrights on their portions of the work.</p></div>
 <div class="listingblock">\r
 <div class="content">\r
 <pre><code>  Copyright (C) 2002-2007 Andrew Tridgell\r
-  Copyright (C) 2009-2017 Joel Rosdahl</code></pre>\r
+  Copyright (C) 2009-2018 Joel Rosdahl</code></pre>\r
 </div></div>\r
 </div>\r
 </div>\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.4<br />\r
+Version 3.3.5<br />\r
 Last updated\r
- 2017-02-17 22:27:14 CET\r
+ 2018-01-13 19:31:27 CET\r
 </div>\r
 </div>\r
 </body>\r
index 5bf7883953095759c1852235427e206324a9c4c7..316fb8121a9a168517ed817bfb3093fa9113e01e 100644 (file)
@@ -38,7 +38,7 @@ The copyright for ccache as a whole is as follows:
 
 -------------------------------------------------------------------------------
   Copyright (C) 2002-2007 Andrew Tridgell
-  Copyright (C) 2009-2017 Joel Rosdahl
+  Copyright (C) 2009-2018 Joel Rosdahl
 -------------------------------------------------------------------------------
 
 
index 1f2e5d9899ac89313bc947044660fabdc16aa3c6..3bf053d1bf9c6ccdabc88f38b39fc437f1de8b39 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.4</span>\r
+<span id="revnumber">version 3.3.5</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>
@@ -1338,7 +1338,8 @@ might be incorrect.</p></div>
 <dd>\r
 <p>\r
     Sets the limit when cleaning up. Files are deleted (in LRU order) until the\r
-    levels are below the limit. The default is 0.8 (= 80%).\r
+    levels are below the limit. The default is 0.8 (= 80%). See\r
+    <a href="#_automatic_cleanup">AUTOMATIC CLEANUP</a> for more information.\r
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
@@ -1356,7 +1357,8 @@ might be incorrect.</p></div>
 <dd>\r
 <p>\r
     This option specifies the maximum number of files to keep in the cache. Use\r
-    0 for no limit (which is the default).\r
+    0 for no limit (which is the default). See also\r
+    <a href="#_cache_size_management">CACHE SIZE MANAGEMENT</a>.\r
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
@@ -1366,7 +1368,8 @@ might be incorrect.</p></div>
 <p>\r
     This option specifies the maximum size of the cache. Use 0 for no limit.\r
     The default value is 5G. Available suffixes: k, M, G, T (decimal) and Ki,\r
-    Mi, Gi, Ti (binary). The default suffix is "G".\r
+    Mi, Gi, Ti (binary). The default suffix is "G". See also\r
+    <a href="#_cache_size_management">CACHE SIZE MANAGEMENT</a>.\r
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
@@ -1476,7 +1479,7 @@ when compiling preprocessed source code.</p></div>
 <p>\r
     ccache normally examines a file&#8217;s contents to determine whether it matches\r
     the cached version. With this option set, ccache will consider a file as\r
-    matching its cached version if the sizes, mtimes and ctimes match.\r
+    matching its cached version if the mtimes and ctimes match.\r
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
@@ -1512,7 +1515,7 @@ when compiling preprocessed source code.</p></div>
 </dt>\r
 <dd>\r
 <p>\r
-    Be sloppy about #defines when precompiling a header file. See\r
+    Be sloppy about <strong>#define</strong>s when precompiling a header file. See\r
     <a href="#_precompiled_headers">PRECOMPILED HEADERS</a> for more information.\r
 </p>\r
 </dd>\r
@@ -1592,11 +1595,56 @@ information.</p></div>
 <div class="sect1">\r
 <h2 id="_cache_size_management">Cache size management</h2>\r
 <div class="sectionbody">\r
-<div class="paragraph"><p>By default, ccache has a five gigabyte limit on the total size of files in the\r
-cache and no maximum number of files. You can set different limits using the\r
+<div class="paragraph"><p>By default, ccache has a 5 GB limit on the total size of files in the cache and\r
+no limit on the number of files. You can set different limits using the\r
 <strong>-M</strong>/<strong>--max-size</strong> and <strong>-F</strong>/<strong>--max-files</strong> options. Use <strong>ccache -s/--show-stats</strong>\r
 to see the cache size and the currently configured limits (in addition to other\r
 various statistics).</p></div>\r
+<div class="paragraph"><p>Cleanup can be triggered in two different ways: automatic and manual.</p></div>\r
+<div class="sect2">\r
+<h3 id="_automatic_cleanup">Automatic cleanup</h3>\r
+<div class="paragraph"><p>ccache maintains counters for various statistics about the cache, including the\r
+size and number of all cached files. In order to improve performance and reduce\r
+issues with concurrent ccache invocations, there is one statistics file for\r
+each of the sixteen subdirectories in the cache.</p></div>\r
+<div class="paragraph"><p>After a new compilation result has been written to the cache, ccache will\r
+update the size and file number statistics for the subdirectory (one of\r
+sixteen) to which the result was written. Then, if the size counter for said\r
+subdirectory is greater than <strong>max_size / 16</strong> or the file number counter is\r
+greater than <strong>max_files / 16</strong>, automatic cleanup is triggered.</p></div>\r
+<div class="paragraph"><p>When automatic cleanup is triggered for a subdirectory in the cache, ccache\r
+will:</p></div>\r
+<div class="olist arabic"><ol class="arabic">\r
+<li>\r
+<p>\r
+Count all files in the subdirectory and compute their aggregated size.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Remove files in LRU (least recently used) order until the size is at most\r
+   <strong>limit_multiple * max_size / 16</strong> and the number of files is at most\r
+   <strong>limit_multiple * max_files / 16</strong>, where <strong>limit_multiple</strong>, <strong>max_size</strong> and\r
+   <strong>max_files</strong> are configuration settings.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Set the size and file number counters to match the files that were kept.\r
+</p>\r
+</li>\r
+</ol></div>\r
+<div class="paragraph"><p>The reason for removing more files than just those needed to not exceed the max\r
+limits is that a cleanup is a fairly slow operation, so it would not be a good\r
+idea to trigger it often, like after each cache miss.</p></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_manual_cleanup">Manual cleanup</h3>\r
+<div class="paragraph"><p>You can run <strong>ccache -c/--cleanup</strong> to force cleanup of the whole cache, i.e. all\r
+of the sixteen subdirectories. This will recalculate the statistics counters\r
+and make sure that the <strong>max_size</strong> and <strong>max_files</strong> settings are not exceeded.\r
+Note that <strong>limit_multiple</strong> is not taken into account for manual cleanup.</p></div>\r
+</div>\r
 </div>\r
 </div>\r
 <div class="sect1">\r
@@ -2008,7 +2056,7 @@ things to make it work properly:</p></div>
 <p>\r
 You must set <strong>sloppiness</strong> to <strong>pch_defines,time_macros</strong>. The reason is that\r
   ccache can&#8217;t tell whether <strong>__TIME__</strong> or <strong>__DATE__</strong> is used when using a\r
-  precompiled header. Further, it can&#8217;t detect changes in #defines in the\r
+  precompiled header. Further, it can&#8217;t detect changes in <strong>#define</strong>s in the\r
   source code because of how preprocessing works in combination with\r
   precompiled headers.\r
 </p>\r
@@ -2371,9 +2419,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.4<br />\r
+Version 3.3.5<br />\r
 Last updated\r
- 2017-02-12 14:58:39 CET\r
+ 2018-01-13 17:47:38 CET\r
 </div>\r
 </div>\r
 </body>\r
index c960979c20081ca1f39dbc1c74d0ad5256f81587..1d4127d02d43f2cd558b6e970cd87908628ad480 100644 (file)
@@ -407,7 +407,8 @@ might be incorrect.
 *limit_multiple* (*CCACHE_LIMIT_MULTIPLE*)::
 
     Sets the limit when cleaning up. Files are deleted (in LRU order) until the
-    levels are below the limit. The default is 0.8 (= 80%).
+    levels are below the limit. The default is 0.8 (= 80%). See
+    <<_automatic_cleanup,AUTOMATIC CLEANUP>> for more information.
 
 *log_file* (*CCACHE_LOGFILE*)::
 
@@ -417,13 +418,15 @@ might be incorrect.
 *max_files* (*CCACHE_MAXFILES*)::
 
     This option specifies the maximum number of files to keep in the cache. Use
-    0 for no limit (which is the default).
+    0 for no limit (which is the default). See also
+    <<_cache_size_management,CACHE SIZE MANAGEMENT>>.
 
 *max_size* (*CCACHE_MAXSIZE*)::
 
     This option specifies the maximum size of the cache. Use 0 for no limit.
     The default value is 5G. Available suffixes: k, M, G, T (decimal) and Ki,
-    Mi, Gi, Ti (binary). The default suffix is "G".
+    Mi, Gi, Ti (binary). The default suffix is "G". See also
+    <<_cache_size_management,CACHE SIZE MANAGEMENT>>.
 
 *path* (*CCACHE_PATH*)::
 
@@ -491,7 +494,7 @@ when compiling preprocessed source code.
 *file_stat_matches*::
     ccache normally examines a file's contents to determine whether it matches
     the cached version. With this option set, ccache will consider a file as
-    matching its cached version if the sizes, mtimes and ctimes match.
+    matching its cached version if the mtimes and ctimes match.
 *include_file_ctime*::
     By default, ccache also will not cache a file if it includes a header whose
     ctime is too new. This option disables that check.
@@ -503,7 +506,7 @@ when compiling preprocessed source code.
     With this option set, ccache will only include system headers in the hash
     but not add the system header files to the list of include files.
 *pch_defines*::
-    Be sloppy about #defines when precompiling a header file. See
+    Be sloppy about **#define**s when precompiling a header file. See
     <<_precompiled_headers,PRECOMPILED HEADERS>> for more information.
 *time_macros*::
     Ignore *\_\_DATE\__* and *\_\_TIME__* being present in the source code.
@@ -550,12 +553,52 @@ NOTE: In previous versions of ccache, *CCACHE_TEMPDIR* had to be on the same
 Cache size management
 ---------------------
 
-By default, ccache has a five gigabyte limit on the total size of files in the
-cache and no maximum number of files. You can set different limits using the
+By default, ccache has a 5 GB limit on the total size of files in the cache and
+no limit on the number of files. You can set different limits using the
 *-M*/*--max-size* and *-F*/*--max-files* options. Use *ccache -s/--show-stats*
 to see the cache size and the currently configured limits (in addition to other
 various statistics).
 
+Cleanup can be triggered in two different ways: automatic and manual.
+
+
+Automatic cleanup
+~~~~~~~~~~~~~~~~~
+
+ccache maintains counters for various statistics about the cache, including the
+size and number of all cached files. In order to improve performance and reduce
+issues with concurrent ccache invocations, there is one statistics file for
+each of the sixteen subdirectories in the cache.
+
+After a new compilation result has been written to the cache, ccache will
+update the size and file number statistics for the subdirectory (one of
+sixteen) to which the result was written. Then, if the size counter for said
+subdirectory is greater than *max_size / 16* or the file number counter is
+greater than *max_files / 16*, automatic cleanup is triggered.
+
+When automatic cleanup is triggered for a subdirectory in the cache, ccache
+will:
+
+1. Count all files in the subdirectory and compute their aggregated size.
+2. Remove files in LRU (least recently used) order until the size is at most
+   *limit_multiple * max_size / 16* and the number of files is at most
+   *limit_multiple * max_files / 16*, where *limit_multiple*, *max_size* and
+   *max_files* are configuration settings.
+3. Set the size and file number counters to match the files that were kept.
+
+The reason for removing more files than just those needed to not exceed the max
+limits is that a cleanup is a fairly slow operation, so it would not be a good
+idea to trigger it often, like after each cache miss.
+
+
+Manual cleanup
+~~~~~~~~~~~~~~
+
+You can run *ccache -c/--cleanup* to force cleanup of the whole cache, i.e. all
+of the sixteen subdirectories. This will recalculate the statistics counters
+and make sure that the *max_size* and *max_files* settings are not exceeded.
+Note that *limit_multiple* is not taken into account for manual cleanup.
+
 
 Cache compression
 -----------------
@@ -822,7 +865,7 @@ things to make it work properly:
 
 * You must set *sloppiness* to *pch_defines,time_macros*. The reason is that
   ccache can't tell whether *\_\_TIME\__* or *\_\_DATE__* is used when using a
-  precompiled header. Further, it can't detect changes in #defines in the
+  precompiled header. Further, it can't detect changes in **#define**s in the
   source code because of how preprocessing works in combination with
   precompiled headers.
 * You must either:
index 6e8af4fb19549b2916870fb38265fd1fedd7e57b..24de53dbdcdfb13556a066106b070c591dd7bed2 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.4</span>\r
+<span id="revnumber">version 3.3.5</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,94 @@ asciidoc.install(2);
 </div>\r
 <div id="content">\r
 <div class="sect1">\r
+<h2 id="_ccache_3_3_5">ccache 3.3.5</h2>\r
+<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">New features and improvements</h3>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+Documented how automatic cache cleanup works.\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
+Fixed a regression where the original order of debug options could be lost.\r
+  This reverts the &#8220;Improved parsing of <code>-g*</code> options&#8221; feature in ccache 3.3.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Multiple <code>-fdebug-prefix-map</code> options should now be handled correctly.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Fixed matching of directories in the <code>ignore_headers_in_manifest</code>\r
+  configuration option.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Fixed detection of missing argument to <code>-opt</code>/<code>--options-file</code>.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+ccache now bails out when building a precompiled header if any of the\r
+  corresponding header files have an updated timestamp. This fixes complaints\r
+  from clang.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Fixed a bug related to erroneously storing a dependency file with absolute\r
+  paths in the cache on a preprocessed hit.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>ccache -c/--cleanup</code> now works like documented: it just recalculates size\r
+  counters and trims the cache to not exceed the max size and file number\r
+  limits. Previously, the forced cleanup took &#8220;limit_multiple&#8221; into account,\r
+  so that <code>ccache -c/--cleanup</code> by default would trim the cache to 80% of the\r
+  max limit.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+ccache no longer ignores linker arguments for clang since clang warns about\r
+  them.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Plugged a couple of file descriptor leaks.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Fixed a bug where ccache would skip hashing the compiler argument following a\r
+  <code>-fno-working-directory</code>, <code>-fworking-directory</code>, <code>-nostdinc</code>, <code>-nostdinc++</code>,\r
+  <code>-remap</code> or <code>-trigraphs</code> option in preprocessor mode.\r
+</p>\r
+</li>\r
+</ul></div>\r
+</div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
 <h2 id="_ccache_3_3_4">ccache 3.3.4</h2>\r
 <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">New features and improvements</h3>\r
+<h3 id="_new_features_and_improvements_2">New features and improvements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -756,7 +839,7 @@ Documented the different cache statistics counters.
 </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
@@ -786,7 +869,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_2">Bug fixes</h3>\r
+<h3 id="_bug_fixes_3">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -803,7 +886,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_3">Bug fixes</h3>\r
+<h3 id="_bug_fixes_4">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -828,7 +911,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_4">Bug fixes</h3>\r
+<h3 id="_bug_fixes_5">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -863,7 +946,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_2">New features and improvements</h3>\r
+<h3 id="_new_features_and_improvements_3">New features and improvements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1010,7 +1093,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_5">Bug fixes</h3>\r
+<h3 id="_bug_fixes_6">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1036,7 +1119,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_6">Bug fixes</h3>\r
+<h3 id="_bug_fixes_7">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1054,7 +1137,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_7">Bug fixes</h3>\r
+<h3 id="_bug_fixes_8">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1078,7 +1161,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_8">Bug fixes</h3>\r
+<h3 id="_bug_fixes_9">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1101,7 +1184,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_9">Bug fixes</h3>\r
+<h3 id="_bug_fixes_10">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1130,7 +1213,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_3">New features and improvements</h3>\r
+<h3 id="_new_features_and_improvements_4">New features and improvements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1151,7 +1234,7 @@ Made it harder to misinterpret documentation of boolean environment settings'
 </ul></div>\r
 </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 +1294,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_11">Bug fixes</h3>\r
+<h3 id="_bug_fixes_12">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1256,7 +1339,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_4">New features and improvements</h3>\r
+<h3 id="_new_features_and_improvements_5">New features and improvements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1266,7 +1349,7 @@ Added support for compiler option <code>-gsplit-dwarf</code>.
 </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
@@ -1303,7 +1386,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_5">New features and improvements</h3>\r
+<h3 id="_new_features_and_improvements_6">New features and improvements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1320,7 +1403,7 @@ Add support for caching code coverage results (compiling for gcov).
 </ul></div>\r
 </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
@@ -1391,7 +1474,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_14">Bug fixes</h3>\r
+<h3 id="_bug_fixes_15">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1432,7 +1515,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_6">New features and improvements</h3>\r
+<h3 id="_new_features_and_improvements_7">New features and improvements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1623,7 +1706,7 @@ Various other improvements of the test suite.
 </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
@@ -1654,7 +1737,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_16">Bug fixes</h3>\r
+<h3 id="_bug_fixes_17">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1672,7 +1755,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_17">Bug fixes</h3>\r
+<h3 id="_bug_fixes_18">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1703,7 +1786,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_7">New features and improvements</h3>\r
+<h3 id="_new_features_and_improvements_8">New features and improvements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1755,7 +1838,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_18">Bug fixes</h3>\r
+<h3 id="_bug_fixes_19">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1795,7 +1878,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_19">Bug fixes</h3>\r
+<h3 id="_bug_fixes_20">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1845,7 +1928,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_8">New features and improvements</h3>\r
+<h3 id="_new_features_and_improvements_9">New features and improvements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1866,7 +1949,7 @@ Clang plugins are now hashed to catch plugin upgrades.
 </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
@@ -1914,7 +1997,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_21">Bug fixes</h3>\r
+<h3 id="_bug_fixes_22">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1987,7 +2070,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_9">New features and improvements</h3>\r
+<h3 id="_new_features_and_improvements_10">New features and improvements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -1997,7 +2080,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_22">Bug fixes</h3>\r
+<h3 id="_bug_fixes_23">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2018,7 +2101,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_10">New features and improvements</h3>\r
+<h3 id="_new_features_and_improvements_11">New features and improvements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2050,7 +2133,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_23">Bug fixes</h3>\r
+<h3 id="_bug_fixes_24">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2083,7 +2166,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_24">Bug fixes</h3>\r
+<h3 id="_bug_fixes_25">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2116,7 +2199,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_25">Bug fixes</h3>\r
+<h3 id="_bug_fixes_26">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2143,7 +2226,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_26">Bug fixes</h3>\r
+<h3 id="_bug_fixes_27">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2191,7 +2274,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_27">Bug fixes</h3>\r
+<h3 id="_bug_fixes_28">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2245,7 +2328,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_11">New features and improvements</h3>\r
+<h3 id="_new_features_and_improvements_12">New features and improvements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2313,7 +2396,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_28">Bug fixes</h3>\r
+<h3 id="_bug_fixes_29">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2399,7 +2482,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_29">Bug fixes</h3>\r
+<h3 id="_bug_fixes_30">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2445,7 +2528,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_12">New features and improvements</h3>\r
+<h3 id="_new_features_and_improvements_13">New features and improvements</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2588,7 +2671,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_30">Bug fixes</h3>\r
+<h3 id="_bug_fixes_31">Bug fixes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -2733,9 +2816,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.4<br />\r
+Version 3.3.5<br />\r
 Last updated\r
- 2017-02-17 22:28:35 CET\r
+ 2018-01-13 17:52:20 CET\r
 </div>\r
 </div>\r
 </body>\r
index e15f18cd1c2d895c5f6d0ad016593de910244071..96bdd04e5d2a66de96ba12a019e8c7bb085351af 100644 (file)
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -1,6 +1,53 @@
 ccache news
 ===========
 
+ccache 3.3.5
+------------
+Release date: 2018-01-13
+
+
+New features and improvements
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- Documented how automatic cache cleanup works.
+
+
+Bug fixes
+~~~~~~~~~
+
+- Fixed a regression where the original order of debug options could be lost.
+  This reverts the ``Improved parsing of `-g*` options'' feature in ccache 3.3.
+
+- Multiple `-fdebug-prefix-map` options should now be handled correctly.
+
+- Fixed matching of directories in the `ignore_headers_in_manifest`
+  configuration option.
+
+- Fixed detection of missing argument to `-opt`/`--options-file`.
+
+- ccache now bails out when building a precompiled header if any of the
+  corresponding header files have an updated timestamp. This fixes complaints
+  from clang.
+
+- Fixed a bug related to erroneously storing a dependency file with absolute
+  paths in the cache on a preprocessed hit.
+
+- `ccache -c/--cleanup` now works like documented: it just recalculates size
+  counters and trims the cache to not exceed the max size and file number
+  limits. Previously, the forced cleanup took ``limit_multiple'' into account,
+  so that `ccache -c/--cleanup` by default would trim the cache to 80% of the
+  max limit.
+
+- ccache no longer ignores linker arguments for clang since clang warns about
+  them.
+
+- Plugged a couple of file descriptor leaks.
+
+- Fixed a bug where ccache would skip hashing the compiler argument following a
+  `-fno-working-directory`, `-fworking-directory`, `-nostdinc`, `-nostdinc++`,
+  `-remap` or `-trigraphs` option in preprocessor mode.
+
+
 ccache 3.3.4
 ------------
 Release date: 2017-02-17
index f0de31b54c84a053fe084896df9aef03ef971444..433cf395f34921a99d0de7080cc212bfcc2b664a 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: 02/17/2017
+.\"      Date: 01/13/2018
 .\"    Manual: ccache Manual
-.\"    Source: ccache 3.3.4
+.\"    Source: ccache 3.3.5
 .\"  Language: English
 .\"
-.TH "CCACHE" "1" "02/17/2017" "ccache 3\&.3\&.4" "ccache Manual"
+.TH "CCACHE" "1" "01/13/2018" "ccache 3\&.3\&.5" "ccache Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -533,7 +533,9 @@ If true, ccache will not discard the comments before hashing preprocessor output
 .PP
 \fBlimit_multiple\fR (\fBCCACHE_LIMIT_MULTIPLE\fR)
 .RS 4
-Sets the limit when cleaning up\&. Files are deleted (in LRU order) until the levels are below the limit\&. The default is 0\&.8 (= 80%)\&.
+Sets the limit when cleaning up\&. Files are deleted (in LRU order) until the levels are below the limit\&. The default is 0\&.8 (= 80%)\&. See
+AUTOMATIC CLEANUP
+for more information\&.
 .RE
 .PP
 \fBlog_file\fR (\fBCCACHE_LOGFILE\fR)
@@ -543,12 +545,14 @@ If set to a file path, ccache will write information on what it is doing to the
 .PP
 \fBmax_files\fR (\fBCCACHE_MAXFILES\fR)
 .RS 4
-This option specifies the maximum number of files to keep in the cache\&. Use 0 for no limit (which is the default)\&.
+This option specifies the maximum number of files to keep in the cache\&. Use 0 for no limit (which is the default)\&. See also
+CACHE SIZE MANAGEMENT\&.
 .RE
 .PP
 \fBmax_size\fR (\fBCCACHE_MAXSIZE\fR)
 .RS 4
-This option specifies the maximum size of the cache\&. Use 0 for no limit\&. The default value is 5G\&. Available suffixes: k, M, G, T (decimal) and Ki, Mi, Gi, Ti (binary)\&. The default suffix is "G"\&.
+This option specifies the maximum size of the cache\&. Use 0 for no limit\&. The default value is 5G\&. Available suffixes: k, M, G, T (decimal) and Ki, Mi, Gi, Ti (binary)\&. The default suffix is "G"\&. See also
+CACHE SIZE MANAGEMENT\&.
 .RE
 .PP
 \fBpath\fR (\fBCCACHE_PATH\fR)
@@ -613,7 +617,7 @@ being present in the source\&.
 .PP
 \fBfile_stat_matches\fR
 .RS 4
-ccache normally examines a file\(cqs contents to determine whether it matches the cached version\&. With this option set, ccache will consider a file as matching its cached version if the sizes, mtimes and ctimes match\&.
+ccache normally examines a file\(cqs contents to determine whether it matches the cached version\&. With this option set, ccache will consider a file as matching its cached version if the mtimes and ctimes match\&.
 .RE
 .PP
 \fBinclude_file_ctime\fR
@@ -633,7 +637,8 @@ By default, ccache will also include all system headers in the manifest\&. With
 .PP
 \fBpch_defines\fR
 .RS 4
-Be sloppy about #defines when precompiling a header file\&. See
+Be sloppy about
+\fB#define\fRs when precompiling a header file\&. See
 PRECOMPILED HEADERS
 for more information\&.
 .RE
@@ -697,7 +702,62 @@ macro\&. Also note that enabling the unifier implies turning off the direct mode
 .RE
 .SH "CACHE SIZE MANAGEMENT"
 .sp
-By default, ccache has a five gigabyte limit on the total size of files in the cache and no maximum number of files\&. You can set different limits using the \fB\-M\fR/\fB\-\-max\-size\fR and \fB\-F\fR/\fB\-\-max\-files\fR options\&. Use \fBccache \-s/\-\-show\-stats\fR to see the cache size and the currently configured limits (in addition to other various statistics)\&.
+By default, ccache has a 5 GB limit on the total size of files in the cache and no limit on the number of files\&. You can set different limits using the \fB\-M\fR/\fB\-\-max\-size\fR and \fB\-F\fR/\fB\-\-max\-files\fR options\&. Use \fBccache \-s/\-\-show\-stats\fR to see the cache size and the currently configured limits (in addition to other various statistics)\&.
+.sp
+Cleanup can be triggered in two different ways: automatic and manual\&.
+.SS "Automatic cleanup"
+.sp
+ccache maintains counters for various statistics about the cache, including the size and number of all cached files\&. In order to improve performance and reduce issues with concurrent ccache invocations, there is one statistics file for each of the sixteen subdirectories in the cache\&.
+.sp
+After a new compilation result has been written to the cache, ccache will update the size and file number statistics for the subdirectory (one of sixteen) to which the result was written\&. Then, if the size counter for said subdirectory is greater than \fBmax_size / 16\fR or the file number counter is greater than \fBmax_files / 16\fR, automatic cleanup is triggered\&.
+.sp
+When automatic cleanup is triggered for a subdirectory in the cache, ccache will:
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 1.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP "  1." 4.2
+.\}
+Count all files in the subdirectory and compute their aggregated size\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 2.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP "  2." 4.2
+.\}
+Remove files in LRU (least recently used) order until the size is at most
+\fBlimit_multiple * max_size / 16\fR
+and the number of files is at most
+\fBlimit_multiple * max_files / 16\fR, where
+\fBlimit_multiple\fR,
+\fBmax_size\fR
+and
+\fBmax_files\fR
+are configuration settings\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 3.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP "  3." 4.2
+.\}
+Set the size and file number counters to match the files that were kept\&.
+.RE
+.sp
+The reason for removing more files than just those needed to not exceed the max limits is that a cleanup is a fairly slow operation, so it would not be a good idea to trigger it often, like after each cache miss\&.
+.SS "Manual cleanup"
+.sp
+You can run \fBccache \-c/\-\-cleanup\fR to force cleanup of the whole cache, i\&.e\&. all of the sixteen subdirectories\&. This will recalculate the statistics counters and make sure that the \fBmax_size\fR and \fBmax_files\fR settings are not exceeded\&. Note that \fBlimit_multiple\fR is not taken into account for manual cleanup\&.
 .SH "CACHE COMPRESSION"
 .sp
 ccache can optionally compress all files it puts into the cache using the compression library zlib\&. While this may involve a tiny performance slowdown, it increases the number of files that fit in the cache\&. You can turn on compression with the \fBcompression\fR configuration setting and you can also tweak the compression level with \fBcompression_level\fR\&.
@@ -1324,7 +1384,8 @@ to
 \fB__TIME__\fR
 or
 \fB__DATE__\fR
-is used when using a precompiled header\&. Further, it can\(cqt detect changes in #defines in the source code because of how preprocessing works in combination with precompiled headers\&.
+is used when using a precompiled header\&. Further, it can\(cqt detect changes in
+\fB#define\fRs in the source code because of how preprocessing works in combination with precompiled headers\&.
 .RE
 .sp
 .RS 4
index de2b1e3d53670762b206dd2eb8c3b2b2478716f7..f72a9bda2fa35e9793b1a608208be1bdb50ba9af 100644 (file)
--- a/ccache.c
+++ b/ccache.c
@@ -1,7 +1,7 @@
 // ccache -- a fast C/C++ compiler cache
 //
 // Copyright (C) 2002-2007 Andrew Tridgell
-// Copyright (C) 2009-2017 Joel Rosdahl
+// 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
@@ -37,7 +37,7 @@ static const char VERSION_TEXT[] =
   MYNAME " version %s\n"
   "\n"
   "Copyright (C) 2002-2007 Andrew Tridgell\n"
-  "Copyright (C) 2009-2017 Joel Rosdahl\n"
+  "Copyright (C) 2009-2018 Joel Rosdahl\n"
   "\n"
   "This program is free software; you can redistribute it and/or modify it under\n"
   "the terms of the GNU General Public License as published by the Free Software\n"
@@ -172,7 +172,10 @@ static bool generating_dependencies;
 static bool generating_coverage;
 
 // Relocating debuginfo in the format old=new.
-static char *debug_prefix_map = NULL;
+static char **debug_prefix_maps = NULL;
+
+// Size of debug_prefix_maps list.
+static size_t debug_prefix_maps_len = 0;
 
 // Is the compiler being asked to output coverage data (.gcda) at runtime?
 static bool profile_arcs;
@@ -194,7 +197,7 @@ static char *cpp_stderr;
 char *stats_file = NULL;
 
 // Whether the output is a precompiled header.
-static bool output_is_precompiled_header = false;
+bool output_is_precompiled_header = false;
 
 // Profile generation / usage information.
 static char *profile_dir = NULL;
@@ -557,12 +560,16 @@ remember_include_file(char *path, struct mdfour *cpp_hash, bool system)
                }
        }
 
+       // The comparison using >= is intentional, due to a possible race between
+       // starting compilation and writing the include file. See also the notes
+       // under "Performance" in MANUAL.txt.
        if (!(conf->sloppiness & SLOPPY_INCLUDE_FILE_MTIME)
            && st.st_mtime >= time_of_compilation) {
                cc_log("Include file %s too new", path);
                goto failure;
        }
 
+       // The same >= logic as above applies to the change time of the file.
        if (!(conf->sloppiness & SLOPPY_INCLUDE_FILE_CTIME)
            && st.st_ctime >= time_of_compilation) {
                cc_log("Include file %s ctime too new", path);
@@ -1548,8 +1555,8 @@ calculate_common_hash(struct args *args, struct mdfour *hash)
        // Possibly hash the current working directory.
        if (generating_debuginfo && conf->hash_dir) {
                char *cwd = gnu_getcwd();
-               if (debug_prefix_map) {
-                       char *map = debug_prefix_map;
+               for (size_t i = 0; i < debug_prefix_maps_len; i++) {
+                       char *map = debug_prefix_maps[i];
                        char *sep = strchr(map, '=');
                        if (sep) {
                                char *old = x_strndup(map, sep - map);
@@ -1632,19 +1639,23 @@ calculate_object_hash(struct args *args, struct mdfour *hash, int direct_mode)
                hash_int(hash, MANIFEST_VERSION);
        }
 
+       // clang will emit warnings for unused linker flags, so we shouldn't skip
+       // those arguments.
+       int is_clang = compiler_is_clang(args);
+
        // First the arguments.
        for (int i = 1; i < args->argc; i++) {
-               // -L doesn't affect compilation.
-               if (i < args->argc-1 && str_eq(args->argv[i], "-L")) {
+               // -L doesn't affect compilation (except for clang).
+               if (i < args->argc-1 && str_eq(args->argv[i], "-L") && !is_clang) {
                        i++;
                        continue;
                }
-               if (str_startswith(args->argv[i], "-L")) {
+               if (str_startswith(args->argv[i], "-L") && !is_clang) {
                        continue;
                }
 
-               // -Wl,... doesn't affect compilation.
-               if (str_startswith(args->argv[i], "-Wl,")) {
+               // -Wl,... doesn't affect compilation (except for clang).
+               if (str_startswith(args->argv[i], "-Wl,") && !is_clang) {
                        continue;
                }
 
@@ -1662,7 +1673,9 @@ calculate_object_hash(struct args *args, struct mdfour *hash, int direct_mode)
                if (!direct_mode && !output_is_precompiled_header
                    && !using_precompiled_header) {
                        if (compopt_affects_cpp(args->argv[i])) {
-                               i++;
+                               if (compopt_takes_arg(args->argv[i])) {
+                                       i++;
+                               }
                                continue;
                        }
                        if (compopt_short(compopt_affects_cpp, args->argv[i])) {
@@ -1863,15 +1876,19 @@ from_cache(enum fromcache_call_mode mode, bool put_object_in_manifest)
                return;
        }
 
-       struct stat st;
-       if (stat(cached_obj, &st) != 0) {
-               cc_log("Object file %s not in cache", cached_obj);
+       // We can't trust the objects based on running the preprocessor
+       // when the output is precompiled headers, as the hash does not
+       // include the mtime of each included header, breaking compilation
+       // with clang when the precompiled header is used after touching
+       // one of the included files.
+       if (output_is_precompiled_header && mode == FROMCACHE_CPP_MODE) {
+               cc_log("Not using preprocessed cached object for precompiled header");
                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);
+       struct stat st;
+       if (stat(cached_obj, &st) != 0) {
+               cc_log("Object file %s not in cache", cached_obj);
                return;
        }
 
@@ -1910,6 +1927,12 @@ from_cache(enum fromcache_call_mode mode, bool put_object_in_manifest)
                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.
        if (!str_eq(output_obj, "/dev/null")) {
@@ -1947,11 +1970,6 @@ from_cache(enum fromcache_call_mode mode, bool put_object_in_manifest)
                update_mtime(cached_dwo);
        }
 
-       if (generating_dependencies && mode == FROMCACHE_CPP_MODE
-           && !conf->read_only && !conf->read_only_direct) {
-               put_file_in_cache(output_dep, cached_dep);
-       }
-
        send_cached_stderr();
 
        if (put_object_in_manifest) {
@@ -2110,8 +2128,6 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
        struct args *dep_args = args_init(0, NULL);
 
        bool found_color_diagnostics = false;
-       int debug_level = 0;
-       const char *debug_argument = NULL;
 
        int argc = expanded_args->argc;
        char **argv = expanded_args->argv;
@@ -2162,8 +2178,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 (i > argc) {
-                               cc_log("Expected argument after -optf/--options-file");
+                       if (i == argc - 1) {
+                               cc_log("Expected argument after %s", argv[i]);
                                stats_update(STATS_ARGS);
                                result = false;
                                goto out;
@@ -2264,7 +2280,7 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                // Special handling for -x: remember the last specified language before the
                // input file and strip all -x options from the arguments.
                if (str_eq(argv[i], "-x")) {
-                       if (i == argc-1) {
+                       if (i == argc - 1) {
                                cc_log("Missing argument to %s", argv[i]);
                                stats_update(STATS_ARGS);
                                result = false;
@@ -2285,7 +2301,7 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
 
                // We need to work out where the output was meant to go.
                if (str_eq(argv[i], "-o")) {
-                       if (i == argc-1) {
+                       if (i == argc - 1) {
                                cc_log("Missing argument to %s", argv[i]);
                                stats_update(STATS_ARGS);
                                result = false;
@@ -2309,7 +2325,10 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                        continue;
                }
                if (str_startswith(argv[i], "-fdebug-prefix-map=")) {
-                       debug_prefix_map = x_strdup(argv[i] + 19);
+                       debug_prefix_maps = x_realloc(
+                               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;
                }
@@ -2317,32 +2336,17 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                // Debugging is handled specially, so that we know if we can strip line
                // number info.
                if (str_startswith(argv[i], "-g")) {
-                       const char *pLevel = argv[i] + 2;
-                       if (str_startswith(argv[i], "-ggdb")) {
-                               pLevel = argv[i] + 5;
-                       } else if (str_startswith(argv[i], "-gstabs")) {
-                               pLevel = argv[i] + 7;
-                       } else if (str_startswith(argv[i], "-gcoff")) {
-                               pLevel = argv[i] + 6;
-                       } else if (str_startswith(argv[i], "-gxcoff")) {
-                               pLevel = argv[i] + 7;
-                       } else if (str_startswith(argv[i], "-gvms")) {
-                               pLevel = argv[i] + 5;
-                       }
-
-                       // Deduce level from argument, default is 2.
-                       int foundlevel = -1;
-                       if (pLevel[0] == '\0') {
-                               foundlevel = 2;
-                       } else if (pLevel[0] >= '0' && pLevel[0] <= '9') {
-                               foundlevel = atoi(pLevel);
-                       }
-
-                       if (foundlevel >= 0) {
-                               debug_level = foundlevel;
-                               debug_argument = argv[i];
-                               continue;
+                       generating_debuginfo = true;
+                       args_add(stripped_args, argv[i]);
+                       if (conf->unify && !str_eq(argv[i], "-g0")) {
+                               cc_log("%s used; disabling unify mode", argv[i]);
+                               conf->unify = false;
                        }
+                       if (str_eq(argv[i], "-g3")) {
+                               cc_log("%s used; not compiling preprocessed code", argv[i]);
+                               conf->run_second_cpp = true;
+                       }
+                       continue;
                }
 
                // These options require special handling, because they behave differently
@@ -2360,7 +2364,7 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                        bool separate_argument = (strlen(argv[i]) == 3);
                        if (separate_argument) {
                                // -MF arg
-                               if (i >= argc - 1) {
+                               if (i == argc - 1) {
                                        cc_log("Missing argument to %s", argv[i]);
                                        stats_update(STATS_ARGS);
                                        result = false;
@@ -2390,7 +2394,7 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                        char *relpath;
                        if (strlen(argv[i]) == 3) {
                                // -MQ arg or -MT arg
-                               if (i >= argc - 1) {
+                               if (i == argc - 1) {
                                        cc_log("Missing argument to %s", argv[i]);
                                        stats_update(STATS_ARGS);
                                        result = false;
@@ -2507,7 +2511,7 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                }
 
                if (str_eq(argv[i], "--serialize-diagnostics")) {
-                       if (i >= argc - 1) {
+                       if (i == argc - 1) {
                                cc_log("Missing argument to %s", argv[i]);
                                stats_update(STATS_ARGS);
                                result = false;
@@ -2597,7 +2601,7 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                // to get better hit rate. A secondary effect is that paths in the standard
                // error output produced by the compiler will be normalized.
                if (compopt_takes_path(argv[i])) {
-                       if (i == argc-1) {
+                       if (i == argc - 1) {
                                cc_log("Missing argument to %s", argv[i]);
                                stats_update(STATS_ARGS);
                                result = false;
@@ -2649,7 +2653,7 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
 
                // Options that take an argument.
                if (compopt_takes_arg(argv[i])) {
-                       if (i == argc-1) {
+                       if (i == argc - 1) {
                                cc_log("Missing argument to %s", argv[i]);
                                stats_update(STATS_ARGS);
                                result = false;
@@ -2726,19 +2730,6 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                }
        } // for
 
-       if (debug_level > 0) {
-               generating_debuginfo = true;
-               args_add(stripped_args, debug_argument);
-               if (conf->unify) {
-                       cc_log("%s used; disabling unify mode", debug_argument);
-                       conf->unify = false;
-               }
-               if (debug_level >= 3 && !conf->run_second_cpp) {
-                       cc_log("%s used; not compiling preprocessed code", debug_argument);
-                       conf->run_second_cpp = true;
-               }
-       }
-
        if (found_S_opt) {
                // Even if -gsplit-dwarf is given, the .dwo file is not generated when -S
                // is also given.
@@ -3092,7 +3083,12 @@ cc_reset(void)
        free(primary_config_path); primary_config_path = NULL;
        free(secondary_config_path); secondary_config_path = NULL;
        free(current_working_dir); current_working_dir = NULL;
-       free(debug_prefix_map); debug_prefix_map = NULL;
+       for (size_t i = 0; i < debug_prefix_maps_len; i++) {
+               free(debug_prefix_maps[i]);
+               debug_prefix_maps[i] = NULL;
+       }
+       free(debug_prefix_maps); debug_prefix_maps = NULL;
+       debug_prefix_maps_len = 0;
        free(profile_dir); profile_dir = NULL;
        free(included_pch_file); included_pch_file = NULL;
        args_free(orig_args); orig_args = NULL;
@@ -3142,6 +3138,7 @@ static void
 setup_uncached_err(void)
 {
        int uncached_fd = dup(2);
+       set_cloexec_flag(uncached_fd);
        if (uncached_fd == -1) {
                cc_log("dup(2) failed: %s", strerror(errno));
                failed();
@@ -3352,7 +3349,7 @@ ccache_main_options(int argc, char *argv[])
 
                case 'c': // --cleanup
                        initialize();
-                       cleanup_all(conf);
+                       clean_up_all(conf);
                        printf("Cleaned cache\n");
                        break;
 
index 8b738aba0c10e8bc52aa6d93a472c43e45dcf1f0..229f8b4ac83f3a0ee432f00548afc6b7d634af85 100644 (file)
--- a/ccache.h
+++ b/ccache.h
@@ -184,6 +184,7 @@ char *x_readlink(const char *path);
 bool read_file(const char *path, size_t size_hint, char **data, size_t *size);
 char *read_text_file(const char *path, size_t size_hint);
 char *subst_env_in_string(const char *str, char **errmsg);
+void set_cloexec_flag(int fd);
 
 // ----------------------------------------------------------------------------
 // stats.c
@@ -217,8 +218,8 @@ void exitfn_call(void);
 // ----------------------------------------------------------------------------
 // cleanup.c
 
-void cleanup_dir(struct conf *conf, const char *dir);
-void cleanup_all(struct conf *conf);
+void clean_up_dir(struct conf *conf, const char *dir, float limit_multiple);
+void clean_up_all(struct conf *conf);
 void wipe_all(struct conf *conf);
 
 // ----------------------------------------------------------------------------
@@ -238,6 +239,7 @@ void lockfile_release(const char *path);
 // ccache.c
 
 extern time_t time_of_compilation;
+extern bool output_is_precompiled_header;
 void block_signals(void);
 void unblock_signals(void);
 bool cc_process_args(struct args *args, struct args **preprocessor_args,
@@ -279,12 +281,12 @@ void add_exe_ext_if_no_to_fullpath(char *full_path_win_ext, size_t max_size,
 #    define lstat(a,b) stat(a,b)
 #    define execv(a,b) win32execute(a,b,0,-1,-1)
 #    define execute(a,b,c,d) win32execute(*(a),a,1,b,c)
-#    define DIR_DELIM_CH '/'
+#    define DIR_DELIM_CH '\\'
 #    define PATH_DELIM ";"
 #    define F_RDLCK 0
 #    define F_WRLCK 0
 #else
-#    define DIR_DELIM_CH '\\'
+#    define DIR_DELIM_CH '/'
 #    define PATH_DELIM ":"
 #endif
 
index 428a64b52b4dcb5072833c5d14f18938dc976e08..458408264c19320b9be2dd9d4853efd17234ed6b 100644 (file)
--- a/cleanup.c
+++ b/cleanup.c
@@ -1,5 +1,5 @@
 // Copyright (C) 2002-2006 Andrew Tridgell
-// Copyright (C) 2009-2016 Joel Rosdahl
+// 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
@@ -170,15 +170,15 @@ sort_and_clean(void)
 
 // Clean up one cache subdirectory.
 void
-cleanup_dir(struct conf *conf, const char *dir)
+clean_up_dir(struct conf *conf, const char *dir, float limit_multiple)
 {
        cc_log("Cleaning up cache directory %s", dir);
 
        // When "max files" or "max cache size" is reached, one of the 16 cache
        // subdirectories is cleaned up. When doing so, files are deleted (in LRU
        // order) until the levels are below limit_multiple.
-       cache_size_threshold = conf->max_size * conf->limit_multiple / 16;
-       files_in_cache_threshold = conf->max_files * conf->limit_multiple / 16;
+       cache_size_threshold = conf->max_size * limit_multiple / 16;
+       files_in_cache_threshold = conf->max_files * limit_multiple / 16;
 
        num_files = 0;
        cache_size = 0;
@@ -194,6 +194,9 @@ cleanup_dir(struct conf *conf, const char *dir)
                stats_add_cleanup(dir, 1);
        }
 
+       cc_log("After cleanup: %lu KiB, %zu files",
+              (unsigned long)cache_size / 1024,
+              files_in_cache);
        stats_set_sizes(dir, files_in_cache, cache_size);
 
        // Free it up.
@@ -214,11 +217,11 @@ cleanup_dir(struct conf *conf, const char *dir)
 }
 
 // Clean up all cache subdirectories.
-void cleanup_all(struct conf *conf)
+void clean_up_all(struct conf *conf)
 {
        for (int i = 0; i <= 0xF; i++) {
                char *dname = format("%s/%1x", conf->cache_dir, i);
-               cleanup_dir(conf, dname);
+               clean_up_dir(conf, dname, 1.0);
                free(dname);
        }
 }
@@ -271,5 +274,5 @@ void wipe_all(struct conf *conf)
        }
 
        // Fix the counters.
-       cleanup_all(conf);
+       clean_up_all(conf);
 }
index e426b1aefa06fcd15fbca114941786ff2a3326fd..61141c236b5241c724bfb4e1b8bf1d98a2e91a03 100644 (file)
@@ -72,14 +72,14 @@ getopt_long(int argc, char *const argv[],
 
                place++;
 
-               if (place[0] && place[0] == '-' && place[1] == '\0')
+               if (place[0] == '-' && place[1] == '\0')
                { /* found "--" */
                        ++optind;
                        place = EMSG;
                        return -1;
                }
 
-               if (place[0] && place[0] == '-' && place[1])
+               if (place[0] == '-' && place[1])
                {
                        /* long option */
                        size_t namelen;
index 7c019e18395502e1f99ed222206653745b06fb73..5cd3ead2ad76c9cda88e68c8d7201580f083b601 100644 (file)
@@ -377,18 +377,23 @@ verify_object(struct conf *conf, struct manifest *mf, struct object *obj,
                        hashtable_insert(stated_files, x_strdup(path), st);
                }
 
+               if (fi->size != st->size) {
+                       return 0;
+               }
+
+               // Clang stores the mtime of the included files in the precompiled header,
+               // and will error out if that header is later used without rebuilding.
+               if (output_is_precompiled_header && fi->mtime != st->mtime) {
+                       cc_log("Precompiled header includes %s, which has a new mtime", path);
+                       return 0;
+               }
+
                if (conf->sloppiness & SLOPPY_FILE_STAT_MATCHES) {
-                       // st->ctime is sometimes 0, so we can't check that both st->ctime and
-                       // st->mtime are greater than time_of_compilation. But it's sufficient to
-                       // check that either is.
-                       if (fi->size == st->size
-                           && fi->mtime == st->mtime
-                           && fi->ctime == st->ctime
-                           && MAX(st->mtime, st->ctime) >= time_of_compilation) {
-                               cc_log("size/mtime/ctime hit for %s", path);
+                       if (fi->mtime == st->mtime && fi->ctime == st->ctime) {
+                               cc_log("mtime/ctime hit for %s", path);
                                continue;
                        } else {
-                               cc_log("size/mtime/ctime miss for %s", path);
+                               cc_log("mtime/ctime miss for %s", path);
                        }
                }
 
index 53319dfb658bdf439b9e7f9a00c1c21bdeda9bd8..d63e0a12022fcd6f514685546413f53b97b561d6 100644 (file)
@@ -30,8 +30,8 @@ murmurhashneutral2(const void *key, int len, unsigned int seed)
 
        switch (len)
        {
-       case 3: h ^= ((unsigned int) data[2]) << 16;
-       case 2: h ^= ((unsigned int) data[1]) << 8;
+       case 3: h ^= ((unsigned int) data[2]) << 16; // Fallthrough.
+       case 2: h ^= ((unsigned int) data[1]) << 8; // Fallthrough.
        case 1: h ^= ((unsigned int) data[0]);
                h *= m;
        };
diff --git a/stats.c b/stats.c
index 5d9fc737885001b5ff822be01eccd481c3105226..0ed203d3e9a5ced967c8b9031b78b2e3792c1d54 100644 (file)
--- a/stats.c
+++ b/stats.c
@@ -1,5 +1,5 @@
 // Copyright (C) 2002-2004 Andrew Tridgell
-// Copyright (C) 2009-2016 Joel Rosdahl
+// 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
@@ -374,22 +374,31 @@ stats_flush(void)
                }
        }
 
+       char *subdir = dirname(stats_file);
        bool need_cleanup = false;
+
        if (conf->max_files != 0
            && counters->data[STATS_NUMFILES] > conf->max_files / 16) {
+               cc_log("Need to clean up %s since it holds %u files (limit: %u files)",
+                      subdir,
+                      counters->data[STATS_NUMFILES],
+                      conf->max_files / 16);
                need_cleanup = true;
        }
        if (conf->max_size != 0
            && counters->data[STATS_TOTALSIZE] > conf->max_size / 1024 / 16) {
+               cc_log("Need to clean up %s since it holds %u KiB (limit: %lu KiB)",
+                      subdir,
+                      counters->data[STATS_TOTALSIZE],
+                      (unsigned long)conf->max_size / 1024 / 16);
                need_cleanup = true;
        }
 
        if (need_cleanup) {
-               char *p = dirname(stats_file);
-               cleanup_dir(conf, p);
-               free(p);
+               clean_up_dir(conf, subdir, conf->limit_multiple);
        }
 
+       free(subdir);
        counters_free(counters);
 }
 
diff --git a/test.sh b/test.sh
index b4c95b1af528abbd75a5eac8014a4c646a80b961..b2d6bf9f007ae29c3ea5121904a861b100894e86 100755 (executable)
--- a/test.sh
+++ b/test.sh
@@ -3,7 +3,7 @@
 # A simple test suite for ccache.
 #
 # Copyright (C) 2002-2007 Andrew Tridgell
-# Copyright (C) 2009-2017 Joel Rosdahl
+# 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
@@ -37,7 +37,7 @@ test_failed() {
     echo
     echo "Test suite:     $(bold $CURRENT_SUITE)"
     echo "Test case:      $(bold $CURRENT_TEST)"
-    echo "Failure reason: $(red $1)"
+    echo "Failure reason: $(red "$1")"
     echo
     echo "ccache -s:"
     $CCACHE -s
@@ -140,28 +140,28 @@ expect_file_count() {
 }
 
 run_suite() {
-    local name=$1
+    local suite_name=$1
 
-    CURRENT_SUITE=$name
+    CURRENT_SUITE=$suite_name
     UNCACHED_COMPILE=uncached_compile
 
     cd $ABS_TESTDIR
     rm -rf $ABS_TESTDIR/fixture
 
-    if type SUITE_${name}_PROBE >/dev/null 2>&1; then
+    if type SUITE_${suite_name}_PROBE >/dev/null 2>&1; then
         mkdir $ABS_TESTDIR/probe
         cd $ABS_TESTDIR/probe
-        local skip_reason="$(SUITE_${name}_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 $name [$skip_reason]"
+            echo "Skipped test suite $suite_name [$skip_reason]"
             return
         fi
     fi
 
-    printf "Running test suite %s" "$(bold $name)"
-    SUITE_$name
+    printf "Running test suite %s" "$(bold $suite_name)"
+    SUITE_$suite_name
     echo
 }
 
@@ -174,34 +174,11 @@ uncached_compile() {
 TEST() {
     CURRENT_TEST=$1
 
-    unset CCACHE_BASEDIR
-    unset CCACHE_CC
-    unset CCACHE_COMMENTS
-    unset CCACHE_COMPILERCHECK
-    unset CCACHE_COMPRESS
-    unset CCACHE_CPP2
-    unset CCACHE_DIR
-    unset CCACHE_DISABLE
-    unset CCACHE_EXTENSION
-    unset CCACHE_EXTRAFILES
-    unset CCACHE_HARDLINK
-    unset CCACHE_IGNOREHEADERS
-    unset CCACHE_LIMIT_MULTIPLE
-    unset CCACHE_LOGFILE
-    unset CCACHE_NLEVELS
-    unset CCACHE_NOCPP2
-    unset CCACHE_NOHASHDIR
-    unset CCACHE_NOSTATS
-    unset CCACHE_PATH
-    unset CCACHE_PREFIX
-    unset CCACHE_PREFIX_CPP
-    unset CCACHE_READONLY
-    unset CCACHE_READONLY_DIRECT
-    unset CCACHE_RECACHE
-    unset CCACHE_SLOPPINESS
-    unset CCACHE_TEMPDIR
-    unset CCACHE_UMASK
-    unset CCACHE_UNIFY
+    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
@@ -218,7 +195,7 @@ TEST() {
     CCACHE_COMPILE="$CCACHE $COMPILER"
 
     if $VERBOSE; then
-        printf "\n  %s" $CURRENT_TEST
+        printf "\n  %s" "$CURRENT_TEST"
     else
         printf .
     fi
@@ -228,8 +205,8 @@ TEST() {
     rm -rf $ABS_TESTDIR/run
     mkdir $ABS_TESTDIR/run
     cd $ABS_TESTDIR/run
-    if type SUITE_${name}_SETUP >/dev/null 2>&1; then
-        SUITE_${name}_SETUP
+    if type SUITE_${suite_name}_SETUP >/dev/null 2>&1; then
+        SUITE_${suite_name}_SETUP
     fi
 }
 
@@ -1280,7 +1257,7 @@ EOF
 # =============================================================================
 
 SUITE_debug_prefix_map_PROBE() {
-    if ! $COMPILER_TYPE_GCC || $COMPILER_USES_MINGW; then
+    if $COMPILER_USES_MINGW; then
         echo "-fdebug-prefix-map not supported by compiler"
     fi
 }
@@ -1323,6 +1300,32 @@ SUITE_debug_prefix_map() {
     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
 }
 
 # =============================================================================
@@ -2231,20 +2234,41 @@ EOF
     expect_stat 'cache miss' 2
 
     # -------------------------------------------------------------------------
-    TEST "CCACHE_IGNOREHEADERS"
+    TEST "CCACHE_IGNOREHEADERS with filename"
 
-    cat <<EOF >ignore.h
+    mkdir subdir
+    cat <<EOF >subdir/ignore.h
 // We don't want this header in the manifest.
 EOF
-    backdate ignore.h
+    backdate subdir/ignore.h
     cat <<EOF >ignore.c
-#include "ignore.h"
+#include "subdir/ignore.h"
 int foo;
 EOF
 
-    CCACHE_IGNOREHEADERS="ignore.h" $CCACHE_COMPILE -c ignore.c
+    CCACHE_IGNOREHEADERS="subdir/ignore.h" $CCACHE_COMPILE -c ignore.c
     manifest=`find $CCACHE_DIR -name '*.manifest'`
-    data="`$CCACHE --dump-manifest $manifest | grep ignore.h`"
+    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
@@ -2307,9 +2331,13 @@ SUITE_basedir() {
     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 correctly:
-    CCACHE_BASEDIR=`pwd` $CCACHE_COMPILE -I`pwd`//include -c `pwd`//src/test.c
+    # 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
@@ -2593,10 +2621,22 @@ SUITE_cleanup() {
 
     prepare_cleanup_test_dir $CCACHE_DIR/a
 
-    # (9/10) * 30 * 16 = 432
-    $CCACHE -F 432 -M 0 >/dev/null
+    # 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
-    # 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
@@ -2627,10 +2667,8 @@ SUITE_cleanup() {
 
     prepare_cleanup_test_dir $CCACHE_DIR/a
 
-    # (4/10) * 10 * 4 * 16 = 256
     $CCACHE -F 0 -M 256K >/dev/null
-    $CCACHE -c >/dev/null
-    # floor(0.8 * 4) = 3
+    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
@@ -2650,22 +2688,45 @@ SUITE_cleanup() {
     done
 
     # -------------------------------------------------------------------------
-    TEST "Automatic cache cleanup"
+    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
 
-    # (9/10) * 30 * 16 = 432
-    $CCACHE -F 432 -M 0 >/dev/null
+    $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_COMPILE -c empty.c -o empty.o
-    # floor(0.8 * 9) = 7
+    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
@@ -2677,8 +2738,7 @@ SUITE_cleanup() {
 
     prepare_cleanup_test_dir $CCACHE_DIR/a
 
-    # (9/10) * 30 * 16 = 432
-    $CCACHE -F 432 -M 0 >/dev/null
+    $CCACHE -F 336 -M 0 >/dev/null
     backdate $CCACHE_DIR/a/result2-4017.stderr
     $CCACHE -c >/dev/null
     # floor(0.8 * 9) = 7
@@ -2707,26 +2767,29 @@ SUITE_cleanup() {
     touch $CCACHE_DIR/a/abcd.unknown
     $CCACHE -F 0 -M 0 -c >/dev/null # update counters
     expect_stat 'files in cache' 31
-    # (9/10) * 30 * 16 = 432
-    $CCACHE -F 432 -M 0 >/dev/null
+
+    $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' 19
+    expect_stat 'files in cache' 28
 
     # -------------------------------------------------------------------------
     TEST "Cleanup of old unknown file"
 
     prepare_cleanup_test_dir $CCACHE_DIR/a
-    # (9/10) * 30 * 16 = 432
-    $CCACHE -F 432 -M 0 >/dev/null
+    $CCACHE -F 480 -M 0 >/dev/null
     touch $CCACHE_DIR/a/abcd.unknown
     backdate $CCACHE_DIR/a/abcd.unknown
-    $CCACHE -c >/dev/null
+    $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"
@@ -2752,16 +2815,6 @@ SUITE_cleanup() {
     $CCACHE -c >/dev/null
     expect_file_count 1 '.nfs*' $CCACHE_DIR
     expect_stat 'files in cache' 30
-
-    # -------------------------------------------------------------------------
-    TEST "CCACHE_LIMIT_MULTIPLE"
-
-    prepare_cleanup_test_dir $CCACHE_DIR/a
-
-    # (1/1) * 30 * 16 = 480
-    $CCACHE -F 480 >/dev/null
-    CCACHE_LIMIT_MULTIPLE=0.5 $CCACHE -c >/dev/null
-    expect_stat 'files in cache' 15
 }
 
 # =============================================================================
@@ -2837,13 +2890,13 @@ pch_suite_gcc() {
     # -------------------------------------------------------------------------
     TEST "Create .gch, -c, no -o, with opt-in"
 
-    CCACHE_SLOPPINESS=pch_defines $CCACHE_COMPILE $SYSROOT -c pch.h
+    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=pch_defines $CCACHE_COMPILE $SYSROOT -c pch.h
+    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
@@ -2854,12 +2907,12 @@ pch_suite_gcc() {
     # -------------------------------------------------------------------------
     TEST "Create .gch, no -c, -o, with opt-in"
 
-    CCACHE_SLOPPINESS=pch_defines,time_macros $CCACHE_COMPILE $SYSROOT pch.h -o pch.gch
+    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=pch_defines,time_macros $CCACHE_COMPILE $SYSROOT pch.h -o pch.gch
+    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
@@ -3038,13 +3091,13 @@ pch_suite_clang() {
     # -------------------------------------------------------------------------
     TEST "Create .gch, -c, no -o, with opt-in"
 
-    CCACHE_SLOPPINESS=pch_defines,time_macros $CCACHE_COMPILE $SYSROOT -c pch.h
+    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=pch_defines,time_macros $CCACHE_COMPILE $SYSROOT -c pch.h
+    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
@@ -3055,12 +3108,12 @@ pch_suite_clang() {
     # -------------------------------------------------------------------------
     TEST "Create .gch, no -c, -o, with opt-in"
 
-    CCACHE_SLOPPINESS=pch_defines,time_macros $CCACHE_COMPILE $SYSROOT pch.h -o pch.gch
+    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=pch_defines,time_macros $CCACHE_COMPILE $SYSROOT pch.h -o pch.gch
+    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
@@ -3068,6 +3121,42 @@ pch_suite_clang() {
         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"
 
@@ -3164,13 +3253,13 @@ pch_suite_clang() {
     # -------------------------------------------------------------------------
     TEST "Create .pth, -c, -o"
 
-    CCACHE_SLOPPINESS=pch_defines,time_macros $CCACHE_COMPILE $SYSROOT -c pch.h -o 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)' 0
     expect_stat 'cache hit (preprocessed)' 0
     expect_stat 'cache miss' 1
     rm -f pch.h.pth
 
-    CCACHE_SLOPPINESS=pch_defines,time_macros $CCACHE_COMPILE $SYSROOT -c pch.h -o 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
index 80f23db5c0520cd5b8fe5288365261697515aac3..c5ee96df9c94c442f25d1bda54bb5b1a4e92aec5 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2016 Joel Rosdahl
+// Copyright (C) 2010-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
@@ -438,4 +438,36 @@ TEST(I_flag_with_concat_arg_should_be_rewritten_if_basedir_is_used)
        args_free(act_cc);
 }
 
+TEST(debug_flag_order_with_known_option_first)
+{
+       struct args *orig = args_init_from_string("cc -g1 -gsplit-dwarf foo.c -c");
+       struct args *exp_cpp = args_init_from_string("cc -g1 -gsplit-dwarf");
+       struct args *exp_cc = args_init_from_string("cc -g1 -gsplit-dwarf -c");
+       struct args *act_cpp = NULL;
+       struct args *act_cc = NULL;
+
+       create_file("foo.c", "");
+       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+       CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
+       CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
+
+       args_free(orig);
+}
+
+TEST(debug_flag_order_with_known_option_last)
+{
+       struct args *orig = args_init_from_string("cc -gsplit-dwarf -g1 foo.c -c");
+       struct args *exp_cpp = args_init_from_string("cc -gsplit-dwarf -g1");
+       struct args *exp_cc = args_init_from_string("cc -gsplit-dwarf -g1 -c");
+       struct args *act_cpp = NULL;
+       struct args *act_cc = NULL;
+
+       create_file("foo.c", "");
+       CHECK(cc_process_args(orig, &act_cpp, &act_cc));
+       CHECK_ARGS_EQ_FREE12(exp_cpp, act_cpp);
+       CHECK_ARGS_EQ_FREE12(exp_cc, act_cc);
+
+       args_free(orig);
+}
+
 TEST_SUITE_END
diff --git a/util.c b/util.c
index f048d972f721d3545b92dc5872b1e581036dafd5..92bebcebd2afdd67e23f19a1f40ea9d267ae6357 100644 (file)
--- a/util.c
+++ b/util.c
@@ -1,5 +1,5 @@
 // Copyright (C) 2002 Andrew Tridgell
-// Copyright (C) 2009-2016 Joel Rosdahl
+// 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
@@ -50,11 +50,7 @@ init_log(void)
        logfile = fopen(conf->log_file, "a");
        if (logfile) {
 #ifndef _WIN32
-               int fd = fileno(logfile);
-               int flags = fcntl(fd, F_GETFD, 0);
-               if (flags >= 0) {
-                       fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
-               }
+               set_cloexec_flag(fileno(logfile));
 #endif
                return true;
        } else {
@@ -969,10 +965,13 @@ parse_size_with_suffix(const char *str, uint64_t *size)
                switch (*p) {
                case 'T':
                        x *= multiplier;
+                       // Fallthrough.
                case 'G':
                        x *= multiplier;
+                       // Fallthrough.
                case 'M':
                        x *= multiplier;
+                       // Fallthrough.
                case 'K':
                case 'k':
                        x *= multiplier;
@@ -1184,6 +1183,7 @@ create_tmp_fd(char **fname)
                fatal("Failed to create temporary file for %s: %s",
                      *fname, strerror(errno));
        }
+       set_cloexec_flag(fd);
 
 #ifndef _WIN32
        fchmod(fd, 0666 & ~get_umask());
@@ -1659,3 +1659,14 @@ subst_env_in_string(const char *str, char **errmsg)
        reformat(&result, "%s%.*s", result, (int)(q - p), p);
        return result;
 }
+
+void
+set_cloexec_flag(int fd)
+{
+#ifndef _WIN32
+       int flags = fcntl(fd, F_GETFD, 0);
+       if (flags >= 0) {
+               fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
+       }
+#endif
+}
index 7866f76f623ed8aca238a1408c0b6469eebec607..21b8c7605d773d2d495ec11b950f41336315681f 100644 (file)
--- a/version.c
+++ b/version.c
@@ -1 +1 @@
-const char CCACHE_VERSION[] = "3.3.4";
+const char CCACHE_VERSION[] = "3.3.5";