<body class="article">\r
<div id="header">\r
<h1>ccache copyright and license</h1>\r
-<span id="revnumber">version 3.7.5</span>\r
+<span id="revnumber">version 3.7.6</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>
<div id="footnotes"><hr /></div>\r
<div id="footer">\r
<div id="footer-text">\r
-Version 3.7.5<br />\r
+Version 3.7.6<br />\r
Last updated\r
- 2019-10-22 20:50:43 CEST\r
+ 2019-11-17 20:10:03 CET\r
</div>\r
</div>\r
</body>\r
.PHONY: update-authors
update-authors:
- git log --pretty=format:"* %aN" \
+ git log --pretty=format:"%H %aN" \
+ | grep -Ev 'd7c5056beda5483fcd5c098165fffd9be86fe98d' \
+ | sed -r 's/[^ ]+/*/' \
| sort -u \
| perl -00 -p -i -e 's/^\*.*/<STDIN> . "\n"/es' doc/AUTHORS.adoc
* Robert Yang
* Robin H. Johnson
* Rolf Bjarne Kvinge
+* Russell King
* RW
* Ryan Brown
* Sam Gross
<body class="article">\r
<div id="header">\r
<h1>ccache authors</h1>\r
-<span id="revnumber">version 3.7.5</span>\r
+<span id="revnumber">version 3.7.6</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>
</li>\r
<li>\r
<p>\r
+Russell King\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
RW\r
</p>\r
</li>\r
<div id="footnotes"><hr /></div>\r
<div id="footer">\r
<div id="footer-text">\r
-Version 3.7.5<br />\r
+Version 3.7.6<br />\r
Last updated\r
- 2019-10-22 20:50:43 CEST\r
+ 2019-11-17 20:10:03 CET\r
</div>\r
</div>\r
</body>\r
computing the manifest hash. This is useful if you use Xcode, which uses an
index store path derived from the local project path. Note that the index
store won't be updated correctly on cache hits if you enable this option.
-*file_macro*::
- ccache normally includes the input file path in the hash in order to be
- able to produce the correct object file if the source code includes a
- `__FILE__` macro. If you know that `__FILE__` isn't used in practise, or
- don't care if ccache produces objects where `__FILE__` is expanded to the
- wrong path, you can set *sloppiness* to *file_macro*. ccache will then
- exclude the input file path from the hash.
*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
output. If you know that `__DATE__` isn't used in practise, or don't care if
ccache produces objects where `__DATE__` is expanded to something in the
past, you can set *sloppiness* to *time_macros*.
-** The input file path has changed. ccache normally includes the input file
- path in the hash in order to be able to produce the correct object file if
- the source code includes a `__FILE__` macro. If you know that `__FILE__`
- isn't used in practise, or don't care if ccache produces objects where
- `__FILE__` is expanded to the wrong path, you can set *sloppiness* to
- *file_macro*. ccache will then exclude the input file path from the hash.
+** The input file path has changed. ccache includes the input file path in the
+ direct mode hash to be able to take relative include files into account and
+ to produce a correct object file if the source code includes a `__FILE__`
+ macro.
* If ``cache miss'' has been incremented even though the same code has been
compiled and cached before, ccache has either detected that something has
changed anyway or a cleanup has been performed (either explicitly or
<body class="article">\r
<div id="header">\r
<h1>CCACHE(1)</h1>\r
-<span id="revnumber">version 3.7.5</span>\r
+<span id="revnumber">version 3.7.6</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>
</p>\r
</dd>\r
<dt class="hdlist1">\r
-<strong>file_macro</strong>\r
-</dt>\r
-<dd>\r
-<p>\r
- ccache normally includes the input file path in the hash in order to be\r
- able to produce the correct object file if the source code includes a\r
- <code>__FILE__</code> macro. If you know that <code>__FILE__</code> isn’t used in practise, or\r
- don’t care if ccache produces objects where <code>__FILE__</code> is expanded to the\r
- wrong path, you can set <strong>sloppiness</strong> to <strong>file_macro</strong>. ccache will then\r
- exclude the input file path from the hash.\r
-</p>\r
-</dd>\r
-<dt class="hdlist1">\r
<strong>file_stat_matches</strong>\r
</dt>\r
<dd>\r
</li>\r
<li>\r
<p>\r
-The input file path has changed. ccache normally includes the input file\r
- path in the hash in order to be able to produce the correct object file if\r
- the source code includes a <code>__FILE__</code> macro. If you know that <code>__FILE__</code>\r
- isn’t used in practise, or don’t care if ccache produces objects where\r
- <code>__FILE__</code> is expanded to the wrong path, you can set <strong>sloppiness</strong> to\r
- <strong>file_macro</strong>. ccache will then exclude the input file path from the hash.\r
+The input file path has changed. ccache includes the input file path in the\r
+ direct mode hash to be able to take relative include files into account and\r
+ to produce a correct object file if the source code includes a <code>__FILE__</code>\r
+ macro.\r
</p>\r
</li>\r
</ul></div>\r
<div id="footnotes"><hr /></div>\r
<div id="footer">\r
<div id="footer-text">\r
-Version 3.7.5<br />\r
+Version 3.7.6<br />\r
Last updated\r
- 2019-10-22 20:50:43 CEST\r
+ 2019-11-17 20:10:03 CET\r
</div>\r
</div>\r
</body>\r
ccache news
===========
+ccache 3.7.6
+------------
+Release date: 2019-11-17
+
+Bug fixes
+~~~~~~~~~
+
+- The opt-in “file_macro sloppiness” mode has been removed so that the input
+ file path now is always included in the direct mode hash. This fixes a bug
+ that could result in false cache hits in an edge case when “file_macro
+ sloppiness” is enabled and several identical source files include a relative
+ header file with the same name but in different directories.
+
+- Statistics files are no longer lost when the filesystem of the cache is full.
+
+- Bail out on too hard Clang option `-MJarg` (in addition to the previous
+ bailout of `-MJ arg`).
+
+- Properly handle color diagnostics in the depend mode as well.
+
+
ccache 3.7.5
------------
Release date: 2019-10-22
<body class="article">\r
<div id="header">\r
<h1>ccache news</h1>\r
-<span id="revnumber">version 3.7.5</span>\r
+<span id="revnumber">version 3.7.6</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>
</div>\r
<div id="content">\r
<div class="sect1">\r
+<h2 id="_ccache_3_7_6">ccache 3.7.6</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>Release date: 2019-11-17</p></div>\r
+<div class="sect2">\r
+<h3 id="_bug_fixes">Bug fixes</h3>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+The opt-in “file_macro sloppiness” mode has been removed so that the input\r
+ file path now is always included in the direct mode hash. This fixes a bug\r
+ that could result in false cache hits in an edge case when “file_macro\r
+ sloppiness” is enabled and several identical source files include a relative\r
+ header file with the same name but in different directories.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Statistics files are no longer lost when the filesystem of the cache is full.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Bail out on too hard Clang option <code>-MJarg</code> (in addition to the previous\r
+ bailout of <code>-MJ arg</code>).\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Properly handle color diagnostics in the depend mode as well.\r
+</p>\r
+</li>\r
+</ul></div>\r
+</div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
<h2 id="_ccache_3_7_5">ccache 3.7.5</h2>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2019-10-22</p></div>\r
</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
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2019-08-17</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
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2019-07-19</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
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2018-09-02</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
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2018-03-25</p></div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_5">Bug fixes</h3>\r
+<h3 id="_bug_fixes_6">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2018-02-11</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
</ul></div>\r
</div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_7">Bug fixes</h3>\r
+<h3 id="_bug_fixes_8">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
</ul></div>\r
</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
</ul></div>\r
</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
</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
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2016-10-26</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
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2016-09-28</p></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
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2016-09-07</p></div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_13">Bug fixes</h3>\r
+<h3 id="_bug_fixes_14">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
</ul></div>\r
</div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_14">Bug fixes</h3>\r
+<h3 id="_bug_fixes_15">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2016-09-28</p></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
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2016-09-07</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
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2016-07-20</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
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2016-07-12</p></div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_18">Bug fixes</h3>\r
+<h3 id="_bug_fixes_19">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
</ul></div>\r
</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
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2015-10-08</p></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
</ul></div>\r
</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
</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
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2014-12-10</p></div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_23">Bug fixes</h3>\r
+<h3 id="_bug_fixes_24">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
</ul></div>\r
</div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_24">Bug fixes</h3>\r
+<h3 id="_bug_fixes_25">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2016-07-12</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
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2015-03-07</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
</ul></div>\r
</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
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2013-01-06</p></div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_28">Bug fixes</h3>\r
+<h3 id="_bug_fixes_29">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
</ul></div>\r
</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
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2012-01-08</p></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
</ul></div>\r
</div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_31">Bug fixes</h3>\r
+<h3 id="_bug_fixes_32">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
</ul></div>\r
</div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_32">Bug fixes</h3>\r
+<h3 id="_bug_fixes_33">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2011-01-09</p></div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_33">Bug fixes</h3>\r
+<h3 id="_bug_fixes_34">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2010-11-28</p></div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_34">Bug fixes</h3>\r
+<h3 id="_bug_fixes_35">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2010-11-21</p></div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_35">Bug fixes</h3>\r
+<h3 id="_bug_fixes_36">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2010-11-07</p></div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_36">Bug fixes</h3>\r
+<h3 id="_bug_fixes_37">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
</ul></div>\r
</div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_37">Bug fixes</h3>\r
+<h3 id="_bug_fixes_38">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div class="sectionbody">\r
<div class="paragraph"><p>Release date: 2010-07-15</p></div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_38">Bug fixes</h3>\r
+<h3 id="_bug_fixes_39">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
</ul></div>\r
</div>\r
<div class="sect2">\r
-<h3 id="_bug_fixes_39">Bug fixes</h3>\r
+<h3 id="_bug_fixes_40">Bug fixes</h3>\r
<div class="ulist"><ul>\r
<li>\r
<p>\r
<div id="footnotes"><hr /></div>\r
<div id="footer">\r
<div id="footer-text">\r
-Version 3.7.5<br />\r
+Version 3.7.6<br />\r
Last updated\r
- 2019-10-22 20:50:43 CEST\r
+ 2019-11-17 20:10:03 CET\r
</div>\r
</div>\r
</body>\r
.\" Title: ccache
.\" Author: [see the "Author" section]
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
-.\" Date: 10/22/2019
+.\" Date: 11/17/2019
.\" Manual: ccache Manual
-.\" Source: ccache 3.7.5
+.\" Source: ccache 3.7.6
.\" Language: English
.\"
-.TH "CCACHE" "1" "10/22/2019" "ccache 3\&.7\&.5" "ccache Manual"
+.TH "CCACHE" "1" "11/17/2019" "ccache 3\&.7\&.6" "ccache Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
and its argument when computing the manifest hash\&. This is useful if you use Xcode, which uses an index store path derived from the local project path\&. Note that the index store won\(cqt be updated correctly on cache hits if you enable this option\&.
.RE
.PP
-\fBfile_macro\fR
-.RS 4
-ccache normally includes the input file path in the hash in order to be able to produce the correct object file if the source code includes a
-\fB__FILE__\fR
-macro\&. If you know that
-\fB__FILE__\fR
-isn\(cqt used in practise, or don\(cqt care if ccache produces objects where
-\fB__FILE__\fR
-is expanded to the wrong path, you can set
-\fBsloppiness\fR
-to
-\fBfile_macro\fR\&. ccache will then exclude the input file path from the hash\&.
-.RE
-.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 mtimes and ctimes match\&.
.sp -1
.IP \(bu 2.3
.\}
-The input file path has changed\&. ccache normally includes the input file path in the hash in order to be able to produce the correct object file if the source code includes a
-\fB__FILE__\fR
-macro\&. If you know that
-\fB__FILE__\fR
-isn\(cqt used in practise, or don\(cqt care if ccache produces objects where
+The input file path has changed\&. ccache includes the input file path in the direct mode hash to be able to take relative include files into account and to produce a correct object file if the source code includes a
\fB__FILE__\fR
-is expanded to the wrong path, you can set
-\fBsloppiness\fR
-to
-\fBfile_macro\fR\&. ccache will then exclude the input file path from the hash\&.
+macro\&.
.RE
.RE
.sp
// The original argument list.
static struct args *orig_args;
+// Argument list to add to compiler invocation in depend mode.
+static struct args *depend_extra_args;
+
// The source file.
static char *input_file;
args_free(prefix);
}
+// Compiler in depend mode is invoked with the original arguments.
+// Collect extra arguments that should be added.
+static void
+add_extra_arg(const char *arg)
+{
+ if (conf->depend_mode) {
+ if (depend_extra_args == NULL) {
+ depend_extra_args = args_init(0, NULL);
+ }
+ args_add(depend_extra_args, arg);
+ }
+}
static void failed(void) ATTR_NORETURN;
time_t now = time(NULL);
struct stat st;
if (x_stat(conf->cache_dir, &st) != 0
- || st.st_mtime + k_tempdir_cleanup_interval >= now) {
+ || st.st_mtime + k_tempdir_cleanup_interval >= now) {
// No cleanup needed.
return;
}
char *path = format("%s/%s", temp_dir(), entry->d_name);
if (x_lstat(path, &st) == 0
- && st.st_mtime + k_tempdir_cleanup_interval < now) {
+ && st.st_mtime + k_tempdir_cleanup_interval < now) {
tmp_unlink(path);
}
free(path);
assert(orig_args);
struct args *depend_mode_args = args_copy(orig_args);
args_strip(depend_mode_args, "--ccache-");
+ if (depend_extra_args) {
+ args_extend(depend_mode_args, depend_extra_args);
+ }
add_prefix(depend_mode_args, conf->prefix_command);
time_of_compilation = time(NULL);
}
}
- if (!(conf->sloppiness & SLOPPY_FILE_MACRO)) {
- // The source code file or an include file may contain __FILE__, so make
- // sure that the hash is unique for the file name.
- hash_delimiter(hash, "inputfile");
- hash_string(hash, input_file);
- }
+ // Make sure that the direct mode hash is unique for the input file path.
+ // If this would not be the case:
+ //
+ // * An false cache hit may be produced. Scenario:
+ // - a/r.h exists.
+ // - a/x.c has #include "r.h".
+ // - b/x.c is identical to a/x.c.
+ // - Compiling a/x.c records a/r.h in the manifest.
+ // - Compiling b/x.c results in a false cache hit since a/x.c and b/x.c
+ // share manifests and a/r.h exists.
+ // * The expansion of __FILE__ may be incorrect.
+ hash_delimiter(hash, "inputfile");
+ hash_string(hash, input_file);
hash_delimiter(hash, "sourcecode");
int result = hash_source_code_file(conf, hash, input_file);
}
// These are always too hard.
- if (compopt_too_hard(argv[i]) || str_startswith(argv[i], "-fdump-")) {
+ if (compopt_too_hard(argv[i])
+ || str_startswith(argv[i], "-fdump-")
+ || str_startswith(argv[i], "-MJ")) {
cc_log("Compiler option %s is unsupported", argv[i]);
stats_update(STATS_UNSUPPORTED_OPTION);
result = false;
if (color_output_possible()) {
// Output is redirected, so color output must be forced.
args_add(common_args, "-fdiagnostics-color=always");
+ add_extra_arg("-fdiagnostics-color=always");
cc_log("Automatically forcing colors");
} else {
args_add(common_args, argv[i]);
if (guessed_compiler == GUESSED_CLANG) {
if (!str_eq(actual_language, "assembler")) {
args_add(common_args, "-fcolor-diagnostics");
+ add_extra_arg("-fcolor-diagnostics");
cc_log("Automatically enabling colors");
}
} else if (guessed_compiler == GUESSED_GCC) {
// colors.
if (getenv("GCC_COLORS") && getenv("GCC_COLORS")[0] != '\0') {
args_add(common_args, "-fdiagnostics-color");
+ add_extra_arg("-fdiagnostics-color");
cc_log("Automatically enabling colors");
}
}
sanitize_blacklists_len = 0;
free(included_pch_file); included_pch_file = NULL;
args_free(orig_args); orig_args = NULL;
+ args_free(depend_extra_args); depend_extra_args = NULL;
free(input_file); input_file = NULL;
free(output_obj); output_obj = NULL;
free(output_dep); output_dep = NULL;
#define SLOPPY_INCLUDE_FILE_MTIME (1U << 0)
#define SLOPPY_INCLUDE_FILE_CTIME (1U << 1)
-#define SLOPPY_FILE_MACRO (1U << 2)
-#define SLOPPY_TIME_MACROS (1U << 3)
-#define SLOPPY_PCH_DEFINES (1U << 4)
+#define SLOPPY_TIME_MACROS (1U << 2)
+#define SLOPPY_PCH_DEFINES (1U << 3)
// Allow us to match files based on their stats (size, mtime, ctime), without
// looking at their contents.
-#define SLOPPY_FILE_STAT_MATCHES (1U << 5)
+#define SLOPPY_FILE_STAT_MATCHES (1U << 4)
// Allow us to not include any system headers in the manifest include files,
// similar to -MM versus -M for dependencies.
-#define SLOPPY_SYSTEM_HEADERS (1U << 6)
+#define SLOPPY_SYSTEM_HEADERS (1U << 5)
// Allow us to ignore ctimes when comparing file stats, so we can fake mtimes
// if we want to (it is much harder to fake ctimes, requires changing clock)
-#define SLOPPY_FILE_STAT_MATCHES_CTIME (1U << 7)
+#define SLOPPY_FILE_STAT_MATCHES_CTIME (1U << 6)
// Allow us to not include the -index-store-path option in the manifest hash.
-#define SLOPPY_CLANG_INDEX_STORE (1U << 8)
+#define SLOPPY_CLANG_INDEX_STORE (1U << 7)
// Ignore locale settings.
-#define SLOPPY_LOCALE (1U << 9)
+#define SLOPPY_LOCALE (1U << 8)
#define str_eq(s1, s2) (strcmp((s1), (s2)) == 0)
#define str_startswith(s, prefix) \
{"-L", TAKES_ARG},
{"-M", TOO_HARD},
{"-MF", TAKES_ARG},
- {"-MJ", TAKES_ARG | TOO_HARD},
{"-MM", TOO_HARD},
{"-MQ", TAKES_ARG},
{"-MT", TAKES_ARG},
}
// Used by unittest/test_compopt.c.
-bool compopt_verify_sortedness(void);
+bool compopt_verify_sortedness_and_flags(void);
// For test purposes.
bool
-compopt_verify_sortedness(void)
+compopt_verify_sortedness_and_flags(void)
{
- for (size_t i = 1; i < ARRAY_SIZE(compopts); i++) {
+ for (size_t i = 0; i < ARRAY_SIZE(compopts); i++) {
+ if (compopts[i].type & TOO_HARD && compopts[i].type & TAKES_CONCAT_ARG) {
+ fprintf(stderr,
+ "type (TOO_HARD | TAKES_CONCAT_ARG) not allowed, used by %s\n",
+ compopts[i].name);
+ return false;
+ }
+
+ if (i == 0) {
+ continue;
+ }
+
if (strcmp(compopts[i-1].name, compopts[i].name) >= 0) {
fprintf(stderr,
- "compopt_verify_sortedness: %s >= %s\n",
+ "compopt_verify_sortedness_and_flags: %s >= %s\n",
compopts[i-1].name,
compopts[i].name);
return false;
static char *
format_string(const void *value)
{
- const char * const *str = (const char * const*)value;
+ const char *const *str = (const char *const *)value;
return x_strdup(*str);
}
bool
confitem_parse_sloppiness(const char *str, void *result, char **errmsg)
{
+ (void)errmsg;
+
unsigned *value = (unsigned *)result;
if (!str) {
return *value;
char *word;
char *saveptr = NULL;
while ((word = strtok_r(q, ", ", &saveptr))) {
- if (str_eq(word, "file_macro")) {
- *value |= SLOPPY_FILE_MACRO;
- } else if (str_eq(word, "file_stat_matches")) {
+ if (str_eq(word, "file_stat_matches")) {
*value |= SLOPPY_FILE_STAT_MATCHES;
} else if (str_eq(word, "file_stat_matches_ctime")) {
*value |= SLOPPY_FILE_STAT_MATCHES_CTIME;
*value |= SLOPPY_CLANG_INDEX_STORE;
} else if (str_eq(word, "locale")) {
*value |= SLOPPY_LOCALE;
- } else {
- *errmsg = format("unknown sloppiness: \"%s\"", word);
- free(p);
- return false;
}
+ // else: ignore unknown value for forward compatibility
q = NULL;
}
free(p);
{
const unsigned *sloppiness = (const unsigned *)value;
char *s = x_strdup("");
- if (*sloppiness & SLOPPY_FILE_MACRO) {
- reformat(&s, "%sfile_macro, ", s);
- }
if (*sloppiness & SLOPPY_INCLUDE_FILE_MTIME) {
reformat(&s, "%sinclude_file_mtime, ", s);
}
bool
confitem_verify_absolute_path(const void *value, char **errmsg)
{
- const char * const *path = (const char * const *)value;
+ const char *const *path = (const char *const *)value;
assert(*path);
if (str_eq(*path, "")) {
// The empty string means "disable" in this case.
FILE *f = create_tmp_file(&tmp_file, "wb");
for (size_t i = 0; i < counters->size; i++) {
if (fprintf(f, "%u\n", counters->data[i]) < 0) {
- fatal("Failed to write to %s", tmp_file);
+ fclose(f);
+ goto error;
}
}
- fclose(f);
+ if (fclose(f) == EOF) {
+ goto error;
+ }
x_rename(tmp_file, path);
free(tmp_file);
+ return;
+
+error:
+ tmp_unlink(tmp_file);
+ fatal("Failed to write to %s", tmp_file);
}
static void
if (tm) {
*result = *tm;
return result;
- }
- else {
+ } else {
memset(result, 0, sizeof(*result));
return NULL;
}
-extern const char CCACHE_VERSION[]; const char CCACHE_VERSION[] = "3.7.5";
+extern const char CCACHE_VERSION[]; const char CCACHE_VERSION[] = "3.7.6";
expect_stat 'cache miss' 1
# -------------------------------------------------------------------------
- TEST "__FILE__ in source file disables direct mode"
+ TEST "The source file path is included in the hash"
cat <<EOF >file.c
#define file __FILE__
int test;
EOF
+ cp file.c file2.c
$CCACHE_COMPILE -c file.c
expect_stat 'cache hit (direct)' 0
expect_stat 'cache hit (preprocessed)' 0
expect_stat 'cache miss' 1
- $CCACHE_COMPILE -c `pwd`/file.c
+ $CCACHE_COMPILE -c file2.c
expect_stat 'cache hit (direct)' 1
expect_stat 'cache hit (preprocessed)' 0
expect_stat 'cache miss' 2
- # -------------------------------------------------------------------------
- TEST "__FILE__ in include file disables direct mode"
-
- cat <<EOF >file.h
-#define file __FILE__
-int test;
-EOF
- backdate file.h
- cat <<EOF >file_h.c
-#include "file.h"
-EOF
-
- $CCACHE_COMPILE -c file_h.c
- expect_stat 'cache hit (direct)' 0
+ $CCACHE_COMPILE -c file2.c
+ expect_stat 'cache hit (direct)' 2
expect_stat 'cache hit (preprocessed)' 0
- expect_stat 'cache miss' 1
+ expect_stat 'cache miss' 2
- $CCACHE_COMPILE -c file_h.c
- expect_stat 'cache hit (direct)' 1
+ $CCACHE_COMPILE -c $(pwd)/file.c
+ expect_stat 'cache hit (direct)' 2
expect_stat 'cache hit (preprocessed)' 0
- expect_stat 'cache miss' 1
-
- mv file_h.c file2_h.c
+ expect_stat 'cache miss' 3
- $CCACHE_COMPILE -c `pwd`/file2_h.c
- expect_stat 'cache hit (direct)' 1
+ $CCACHE_COMPILE -c $(pwd)/file.c
+ expect_stat 'cache hit (direct)' 3
expect_stat 'cache hit (preprocessed)' 0
- expect_stat 'cache miss' 2
+ expect_stat 'cache miss' 3
# -------------------------------------------------------------------------
- TEST "__FILE__ in source file ignored if sloppy"
+ TEST "The source file path is included even if sloppiness = file_macro"
cat <<EOF >file.c
#define file __FILE__
int test;
EOF
+ cp file.c file2.c
CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c file.c
expect_stat 'cache hit (direct)' 0
expect_stat 'cache hit (preprocessed)' 0
expect_stat 'cache miss' 1
- CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c `pwd`/file.c
+ CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c file2.c
+ expect_stat 'cache hit (direct)' 1
+ expect_stat 'cache hit (preprocessed)' 0
+ expect_stat 'cache miss' 2
+
+ CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c file2.c
expect_stat 'cache hit (direct)' 2
expect_stat 'cache hit (preprocessed)' 0
- expect_stat 'cache miss' 1
+ expect_stat 'cache miss' 2
+
+ CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c $(pwd)/file.c
+ expect_stat 'cache hit (direct)' 2
+ expect_stat 'cache hit (preprocessed)' 0
+ expect_stat 'cache miss' 3
+
+ CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c $(pwd)/file.c
+ expect_stat 'cache hit (direct)' 3
+ expect_stat 'cache hit (preprocessed)' 0
+ expect_stat 'cache miss' 3
# -------------------------------------------------------------------------
- TEST "__FILE__ in include file ignored if sloppy"
+ TEST "Relative includes for identical source code in different directories"
- cat <<EOF >file.h
-#define file __FILE__
-int test;
+ mkdir a
+ cat <<EOF >a/file.c
+#include "file.h"
+EOF
+ cat <<EOF >a/file.h
+int x = 1;
EOF
- backdate file.h
- cat <<EOF >file_h.c
+ backdate a/file.h
+
+ mkdir b
+ cat <<EOF >b/file.c
#include "file.h"
EOF
+ cat <<EOF >b/file.h
+int x = 2;
+EOF
+ backdate b/file.h
- CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c file_h.c
+ $CCACHE_COMPILE -c a/file.c
expect_stat 'cache hit (direct)' 0
expect_stat 'cache hit (preprocessed)' 0
expect_stat 'cache miss' 1
- CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c file_h.c
+ $CCACHE_COMPILE -c a/file.c
expect_stat 'cache hit (direct)' 1
expect_stat 'cache hit (preprocessed)' 0
expect_stat 'cache miss' 1
- mv file_h.c file2_h.c
+ $CCACHE_COMPILE -c b/file.c
+ expect_stat 'cache hit (direct)' 1
+ expect_stat 'cache hit (preprocessed)' 0
+ expect_stat 'cache miss' 2
- CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS file_macro" $CCACHE_COMPILE -c `pwd`/file2_h.c
+ $CCACHE_COMPILE -c b/file.c
expect_stat 'cache hit (direct)' 2
expect_stat 'cache hit (preprocessed)' 0
- expect_stat 'cache miss' 1
+ expect_stat 'cache miss' 2
# -------------------------------------------------------------------------
TEST "__TIME__ in source file disables direct mode"
TEST(option_table_should_be_sorted)
{
- bool compopt_verify_sortedness(void);
- CHECK(compopt_verify_sortedness());
+ bool compopt_verify_sortedness_and_flags(void);
+ CHECK(compopt_verify_sortedness_and_flags());
}
TEST(dash_I_affects_cpp)
"read_only_direct = true\n"
"recache = true\n"
"run_second_cpp = false\n"
- "sloppiness = file_macro ,time_macros, include_file_mtime,include_file_ctime,file_stat_matches,file_stat_matches_ctime,pch_defines , no_system_headers,system_headers,clang_index_store\n"
+ "sloppiness = time_macros ,include_file_mtime include_file_ctime,file_stat_matches,file_stat_matches_ctime,pch_defines , no_system_headers,system_headers,clang_index_store\n"
"stats = false\n"
"temporary_dir = ${USER}_foo\n"
"umask = 777\n"
CHECK_INT_EQ(
SLOPPY_INCLUDE_FILE_MTIME
|SLOPPY_INCLUDE_FILE_CTIME
- |SLOPPY_FILE_MACRO
|SLOPPY_TIME_MACROS
|SLOPPY_FILE_STAT_MATCHES
|SLOPPY_FILE_STAT_MATCHES_CTIME
conf_free(conf);
}
-TEST(conf_read_invalid_sloppiness)
+TEST(conf_read_unknown_sloppiness)
{
struct conf *conf = conf_create();
char *errmsg;
- create_file("ccache.conf", "sloppiness = file_macro, foo");
- CHECK(!conf_read(conf, "ccache.conf", &errmsg));
- CHECK_INT_EQ(errno, 0);
- CHECK_STR_EQ_FREE2("ccache.conf:1: unknown sloppiness: \"foo\"",
- errmsg);
+ create_file("ccache.conf", "sloppiness = time_macros, foo");
+ CHECK(conf_read(conf, "ccache.conf", &errmsg));
+ CHECK_INT_EQ(conf->sloppiness, SLOPPY_TIME_MACROS);
conf_free(conf);
}
char *data;
create_file("ccache.conf", "path = vanilla\n");
- CHECKM(conf_set_value_in_file("ccache.conf", "compiler", "chocolate", &errmsg),
+ CHECKM(conf_set_value_in_file("ccache.conf", "compiler", "chocolate",
+ &errmsg),
errmsg);
data = read_text_file("ccache.conf", 0);
CHECK(data);
CHECK_STR_EQ_FREE2("path = chocolate\nstats = chocolate\n", data);
}
+TEST(conf_set_unknown_sloppiness)
+{
+ char *errmsg;
+ char *data;
+
+ create_file("ccache.conf", "path = vanilla\n");
+ CHECK(conf_set_value_in_file("ccache.conf", "sloppiness", "foo", &errmsg));
+
+ data = read_text_file("ccache.conf", 0);
+ CHECK(data);
+ CHECK_STR_EQ_FREE2("path = vanilla\nsloppiness = foo\n", data);
+}
+
TEST(conf_print_existing_value)
{
struct conf *conf = conf_create();
true,
true,
.run_second_cpp = false,
- SLOPPY_FILE_MACRO|SLOPPY_INCLUDE_FILE_MTIME|
+ SLOPPY_INCLUDE_FILE_MTIME|
SLOPPY_INCLUDE_FILE_CTIME|SLOPPY_TIME_MACROS|
SLOPPY_FILE_STAT_MATCHES|SLOPPY_FILE_STAT_MATCHES_CTIME|
SLOPPY_PCH_DEFINES|SLOPPY_SYSTEM_HEADERS|SLOPPY_CLANG_INDEX_STORE,
CHECK_STR_EQ("read_only_direct = true", received_conf_items[n++].descr);
CHECK_STR_EQ("recache = true", received_conf_items[n++].descr);
CHECK_STR_EQ("run_second_cpp = false", received_conf_items[n++].descr);
- CHECK_STR_EQ("sloppiness = file_macro, include_file_mtime,"
+ CHECK_STR_EQ("sloppiness = include_file_mtime,"
" include_file_ctime, time_macros, pch_defines,"
" file_stat_matches, file_stat_matches_ctime, system_headers,"
" clang_index_store",