Imported Upstream version 3.7 upstream/3.7
authorJinWang An <jinwang.an@samsung.com>
Tue, 3 Aug 2021 07:28:18 +0000 (16:28 +0900)
committerJinWang An <jinwang.an@samsung.com>
Tue, 3 Aug 2021 07:28:18 +0000 (16:28 +0900)
42 files changed:
CONTRIBUTING.md
INSTALL.md
LICENSE.adoc
LICENSE.html
Makefile.in
README.md
config.h.in
configure
configure.ac
dev.mk.in
doc/AUTHORS.adoc
doc/AUTHORS.html
doc/MANUAL.adoc
doc/MANUAL.html
doc/NEWS.adoc
doc/NEWS.html
doc/ccache.1
src/ccache.c
src/ccache.h
src/compopt.c
src/conf.c
src/hash.c
src/hashutil.c
src/language.c
src/mdfour.c
src/mdfour.h
src/minitrace.c [new file with mode: 0644]
src/minitrace.h [new file with mode: 0644]
src/stats.c
src/unify.c
src/util.c
src/version.c
test/run
test/suites/base.bash
test/suites/depend.bash
test/suites/direct.bash
test/suites/hardlink.bash
test/suites/pch.bash~ [deleted file]
test/suites/split_dwarf.bash [new file with mode: 0644]
unittest/test_compopt.c
unittest/test_conf.c
unittest/test_hash.c

index 0147aa7e9f5a6df35e616161150a200e4642309e..763be4faba163b8a6973c6793916588d56022f3c 100644 (file)
@@ -24,12 +24,15 @@ Please include at least the following information in your bug report:
 Also, consider reading [Effective Ways to Get Help from Maintainers](
 https://www.snoyman.com/blog/2017/10/effective-ways-help-from-maintainers).
 
-
 ## Contributing code?
 
-Great! You can create a pull request with your proposal on github, or you could
-post one or several patches to the
-[mailing list](https://lists.samba.org/mailman/listinfo/ccache/).
+The preferred way is to create one or several pull request with your
+proposal(s) on [GitHub](https://github.com/ccache/ccache).
+
+If you plan to implement major changes it is wise to open an issue on GitHub
+(or send a mail to the mailing list) asking for comments on your plans before
+doing the bulk of the work. That way you can avoid potentially wasting time on
+doing something that might not end up being accepted.
 
 ### How to write commit messages
 
index e5e335d4da9dbd39f12cbcd3fbb25eafa472b39a..a72599e9ffce29561a3e0b47f5f4b18bd0f7961d 100644 (file)
@@ -5,7 +5,7 @@ Prerequisites
 -------------
 
 To build ccache from a
-[release archive](https://ccache.samba.org/download.html), you need:
+[release archive](https://ccache.dev/download.html), you need:
 
 - A C compiler (for instance GCC)
 
index 4888b83b00042c2902c0e4d58a1105c7a69979f4..30848f40d405627601830cecbd1655688848a93d 100644 (file)
@@ -29,10 +29,10 @@ Copyright and authors
 ---------------------
 
 ccache is a collective work with contributions from many people, listed in
-AUTHORS.adoc and at https://ccache.samba.org/credits.html. Subsequent additions
-by contributing authors are implicitly licensed to the public under the same
-terms (GNU GPL version 3 or later), but the contributing authors retain
-copyrights on their portions of the work.
+AUTHORS.adoc and at https://ccache.dev/credits.html. Subsequent additions by
+contributing authors are implicitly licensed to the public under the same terms
+(GNU GPL version 3 or later), but the contributing authors retain copyrights on
+their portions of the work.
 
 The copyright for ccache as a whole is as follows:
 
@@ -444,6 +444,35 @@ http://www.jhweiss.de/software/snprintf.html and has the following license:
   modified) versions of this file, nor is leaving this notice intact mandatory.
 -------------------------------------------------------------------------------
 
+src/minitrace.[hc]
+~~~~~~~~~~~~~~~~~~
+
+A library for producing JSON traces suitable for Chrome's built-in trace viewer
+(chrome://tracing). Downloaded from <https://github.com/hrydgard/minitrace>.
+
+-------------------------------------------------------------------------------
+The MIT License (MIT)
+
+Copyright (c) 2014 Henrik Rydgård
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+-------------------------------------------------------------------------------
 
 src/zlib/*.[hc]
 ~~~~~~~~~~~~~~~
index 68719191f41af1ca065dbba0cc922e171ba94cb8..1de702f9e897539e2ab605a68e5781e35ce08470 100644 (file)
@@ -735,7 +735,7 @@ asciidoc.install(2);
 <body class="article">\r
 <div id="header">\r
 <h1>ccache copyright and license</h1>\r
-<span id="revnumber">version 3.6</span>\r
+<span id="revnumber">version 3.7</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>
@@ -769,10 +769,10 @@ asciidoc.install(2);
 <h2 id="_copyright_and_authors">Copyright and authors</h2>\r
 <div class="sectionbody">\r
 <div class="paragraph"><p>ccache is a collective work with contributions from many people, listed in\r
-AUTHORS.adoc and at <a href="https://ccache.samba.org/credits.html">https://ccache.samba.org/credits.html</a>. Subsequent additions\r
-by contributing authors are implicitly licensed to the public under the same\r
-terms (GNU GPL version 3 or later), but the contributing authors retain\r
-copyrights on their portions of the work.</p></div>\r
+AUTHORS.adoc and at <a href="https://ccache.dev/credits.html">https://ccache.dev/credits.html</a>. Subsequent additions by\r
+contributing authors are implicitly licensed to the public under the same terms\r
+(GNU GPL version 3 or later), but the contributing authors retain copyrights on\r
+their portions of the work.</p></div>\r
 <div class="paragraph"><p>The copyright for ccache as a whole is as follows:</p></div>\r
 <div class="listingblock">\r
 <div class="content">\r
@@ -1173,6 +1173,35 @@ Appleby. See <a href="http://murmurhash.googlepages.com">http://murmurhash.googl
 </div></div>\r
 </div>\r
 <div class="sect2">\r
+<h3 id="_src_minitrace_hc">src/minitrace.[hc]</h3>\r
+<div class="paragraph"><p>A library for producing JSON traces suitable for Chrome&#8217;s built-in trace viewer\r
+(chrome://tracing). Downloaded from <a href="https://github.com/hrydgard/minitrace">https://github.com/hrydgard/minitrace</a>.</p></div>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><code>The MIT License (MIT)\r
+\r
+Copyright (c) 2014 Henrik Rydgård\r
+\r
+Permission is hereby granted, free of charge, to any person obtaining a copy\r
+of this software and associated documentation files (the "Software"), to deal\r
+in the Software without restriction, including without limitation the rights\r
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+copies of the Software, and to permit persons to whom the Software is\r
+furnished to do so, subject to the following conditions:\r
+\r
+The above copyright notice and this permission notice shall be included in all\r
+copies or substantial portions of the Software.\r
+\r
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+SOFTWARE.</code></pre>\r
+</div></div>\r
+</div>\r
+<div class="sect2">\r
 <h3 id="_src_zlib_hc">src/zlib/*.[hc]</h3>\r
 <div class="paragraph"><p>This is a bundled subset of zlib 1.2.11 from <a href="http://zlib.net">http://zlib.net</a> with the\r
 following license:</p></div>\r
@@ -1206,9 +1235,9 @@ following license:</p></div>
 <div id="footnotes"><hr /></div>\r
 <div id="footer">\r
 <div id="footer-text">\r
-Version 3.6<br />\r
+Version 3.7<br />\r
 Last updated\r
- 2019-01-13 21:38:14 CET\r
+ 2019-04-23 21:35:11 CEST\r
 </div>\r
 </div>\r
 </body>\r
index 83beae1ef6826d819bfa849469365c381a217d74..fba5e10e5dfcc4de8815d496194d573f23de07f3 100644 (file)
@@ -58,9 +58,12 @@ generated_sources = \
     src/hashtable_itr.c \
     src/murmurhashneutral2.c \
     src/snprintf.c
-base_sources = $(non_3pp_sources) $(generated_sources) $(3pp_sources)
+extra_sources = @extra_sources@
+base_sources = $(non_3pp_sources) $(generated_sources) $(3pp_sources) $(extra_sources)
 base_objs = $(base_sources:.c=.o)
 
+non_3pp_objs = $(non_3pp_sources:.c=.o)
+
 ccache_sources = src/main.c $(base_sources)
 ccache_objs = $(ccache_sources:.c=.o)
 
@@ -133,9 +136,9 @@ src/zlib/libz.a: $(zlib_objs)
        $(if $(quiet),@echo "  RANLIB   $@")
        $(Q)$(RANLIB) $@
 
-.PHONY: perf
-perf: ccache$(EXEEXT)
-       $(srcdir)/perf/perf.py --ccache ccache$(EXEEXT) $(CC) $(all_cppflags) $(all_cflags) $(srcdir)/src/ccache.c
+.PHONY: performance
+performance: ccache$(EXEEXT)
+       $(srcdir)/misc/performance --ccache ccache$(EXEEXT) $(CC) $(all_cppflags) $(all_cflags) $(srcdir)/src/ccache.c
 
 .PHONY: test
 test: ccache$(EXEEXT) unittest/run$(EXEEXT)
index 63bed113ce9cd29c5bd861763841b651468fa1d9..58f8a4dab12cd25f0387e5fd06e0615b5114ef78 100644 (file)
--- a/README.md
+++ b/README.md
@@ -13,14 +13,14 @@ again. Supported languages are C, C++, Objective-C and Objective-C++.
 General information
 -------------------
 
-* [Main web site](https://ccache.samba.org)
-* [Documentation](https://ccache.samba.org/documentation.html)
-  * [Latest manual](https://ccache.samba.org/manual/latest.html)
+* [Main web site](https://ccache.dev)
+* [Documentation](https://ccache.dev/documentation.html)
+  * [Latest manual](https://ccache.dev/manual/latest.html)
   * [Installation from Git source repository](https://github.com/ccache/ccache/blob/master/doc/INSTALL.md)
   * [Installation from release archive](https://github.com/ccache/ccache/blob/master/doc/INSTALL-from-release-archive.md)
-* [Release notes](https://ccache.samba.org/releasenotes.html)
-* [Credits and history](https://ccache.samba.org/credits.html)
-* [License and copyright](https://ccache.samba.org/license.html)
+* [Release notes](https://ccache.dev/releasenotes.html)
+* [Credits and history](https://ccache.dev/credits.html)
+* [License and copyright](https://ccache.dev/license.html)
 
 
 Contributing to ccache
@@ -29,7 +29,7 @@ Contributing to ccache
 * [Source repository](https://github.com/ccache/ccache)
 * [Notes on how to contribute](https://github.com/ccache/ccache/blob/master/CONTRIBUTING.md)
 * [Mailing list](https://lists.samba.org/mailman/listinfo/ccache/)
-* [Bug report info](https://ccache.samba.org/bugs.html)
+* [Bug report info](https://ccache.dev/bugs.html)
 * [Issue tracker](https://github.com/ccache/ccache/issues)
   * [Help wanted!](https://github.com/ccache/ccache/issues/help%20wanted)
   * [Good first issues!](https://github.com/ccache/ccache/issues/good%20first%20issue)
index 1493ab9906e1320a43485c20b5a321be3d085bb5..4e8242a727927ef5c287b2143e582f6e3a07992e 100644 (file)
@@ -46,6 +46,9 @@
 /* Define to 1 if you have the <locale.h> header file. */
 #undef HAVE_LOCALE_H
 
+/* Define to 1 if you have the `localtime_r' function. */
+#undef HAVE_LOCALTIME_R
+
 /* Define to 1 if the system has the type `long long'. */
 #undef HAVE_LONG_LONG
 
index b13d086766d40de481981a42123a2459acc9c665..7530d839b995d8ef4f50a6619082d6ffba235d8f 100755 (executable)
--- a/configure
+++ b/configure
@@ -620,6 +620,7 @@ ac_includes_default="\
 
 ac_header_list=
 ac_subst_vars='LTLIBOBJS
+GPERF
 LIBOBJS
 EGREP
 GREP
@@ -641,6 +642,7 @@ test_suites
 no_implicit_fallthrough_warning
 more_warnings
 include_dev_mk
+extra_sources
 extra_libs
 disable_man
 host_os
@@ -696,6 +698,7 @@ enable_option_checking
 enable_more_warnings
 with_bundled_zlib
 enable_man
+enable_tracing
 '
       ac_precious_vars='build_alias
 host_alias
@@ -1330,6 +1333,7 @@ Optional Features:
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
   --enable-more-warnings  enable more compiler warnings
   --disable-man           disable installing man pages
+  --enable-tracing        enable possibility to use internal ccache tracing
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -2368,6 +2372,7 @@ esac
 
 
 
+
 # The later defininition of _XOPEN_SOURCE disables certain features
 # on Linux, so we need _GNU_SOURCE to re-enable them (makedev, tm_zone).
 
@@ -4659,6 +4664,17 @@ _ACEOF
 fi
 done
 
+for ac_func in localtime_r
+do :
+  ac_fn_c_check_func "$LINENO" "localtime_r" "ac_cv_func_localtime_r"
+if test "x$ac_cv_func_localtime_r" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LOCALTIME_R 1
+_ACEOF
+
+fi
+done
+
 for ac_func in mkstemp
 do :
   ac_fn_c_check_func "$LINENO" "mkstemp" "ac_cv_func_mkstemp"
@@ -5988,6 +6004,16 @@ if test x${enable_man} = xno; then
     disable_man='#'
 fi
 
+# Check whether --enable-tracing was given.
+if test "${enable_tracing+set}" = set; then :
+  enableval=$enable_tracing;
+fi
+
+if test x${enable_tracing} = xyes; then
+    CPPFLAGS="$CPPFLAGS -DMTR_ENABLED"
+    extra_sources="src/minitrace.c"
+fi
+
 if test x${windows_os} = xyes; then
     LIBS="$LIBS -lws2_32"
     for ac_func in GetFinalPathNameByHandleW
@@ -6318,6 +6344,101 @@ $as_echo "$as_me: developer mode enabled" >&6;}
     include_dev_mk='include dev.mk'
     version=`(git --git-dir=$srcdir/.git describe --dirty 2>/dev/null || echo vunknown) | sed -e 's/v//' -e 's/-/+/' -e 's/-/_/g'`
     echo "extern const char CCACHE_VERSION[]; const char CCACHE_VERSION[] = \"$version\";" >src/version.c
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gperf", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gperf; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_GPERF+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$GPERF"; then
+  ac_cv_prog_GPERF="$GPERF" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_GPERF="${ac_tool_prefix}gperf"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+GPERF=$ac_cv_prog_GPERF
+if test -n "$GPERF"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GPERF" >&5
+$as_echo "$GPERF" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_GPERF"; then
+  ac_ct_GPERF=$GPERF
+  # Extract the first word of "gperf", so it can be a program name with args.
+set dummy gperf; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_GPERF+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_GPERF"; then
+  ac_cv_prog_ac_ct_GPERF="$ac_ct_GPERF" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_GPERF="gperf"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_GPERF=$ac_cv_prog_ac_ct_GPERF
+if test -n "$ac_ct_GPERF"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_GPERF" >&5
+$as_echo "$ac_ct_GPERF" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_GPERF" = x; then
+    GPERF=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    GPERF=$ac_ct_GPERF
+  fi
+else
+  GPERF="$ac_cv_prog_GPERF"
+fi
+
+    if test -z "$GPERF"; then
+        as_fn_error $? "please install gperf" "$LINENO" 5
+    fi
 else
     { $as_echo "$as_me:${as_lineno-$LINENO}: developer mode disabled" >&5
 $as_echo "$as_me: developer mode disabled" >&6;}
index 761fbdd8df9af1b12dc3564eeea03ca10e5d3863..903091aefa4bf11bb7fe179147073df4a61e7314 100644 (file)
@@ -21,6 +21,7 @@ esac
 
 AC_SUBST(disable_man)
 AC_SUBST(extra_libs)
+AC_SUBST(extra_sources)
 AC_SUBST(include_dev_mk)
 AC_SUBST(more_warnings)
 AC_SUBST(no_implicit_fallthrough_warning)
@@ -86,6 +87,7 @@ AC_CHECK_FUNCS(gethostname)
 AC_CHECK_FUNCS(getopt_long)
 AC_CHECK_FUNCS(getpwuid)
 AC_CHECK_FUNCS(gettimeofday)
+AC_CHECK_FUNCS(localtime_r)
 AC_CHECK_FUNCS(mkstemp)
 AC_CHECK_FUNCS(realpath)
 AC_CHECK_FUNCS(setenv)
@@ -166,6 +168,14 @@ if test x${enable_man} = xno; then
     disable_man='#'
 fi
 
+AC_ARG_ENABLE(tracing,
+  [AS_HELP_STRING([--enable-tracing],
+    [enable possibility to use internal ccache tracing])])
+if test x${enable_tracing} = xyes; then
+    CPPFLAGS="$CPPFLAGS -DMTR_ENABLED"
+    extra_sources="src/minitrace.c"
+fi
+
 dnl Linking on Windows needs ws2_32
 if test x${windows_os} = xyes; then
     LIBS="$LIBS -lws2_32"
@@ -204,6 +214,10 @@ if test ! -f $srcdir/dev_mode_disabled && test "$RUN_FROM_BUILD_FARM" != yes; th
     include_dev_mk='include dev.mk'
     version=`(git --git-dir=$srcdir/.git describe --dirty 2>/dev/null || echo vunknown) | sed -e 's/v//' -e 's/-/+/' -e 's/-/_/g'`
     echo "extern const char CCACHE_VERSION@<:@@:>@; const char CCACHE_VERSION@<:@@:>@ = \"$version\";" >src/version.c
+    AC_CHECK_TOOL(GPERF, gperf)
+    if test -z "$GPERF"; then
+        AC_MSG_ERROR(please install gperf)
+    fi
 else
     AC_MSG_NOTICE(developer mode disabled)
 fi
index cf6e17c71dec0fca1766eaecef9246bdbdfd5f5d..80a2cd3ccff0d41e3925aebb06c088896fe1a853 100644 (file)
--- a/dev.mk.in
+++ b/dev.mk.in
@@ -1,7 +1,7 @@
 # GNU make syntax reigns in this file.
 
-all_cflags += -Werror @more_warnings@
-all_cppflags += -MD -MP -MF .deps/$(subst .._,,$(subst /,_,$<)).d
+all_cflags += -Werror
+all_cppflags += -MD -MP -MF .deps/$(subst .._,,$(subst /,_,$(subst $(srcdir)/,,$<))).d
 
 A2X = a2x
 ASCIIDOC = asciidoc
@@ -13,7 +13,7 @@ COMPILEDB = compiledb
 CLANG_TIDY = clang-tidy
 SCAN_BUILD = scan-build
 DOCKER = docker
-GPERF = gperf
+GPERF = @GPERF@
 TEST = test
 
 version := \
@@ -53,6 +53,7 @@ headers = \
     src/macroskip.h \
     src/manifest.h \
     src/mdfour.h \
+    src/minitrace.h \
     src/murmurhashneutral2.h \
     src/system.h \
     src/unify.h \
@@ -95,21 +96,16 @@ source_dist_files = \
     src/envtoconfitems.gperf \
     src/envtoconfitems_lookup.c \
     src/main.c \
+    src/minitrace.c \
     src/zlib/*.c \
     src/zlib/*.h \
     test/run \
-    test/suites/*
+    test/suites/*.bash
 
 dist_files = \
     $(addprefix $(srcdir)/, $(source_dist_files)) \
     $(built_dist_files)
 
-uncrustify_exclude_files = \
-    src/getopt_long.c \
-    src/hashtable.c \
-    src/hashtable_itr.c \
-    src/snprintf.c
-
 ifneq ($(shell sed 's/.*"\(.*\)".*/\1/' src/version.c 2>/dev/null),$(version))
   $(shell echo 'extern const char CCACHE_VERSION[]; const char CCACHE_VERSION[] = "$(version)";' >src/version.c)
 endif
@@ -193,13 +189,15 @@ docs: $(generated_docs)
        $(Q)$(ASCIIDOC) -a revnumber=$(version) -d manpage -b docbook -o - $< | \
          perl -pe 's!<literal>(.*?)</literal>!<emphasis role="strong">\1</emphasis>!g' >$@
 
+$(non_3pp_objs) $(test_objs): CFLAGS += @more_warnings@
+
 doc/ccache.1: doc/MANUAL.xml
        $(if $(quiet),@echo "  A2X      $@")
        $(Q)$(A2X) --doctype manpage --format manpage $<
 
 .PHONY: update-authors
 update-authors:
-       git log --pretty=format:"* %aN <%aE>" \
+       git log --pretty=format:"* %aN" \
          | sort -u \
          | perl -00 -p -i -e 's/^\*.*/<STDIN> . "\n"/es' doc/AUTHORS.adoc
 
@@ -220,7 +218,7 @@ shellcheck: test/suites/*.bash
 
 .PHONY: uncrustify
 uncrustify:
-       uncrustify -c misc/uncrustify.cfg --no-backup --replace $(filter-out $(uncrustify_exclude_files), $(base_sources)) $(test_sources)
+       uncrustify -c misc/uncrustify.cfg --no-backup --replace $(non_3pp_sources) $(test_sources)
 
 # pip install compiledb
 compile_commands.json:
@@ -247,6 +245,6 @@ docker: buildenv/$(BUILDENV)/Dockerfile
 travis: .travis/Dockerfile
        $(DOCKER) inspect travis-build >/dev/null || $(DOCKER) build -t travis-build .travis
        $(DOCKER) run --rm --volume $(PWD):/src --tmpfs /dst:rw,exec --env ASAN_OPTIONS='$(ASAN_OPTIONS)' travis-build \
-       sh -c "cd /src && ./autogen.sh && cd /dst && CC=$(CC) CFLAGS='$(CFLAGS)' /src/configure $(HOST) && make && make $(TEST)"
+       sh -c "cd /src && ./autogen.sh && cd /dst && CC=$(CC) CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' /src/configure $(HOST) && make V=$(V) && make V=$(V) $(TEST)"
 
 -include .deps/*.d
index f9c665bf63234be28ca7109b38f8c4d43a593c7e..ab8d39d8b2b48219be1204ee01fdbf60865bd4ac 100644 (file)
@@ -6,95 +6,98 @@ 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 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>
-* Bernhard Bauer <bauerb@chromium.org>
-* Björn Jacke <bj@sernet.de>
-* Chiaki Ishikawa <ishikawa@yk.rim.or.jp>
-* Chris AtLee <catlee@mozilla.com>
-* Clemens Rabe <clemens.rabe@gmail.com>
-* David Givone <david@givone.net>
-* Edward Z. Yang <ezyang@fb.com>
-* Francois Marier <francois@debian.org>
-* Gabriel Scherer <gabriel.scherer@gmail.com>
-* Geert Bosch <geert@mongodb.com>
-* Geert Kloosterman <geert.kloosterman@brightcomputing.com>
-* Grigory Entin <grigorye@dins.ru>
-* Havard Graff <havard.graff@gmail.com>
-* Hongli Lai <hongli@phusion.nl>
-* Ivan Vaigult <i.vaigult@gmail.com>
-* Jiang Jiang <jiangj@opera.com>
-* Joel Galenson <jgalenson@gmail.com>
-* Joel Rosdahl <joel@rosdahl.net>
-* John Basila <jbasila@checkpoint.com>
-* John Coiner <john.coiner@amd.com>
-* Jon Bernard <jbernard@tuxion.com>
-* Jonny Yu <yingshen.yu@gmail.com>
-* Jørgen P. Tjernø <jorgen@valvesoftware.com>
-* Josh Soref <jsoref@users.noreply.github.com>
-* Justin Lebar <justin.lebar@gmail.com>
-* Karl Chen <quarl@cs.berkeley.edu>
-* Kona Blend <kona8lend@gmail.com>
-* Kovarththanan Rajaratnam <kovarththanan.rajaratnam@gmail.com>
-* Lalit Chhabra <lchhabra@linuxmail.org>
-* Lars Gustäbel <lars@gustaebel.de>
-* Leanid Chaika <leanid.chaika@gmail.com>
-* Luboš Luňák <l.lunak@centrum.cz>
-* Maarten Maathuis <madman2003@shikahr.net>
-* Mark Starovoytov <starovoytov.mark@googlemail.com>
-* Martin Ettl <ettl.martin78@gmail.com>
-* Martin Pool <mbp@sourcefrog.net>
-* Mathias De Maré <mathias.de_mare@nokia.com>
-* Matthias Kretz <kretz@kde.org>
-* Melven Roehrig-Zoellner <Melven.Roehrig-Zoellner@DLR.de>
-* Michael Marineau <michael.marineau@coreos.com>
-* Michael Meeks <michael.meeks@suse.com>
-* Michał Mirosław <mirq-linux@rere.qmqm.pl>
-* Mihai Serban <mihai.serban@intel.com>
-* Mike Frysinger <vapier@gentoo.org>
-* Mike Gulick <mgulick@mathworks.com>
-* Mikhail Kolomeytsev <mkolom@yandex-team.ru>
-* Mostyn Bramley-Moore <mostyn@antipode.se>
-* Neil Mushell <nmushell@bloomberg.net>
-* Nick Schultz <nick.schultz@intel.com>
-* Norbert Lange <nolange79@gmail.com>
-* Oded Shimon <oded@istraresearch.com>
-* Orgad Shaneh <orgad.shaneh@audiocodes.com>
-* Orion Poplawski <orion@cora.nwra.com>
-* Owen Mann <owen@mann.org>
-* Patrick von Reth <vonreth@kde.org>
-* Paul Griffith <paulg@cse.yorku.ca>
-* Pavel Boldin <pboldin@cloudlinux.com>
-* Per Nordlöw <per.nordlow@autoliv.com>
-* Peter Budai <peterbudai@hotmail.com>
-* Philippe Proulx <eeppeliteloop@gmail.com>
-* Rafael Kitover <rkitover@gmail.com>
-* Ramiro Polla <ramiro.polla@gmail.com>
-* Robin H. Johnson <robbat2@gentoo.org>
-* Rolf Bjarne Kvinge <rolf@xamarin.com>
-* RW <fbsd06@mlists.homeunix.com>
-* Ryan Brown <ryb@ableton.com>
-* Sam Gross <sgross@fb.com>
-* Thomas Otto <thomas.otto@psd-fs.de>
-* Thomas Röfer <Thomas.Roefer@dfki.de>
-* Timofei Kushnir <timophey@rdp.ru>
-* Tim Potter <tpot@samba.org>
-* Tomasz Miąsko <tomasz.miasko@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>
-* Wilson Snyder <wsnyder@wsnyder.org>
-* Xavier René-Corail <xavier.renecorail@gmail.com>
-* Yiding Jia <yiding@fb.com>
-* Yvan Janssens <friedkiwi@yvanj.me>
+* Alexey Tourbin
+* Alfred Landrum
+* Anders F Björklund
+* Andrea Bittau
+* Andreas Huber
+* André Klitzing
+* Andrew P Boie
+* Andrew Stubbs
+* Andrew Tridgell
+* Bernhard Bauer
+* Björn Jacke
+* Chiaki Ishikawa
+* Chris AtLee
+* Clemens Rabe
+* David Givone
+* Doug Anderson
+* Edward Z. Yang
+* Francois Marier
+* Gabriel Scherer
+* Geert Bosch
+* Geert Kloosterman
+* Grigory Entin
+* Havard Graff
+* Hongli Lai
+* Ivan Vaigult
+* Jiang Jiang
+* Joel Galenson
+* Joel Rosdahl
+* John Basila
+* John Coiner
+* Jon Bernard
+* Jonny Yu
+* Jørgen P. Tjernø
+* Josh Soref
+* Justin Lebar
+* Karl Chen
+* Kona Blend
+* Kovarththanan Rajaratnam
+* Lalit Chhabra
+* Lars Gustäbel
+* Leanid Chaika
+* Luboš Luňák
+* Maarten Maathuis
+* Mark Starovoytov
+* Martin Ettl
+* Martin Pool
+* Mathias De Maré
+* Matthias Kretz
+* Melven Roehrig-Zoellner
+* Michael Marineau
+* Michael Meeks
+* Michał Mirosław
+* Mihai Serban
+* Mike Frysinger
+* Mike Gulick
+* Mikhail Kolomeytsev
+* Mostyn Bramley-Moore
+* Neil Mushell
+* Nick Schultz
+* Norbert Lange
+* Oded Shimon
+* Orgad Shaneh
+* Orion Poplawski
+* Owen Mann
+* Patrick von Reth
+* Paul Griffith
+* Pavel Boldin
+* Pavol Sakac
+* Per Nordlöw
+* Peter Budai
+* Philippe Proulx
+* Rafael Kitover
+* Ramiro Polla
+* Robert Yang
+* Robin H. Johnson
+* Rolf Bjarne Kvinge
+* RW
+* Ryan Brown
+* Sam Gross
+* Thomas Otto
+* Thomas Röfer
+* Timofei Kushnir
+* Tim Potter
+* Tomasz Miąsko
+* Tom Hughes
+* Tor Arne Vestbø
+* Vadim Petrochenkov
+* Ville Skyttä
+* William S Fulton
+* Wilson Snyder
+* Xavier René-Corail
+* Yiding Jia
+* Yvan Janssens
 
 Thanks!
index aacab33641c1d9deb74cc46a47f7564c5959ea4e..aa15ee80a6562811c92ce8efaac5515948f31a85 100644 (file)
@@ -735,7 +735,7 @@ asciidoc.install(2);
 <body class="article">\r
 <div id="header">\r
 <h1>ccache authors</h1>\r
-<span id="revnumber">version 3.6</span>\r
+<span id="revnumber">version 3.7</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>
@@ -750,452 +750,467 @@ 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
+Alexey Tourbin\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
+Alfred Landrum\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Anders F Björklund &lt;<a href="mailto:anders.f.bjorklund@gmail.com">anders.f.bjorklund@gmail.com</a>&gt;\r
+Anders F Björklund\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Andrea Bittau &lt;<a href="mailto:a.bittau@cs.ucl.ac.uk">a.bittau@cs.ucl.ac.uk</a>&gt;\r
+Andrea Bittau\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Andreas Huber &lt;<a href="mailto:andreas.huber@deltaww.com">andreas.huber@deltaww.com</a>&gt;\r
+Andreas Huber\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-André Klitzing &lt;<a href="mailto:aklitzing@gmail.com">aklitzing@gmail.com</a>&gt;\r
+André Klitzing\r
 </p>\r
 </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
+Andrew P Boie\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Andrew Stubbs &lt;<a href="mailto:ams@codesourcery.com">ams@codesourcery.com</a>&gt;\r
+Andrew Stubbs\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 Tridgell\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Bernhard Bauer &lt;<a href="mailto:bauerb@chromium.org">bauerb@chromium.org</a>&gt;\r
+Bernhard Bauer\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Björn Jacke &lt;<a href="mailto:bj@sernet.de">bj@sernet.de</a>&gt;\r
+Björn Jacke\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Chiaki Ishikawa &lt;<a href="mailto:ishikawa@yk.rim.or.jp">ishikawa@yk.rim.or.jp</a>&gt;\r
+Chiaki Ishikawa\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Chris AtLee &lt;<a href="mailto:catlee@mozilla.com">catlee@mozilla.com</a>&gt;\r
+Chris AtLee\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Clemens Rabe &lt;<a href="mailto:clemens.rabe@gmail.com">clemens.rabe@gmail.com</a>&gt;\r
+Clemens Rabe\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-David Givone &lt;<a href="mailto:david@givone.net">david@givone.net</a>&gt;\r
+David Givone\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Edward Z. Yang &lt;<a href="mailto:ezyang@fb.com">ezyang@fb.com</a>&gt;\r
+Doug Anderson\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Francois Marier &lt;<a href="mailto:francois@debian.org">francois@debian.org</a>&gt;\r
+Edward Z. Yang\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Gabriel Scherer &lt;<a href="mailto:gabriel.scherer@gmail.com">gabriel.scherer@gmail.com</a>&gt;\r
+Francois Marier\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Geert Bosch &lt;<a href="mailto:geert@mongodb.com">geert@mongodb.com</a>&gt;\r
+Gabriel Scherer\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Geert Kloosterman &lt;<a href="mailto:geert.kloosterman@brightcomputing.com">geert.kloosterman@brightcomputing.com</a>&gt;\r
+Geert Bosch\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Grigory Entin &lt;<a href="mailto:grigorye@dins.ru">grigorye@dins.ru</a>&gt;\r
+Geert Kloosterman\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Havard Graff &lt;<a href="mailto:havard.graff@gmail.com">havard.graff@gmail.com</a>&gt;\r
+Grigory Entin\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Hongli Lai &lt;<a href="mailto:hongli@phusion.nl">hongli@phusion.nl</a>&gt;\r
+Havard Graff\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Ivan Vaigult &lt;<a href="mailto:i.vaigult@gmail.com">i.vaigult@gmail.com</a>&gt;\r
+Hongli Lai\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Jiang Jiang &lt;<a href="mailto:jiangj@opera.com">jiangj@opera.com</a>&gt;\r
+Ivan Vaigult\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Joel Galenson &lt;<a href="mailto:jgalenson@gmail.com">jgalenson@gmail.com</a>&gt;\r
+Jiang Jiang\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Joel Rosdahl &lt;<a href="mailto:joel@rosdahl.net">joel@rosdahl.net</a>&gt;\r
+Joel Galenson\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-John Basila &lt;<a href="mailto:jbasila@checkpoint.com">jbasila@checkpoint.com</a>&gt;\r
+Joel Rosdahl\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-John Coiner &lt;<a href="mailto:john.coiner@amd.com">john.coiner@amd.com</a>&gt;\r
+John Basila\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Jon Bernard &lt;<a href="mailto:jbernard@tuxion.com">jbernard@tuxion.com</a>&gt;\r
+John Coiner\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Jonny Yu &lt;<a href="mailto:yingshen.yu@gmail.com">yingshen.yu@gmail.com</a>&gt;\r
+Jon Bernard\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
+Jonny Yu\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Josh Soref &lt;<a href="mailto:jsoref@users.noreply.github.com">jsoref@users.noreply.github.com</a>&gt;\r
+Jørgen P. Tjernø\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Justin Lebar &lt;<a href="mailto:justin.lebar@gmail.com">justin.lebar@gmail.com</a>&gt;\r
+Josh Soref\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Karl Chen &lt;<a href="mailto:quarl@cs.berkeley.edu">quarl@cs.berkeley.edu</a>&gt;\r
+Justin Lebar\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Kona Blend &lt;<a href="mailto:kona8lend@gmail.com">kona8lend@gmail.com</a>&gt;\r
+Karl Chen\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Kovarththanan Rajaratnam &lt;<a href="mailto:kovarththanan.rajaratnam@gmail.com">kovarththanan.rajaratnam@gmail.com</a>&gt;\r
+Kona Blend\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Lalit Chhabra &lt;<a href="mailto:lchhabra@linuxmail.org">lchhabra@linuxmail.org</a>&gt;\r
+Kovarththanan Rajaratnam\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Lars Gustäbel &lt;<a href="mailto:lars@gustaebel.de">lars@gustaebel.de</a>&gt;\r
+Lalit Chhabra\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Leanid Chaika &lt;<a href="mailto:leanid.chaika@gmail.com">leanid.chaika@gmail.com</a>&gt;\r
+Lars Gustäbel\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Luboš Luňák &lt;<a href="mailto:l.lunak@centrum.cz">l.lunak@centrum.cz</a>&gt;\r
+Leanid Chaika\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Maarten Maathuis &lt;<a href="mailto:madman2003@shikahr.net">madman2003@shikahr.net</a>&gt;\r
+Luboš Luňák\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Mark Starovoytov &lt;<a href="mailto:starovoytov.mark@googlemail.com">starovoytov.mark@googlemail.com</a>&gt;\r
+Maarten Maathuis\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Martin Ettl &lt;<a href="mailto:ettl.martin78@gmail.com">ettl.martin78@gmail.com</a>&gt;\r
+Mark Starovoytov\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Martin Pool &lt;<a href="mailto:mbp@sourcefrog.net">mbp@sourcefrog.net</a>&gt;\r
+Martin Ettl\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Mathias De Maré &lt;<a href="mailto:mathias.de_mare@nokia.com">mathias.de_mare@nokia.com</a>&gt;\r
+Martin Pool\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Matthias Kretz &lt;<a href="mailto:kretz@kde.org">kretz@kde.org</a>&gt;\r
+Mathias De Maré\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Melven Roehrig-Zoellner &lt;<a href="mailto:Melven.Roehrig-Zoellner@DLR.de">Melven.Roehrig-Zoellner@DLR.de</a>&gt;\r
+Matthias Kretz\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Michael Marineau &lt;<a href="mailto:michael.marineau@coreos.com">michael.marineau@coreos.com</a>&gt;\r
+Melven Roehrig-Zoellner\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Michael Meeks &lt;<a href="mailto:michael.meeks@suse.com">michael.meeks@suse.com</a>&gt;\r
+Michael Marineau\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Michał Mirosław &lt;<a href="mailto:mirq-linux@rere.qmqm.pl">mirq-linux@rere.qmqm.pl</a>&gt;\r
+Michael Meeks\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Mihai Serban &lt;<a href="mailto:mihai.serban@intel.com">mihai.serban@intel.com</a>&gt;\r
+Michał Mirosław\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Mike Frysinger &lt;<a href="mailto:vapier@gentoo.org">vapier@gentoo.org</a>&gt;\r
+Mihai Serban\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Mike Gulick &lt;<a href="mailto:mgulick@mathworks.com">mgulick@mathworks.com</a>&gt;\r
+Mike Frysinger\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Mikhail Kolomeytsev &lt;<a href="mailto:mkolom@yandex-team.ru">mkolom@yandex-team.ru</a>&gt;\r
+Mike Gulick\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Mostyn Bramley-Moore &lt;<a href="mailto:mostyn@antipode.se">mostyn@antipode.se</a>&gt;\r
+Mikhail Kolomeytsev\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Neil Mushell &lt;<a href="mailto:nmushell@bloomberg.net">nmushell@bloomberg.net</a>&gt;\r
+Mostyn Bramley-Moore\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Nick Schultz &lt;<a href="mailto:nick.schultz@intel.com">nick.schultz@intel.com</a>&gt;\r
+Neil Mushell\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Norbert Lange &lt;<a href="mailto:nolange79@gmail.com">nolange79@gmail.com</a>&gt;\r
+Nick Schultz\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Oded Shimon &lt;<a href="mailto:oded@istraresearch.com">oded@istraresearch.com</a>&gt;\r
+Norbert Lange\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
+Oded Shimon\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Orion Poplawski &lt;<a href="mailto:orion@cora.nwra.com">orion@cora.nwra.com</a>&gt;\r
+Orgad Shaneh\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Owen Mann &lt;<a href="mailto:owen@mann.org">owen@mann.org</a>&gt;\r
+Orion Poplawski\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Patrick von Reth &lt;<a href="mailto:vonreth@kde.org">vonreth@kde.org</a>&gt;\r
+Owen Mann\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Paul Griffith &lt;<a href="mailto:paulg@cse.yorku.ca">paulg@cse.yorku.ca</a>&gt;\r
+Patrick von Reth\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Pavel Boldin &lt;<a href="mailto:pboldin@cloudlinux.com">pboldin@cloudlinux.com</a>&gt;\r
+Paul Griffith\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Per Nordlöw &lt;<a href="mailto:per.nordlow@autoliv.com">per.nordlow@autoliv.com</a>&gt;\r
+Pavel Boldin\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Peter Budai &lt;<a href="mailto:peterbudai@hotmail.com">peterbudai@hotmail.com</a>&gt;\r
+Pavol Sakac\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Philippe Proulx &lt;<a href="mailto:eeppeliteloop@gmail.com">eeppeliteloop@gmail.com</a>&gt;\r
+Per Nordlöw\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Rafael Kitover &lt;<a href="mailto:rkitover@gmail.com">rkitover@gmail.com</a>&gt;\r
+Peter Budai\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
+Philippe Proulx\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
+Rafael Kitover\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
+Ramiro Polla\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-RW &lt;<a href="mailto:fbsd06@mlists.homeunix.com">fbsd06@mlists.homeunix.com</a>&gt;\r
+Robert Yang\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Ryan Brown &lt;<a href="mailto:ryb@ableton.com">ryb@ableton.com</a>&gt;\r
+Robin H. Johnson\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Sam Gross &lt;<a href="mailto:sgross@fb.com">sgross@fb.com</a>&gt;\r
+Rolf Bjarne Kvinge\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Thomas Otto &lt;<a href="mailto:thomas.otto@psd-fs.de">thomas.otto@psd-fs.de</a>&gt;\r
+RW\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Thomas Röfer &lt;<a href="mailto:Thomas.Roefer@dfki.de">Thomas.Roefer@dfki.de</a>&gt;\r
+Ryan Brown\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Timofei Kushnir &lt;<a href="mailto:timophey@rdp.ru">timophey@rdp.ru</a>&gt;\r
+Sam Gross\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Tim Potter &lt;<a href="mailto:tpot@samba.org">tpot@samba.org</a>&gt;\r
+Thomas Otto\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Tomasz Miąsko &lt;<a href="mailto:tomasz.miasko@gmail.com">tomasz.miasko@gmail.com</a>&gt;\r
+Thomas Röfer\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Tom Hughes &lt;<a href="mailto:tomtheengineer@gmail.com">tomtheengineer@gmail.com</a>&gt;\r
+Timofei Kushnir\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
+Tim Potter\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Vadim Petrochenkov &lt;<a href="mailto:vadim.petrochenkov@gmail.com">vadim.petrochenkov@gmail.com</a>&gt;\r
+Tomasz Miąsko\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Ville Skyttä &lt;<a href="mailto:ville.skytta@iki.fi">ville.skytta@iki.fi</a>&gt;\r
+Tom Hughes\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-William S Fulton &lt;<a href="mailto:wsf@fultondesigns.co.uk">wsf@fultondesigns.co.uk</a>&gt;\r
+Tor Arne Vestbø\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Wilson Snyder &lt;<a href="mailto:wsnyder@wsnyder.org">wsnyder@wsnyder.org</a>&gt;\r
+Vadim Petrochenkov\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Xavier René-Corail &lt;<a href="mailto:xavier.renecorail@gmail.com">xavier.renecorail@gmail.com</a>&gt;\r
+Ville Skyttä\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Yiding Jia &lt;<a href="mailto:yiding@fb.com">yiding@fb.com</a>&gt;\r
+William S Fulton\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Yvan Janssens &lt;<a href="mailto:friedkiwi@yvanj.me">friedkiwi@yvanj.me</a>&gt;\r
+Wilson Snyder\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Xavier René-Corail\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Yiding Jia\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Yvan Janssens\r
 </p>\r
 </li>\r
 </ul></div>\r
@@ -1206,9 +1221,9 @@ Yvan Janssens &lt;<a href="mailto:friedkiwi@yvanj.me">friedkiwi@yvanj.me</a>&gt;
 <div id="footnotes"><hr /></div>\r
 <div id="footer">\r
 <div id="footer-text">\r
-Version 3.6<br />\r
+Version 3.7<br />\r
 Last updated\r
- 2019-01-14 21:09:34 CET\r
+ 2019-04-23 21:35:11 CEST\r
 </div>\r
 </div>\r
 </body>\r
index 7a5766054b93f45498e7a74b36561714f153beb3..bfafd3025ff3b14b41549274fb4dc4f0ad7457f3 100644 (file)
@@ -115,16 +115,31 @@ compiler options apply and you should refer to the compiler's documentation.
     Clear the entire cache, removing all cached files, but keeping the
     configuration file.
 
-*`-F, --max-files`*=_N_::
+*`--dump-manifest`*=_PATH_::
 
-    Set the maximum number of files allowed in the cache. Use 0 for no limit.
-    The value is stored in a configuration file in the cache directory and
-    applies to all future compilations.
+    Dump manifest file at PATH in text format. This is only useful when
+    debugging ccache and its behavior.
+
+*`-k, --get-config`*=_KEY_::
+
+    Print the value of configuration option _KEY_. See
+    <<_configuration,CONFIGURATION>> for more information.
+
+*`--hash-file`*=_PATH_::
+
+    Print the hash (in format `<MD4>-<size>`) of the file at PATH. This is only
+    useful when debugging ccache and its behavior.
 
 *`-h, --help`*::
 
     Print an options summary page.
 
+*`-F, --max-files`*=_N_::
+
+    Set the maximum number of files allowed in the cache. Use 0 for no limit.
+    The value is stored in a configuration file in the cache directory and
+    applies to all future compilations.
+
 *`-M, --max-size`*=_SIZE_::
 
     Set the maximum size of the files stored in the cache. _SIZE_ should be a
@@ -133,19 +148,26 @@ compiler options apply and you should refer to the compiler's documentation.
     stored in a configuration file in the cache directory and applies to all
     future compilations.
 
+*`--print-stats`*::
+
+    Print statistics counter IDs and corresponding values machine-parsable
+    (tab-separated) format.
+
 *`-o, --set-config`*=_KEY=VALUE_::
 
-    Set configuration _KEY_ to _VALUE_. See <<_configuration,CONFIGURATION>>
-    for more information.
+    Set configuration option _KEY_ to _VALUE_. See
+    <<_configuration,CONFIGURATION>> for more information.
 
-*`-p, --print-config`*::
+*`-p, --show-config`*::
 
     Print current configuration options and from where they originate
-    (environment variable, configuration file or compile-time default).
+    (environment variable, configuration file or compile-time default) in
+    human-readable format.
 
 *`-s, --show-stats`*::
 
-    Print the current statistics summary for the cache.
+    Print a summary of configuration and statistics counters in human-readable
+    format.
 
 *`-V, --version`*::
 
@@ -1142,9 +1164,10 @@ General
 ~~~~~~~
 
 A general tip for getting information about what ccache is doing is to enable
-debug logging by setting *log_file*. The log contains executed commands,
-important decisions that ccache makes, read and written files, etc. Another way
-of keeping track of what is happening is to check the output of *ccache -s*.
+debug logging by setting the configuration option *debug* (or the environment
+variable *CCACHE_DEBUG*); see <<_cache_debugging,debugging>> for more
+information. Another way of keeping track of what is happening is to check the
+output of *ccache -s*.
 
 
 Performance
@@ -1249,7 +1272,7 @@ More information
 ----------------
 
 Credits, mailing list information, bug reporting instructions, source code,
-etc, can be found on ccache's web site: <https://ccache.samba.org>.
+etc, can be found on ccache's web site: <https://ccache.dev>.
 
 
 Author
@@ -1257,4 +1280,4 @@ Author
 
 ccache was originally written by Andrew Tridgell and is currently developed and
 maintained by Joel Rosdahl. See AUTHORS.txt or AUTHORS.html and
-<https://ccache.samba.org/credits.html> for a list of contributors.
+<https://ccache.dev/credits.html> for a list of contributors.
index 7f3bc98de8f912a2f8e778f76ed5376b2e3b2f2a..b25e3c742a57b0a85dd18d77fb1941c80e0fc3bf 100644 (file)
@@ -735,7 +735,7 @@ asciidoc.install(2);
 <body class="article">\r
 <div id="header">\r
 <h1>CCACHE(1)</h1>\r
-<span id="revnumber">version 3.6</span>\r
+<span id="revnumber">version 3.7</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>
@@ -907,13 +907,30 @@ compiler options apply and you should refer to the compiler&#8217;s documentatio
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
-<strong><code>-F, --max-files</code></strong>=<em>N</em>\r
+<strong><code>--dump-manifest</code></strong>=<em>PATH</em>\r
 </dt>\r
 <dd>\r
 <p>\r
-    Set the maximum number of files allowed in the cache. Use 0 for no limit.\r
-    The value is stored in a configuration file in the cache directory and\r
-    applies to all future compilations.\r
+    Dump manifest file at PATH in text format. This is only useful when\r
+    debugging ccache and its behavior.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+<strong><code>-k, --get-config</code></strong>=<em>KEY</em>\r
+</dt>\r
+<dd>\r
+<p>\r
+    Print the value of configuration option <em>KEY</em>. See\r
+    <a href="#_configuration">CONFIGURATION</a> for more information.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+<strong><code>--hash-file</code></strong>=<em>PATH</em>\r
+</dt>\r
+<dd>\r
+<p>\r
+    Print the hash (in format <code>&lt;MD4&gt;-&lt;size&gt;</code>) of the file at PATH. This is only\r
+    useful when debugging ccache and its behavior.\r
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
@@ -925,6 +942,16 @@ compiler options apply and you should refer to the compiler&#8217;s documentatio
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
+<strong><code>-F, --max-files</code></strong>=<em>N</em>\r
+</dt>\r
+<dd>\r
+<p>\r
+    Set the maximum number of files allowed in the cache. Use 0 for no limit.\r
+    The value is stored in a configuration file in the cache directory and\r
+    applies to all future compilations.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
 <strong><code>-M, --max-size</code></strong>=<em>SIZE</em>\r
 </dt>\r
 <dd>\r
@@ -937,21 +964,31 @@ compiler options apply and you should refer to the compiler&#8217;s documentatio
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
+<strong><code>--print-stats</code></strong>\r
+</dt>\r
+<dd>\r
+<p>\r
+    Print statistics counter IDs and corresponding values machine-parsable\r
+    (tab-separated) format.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
 <strong><code>-o, --set-config</code></strong>=<em>KEY=VALUE</em>\r
 </dt>\r
 <dd>\r
 <p>\r
-    Set configuration <em>KEY</em> to <em>VALUE</em>. See <a href="#_configuration">CONFIGURATION</a>\r
-    for more information.\r
+    Set configuration option <em>KEY</em> to <em>VALUE</em>. See\r
+    <a href="#_configuration">CONFIGURATION</a> for more information.\r
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
-<strong><code>-p, --print-config</code></strong>\r
+<strong><code>-p, --show-config</code></strong>\r
 </dt>\r
 <dd>\r
 <p>\r
     Print current configuration options and from where they originate\r
-    (environment variable, configuration file or compile-time default).\r
+    (environment variable, configuration file or compile-time default) in\r
+    human-readable format.\r
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
@@ -959,7 +996,8 @@ compiler options apply and you should refer to the compiler&#8217;s documentatio
 </dt>\r
 <dd>\r
 <p>\r
-    Print the current statistics summary for the cache.\r
+    Print a summary of configuration and statistics counters in human-readable\r
+    format.\r
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
@@ -2511,9 +2549,10 @@ If ccache guesses that the compiler may emit colored warnings, then a
 <div class="sect2">\r
 <h3 id="_general">General</h3>\r
 <div class="paragraph"><p>A general tip for getting information about what ccache is doing is to enable\r
-debug logging by setting <strong>log_file</strong>. The log contains executed commands,\r
-important decisions that ccache makes, read and written files, etc. Another way\r
-of keeping track of what is happening is to check the output of <strong>ccache -s</strong>.</p></div>\r
+debug logging by setting the configuration option <strong>debug</strong> (or the environment\r
+variable <strong>CCACHE_DEBUG</strong>); see <a href="#_cache_debugging">debugging</a> for more\r
+information. Another way of keeping track of what is happening is to check the\r
+output of <strong>ccache -s</strong>.</p></div>\r
 </div>\r
 <div class="sect2">\r
 <h3 id="_performance">Performance</h3>\r
@@ -2682,7 +2721,7 @@ case, please report it.</p></div>
 <h2 id="_more_information">More information</h2>\r
 <div class="sectionbody">\r
 <div class="paragraph"><p>Credits, mailing list information, bug reporting instructions, source code,\r
-etc, can be found on ccache&#8217;s web site: <a href="https://ccache.samba.org">https://ccache.samba.org</a>.</p></div>\r
+etc, can be found on ccache&#8217;s web site: <a href="https://ccache.dev">https://ccache.dev</a>.</p></div>\r
 </div>\r
 </div>\r
 <div class="sect1">\r
@@ -2690,16 +2729,16 @@ etc, can be found on ccache&#8217;s web site: <a href="https://ccache.samba.org"
 <div class="sectionbody">\r
 <div class="paragraph"><p>ccache was originally written by Andrew Tridgell and is currently developed and\r
 maintained by Joel Rosdahl. See AUTHORS.txt or AUTHORS.html and\r
-<a href="https://ccache.samba.org/credits.html">https://ccache.samba.org/credits.html</a> for a list of contributors.</p></div>\r
+<a href="https://ccache.dev/credits.html">https://ccache.dev/credits.html</a> for a list of contributors.</p></div>\r
 </div>\r
 </div>\r
 </div>\r
 <div id="footnotes"><hr /></div>\r
 <div id="footer">\r
 <div id="footer-text">\r
-Version 3.6<br />\r
+Version 3.7<br />\r
 Last updated\r
- 2019-01-13 21:38:14 CET\r
+ 2019-04-23 21:35:11 CEST\r
 </div>\r
 </div>\r
 </body>\r
index 41197d3dfc83adb6059e6267d0c154df2648a726..0a1a17cd4fea8c4332a62292dde607685c0e1ba2 100644 (file)
@@ -1,6 +1,83 @@
 ccache news
 ===========
 
+ccache 3.7
+----------
+Release date: 2019-04-23
+
+Changes
+~~~~~~~
+
+- Fixed crash when the debug mode is enabled and the output file is in a
+  non-writable directory, e.g. when the output file is `/dev/null`.
+
+- Fixed an issue when printing very large log messages to the debug log.
+
+- Fixed bugs related to support for `-gsplit-dwarf`. Previously ccache could
+  produce an incorrect link to the `.dwo` file in the `.o` file.
+
+- Compilations with /dev/null as the input file are now cached.
+
+- ccache has learned how to contruct the object filename if no `-o` option is
+  given and the source filename does not include a `.` or ends with a `.`.
+
+- Fixed a temporary file leak when the depend mode is enabled and the compiler
+  produces standard error output.
+
+- Fixed a bug in the depend mode where a manifest hash only could be associated
+  with one set of header dependencies.
+
+- Manifest files did not get marked as used on direct cache hits, so the LRU
+  cache cleanup would incorrectly remove them eventually. This has been fixed.
+
+- The rewriting of absolute paths into relative paths in the dependency file
+  has been enabled in the depend mode as well.
+
+- ccache now ignores unknown keys in configuration files for forward
+  compatibility.
+
+- Rearranged command-line options into sections in the help text.
+
+- Documented the previously undocumented `--dump-manifest` and `--hash-file`
+  options (only useful for debugging ccache itself).
+
+- Added missing documentation for the command-line option `-k/--get-config`
+  added in ccache 3.5.
+
+- Renamed the `--print-config` command to `--show-config`.
+
+- Added a new `--print-stats` command that prints statistics counters in
+  machine-parsable (tab-separated) format.
+
+- ccache no longer creates a missing output directory, thus mimicking the
+  compiler behavior for `-o out/obj.o` when “out” doesn’t exist.
+
+- `-fdebug-prefix-map=ARG`, `-ffile-prefix-map=ARG` and
+  `-fmacro-prefix-map=ARG` are now included in the hash, but only the part
+  before “ARG”. This fixes a bug where compiler feature detection of said flags
+  would not work correctly with ccache.
+
+- Bail out on too hard compiler option `-gtoggle`.
+
+- Bail out on too hard Clang options `--analyze` and `-analyze`.
+
+- Improved debug logging of file hashes in depend mode.
+
+- Improved handling of various `-g*` options. In particular, ccache now
+  understands that `-g0` cancels out previous `-g* options`.
+
+- Worked around a problem with Automake related to `.d` files when using the
+  hard link mode.
+
+- Added opt-in (at configure time) support for enabling trace logs for
+  profiling ccache itself. See `doc/DEVELOPER.md` in the code tree for more
+  information
+
+- Removed support for Fortran 77 again. Some Fortran support was added in
+  ccache 3.3, but the implementation did not work when Fortran modules are
+  involved.
+
+
 ccache 3.6
 ----------
 Release date: 2019-01-14
@@ -8,12 +85,12 @@ Release date: 2019-01-14
 Changes
 ~~~~~~~
 
-- ccache now has an opt-in ``depend mode''. When enabled, ccache never executes
+- ccache now has an opt-in “depend mode”. When enabled, ccache never executes
   the preprocessor, which results in much lower cache miss overhead at the
   expense of a lower potential cache hit rate. The depend mode is only possible
   to use when the compiler option `-MD` or `-MMD` is used.
 
-- Added support for GCC's `-ffile-prefix-map` option. The `-fmacro-prefix-map`
+- Added support for GCCs `-ffile-prefix-map` option. The `-fmacro-prefix-map`
   option is now also skipped from the hash.
 
 - Added support for multiple `-fsanitize-blacklist` arguments.
@@ -34,7 +111,7 @@ Changes
 - A new sloppiness setting `clang_index_store` makes ccache skip the Clang
   compiler option `-index-store-path` 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't be
+  path derived from the local project path. Note that the index store wont be
   updated correctly on cache hits if you enable this option.
 
 - Rename sloppiness `no_system_headers` to `system_headers` for consistency
@@ -45,7 +122,7 @@ Changes
   supported correctly.
 
 - The algorithm that scans for `__DATE_` and `__TIME__` tokens in the hashed
-  source code now doesn't produce false positives for tokens where `__DATE__`
+  source code now doesnt produce false positives for tokens where `__DATE__`
   or `__TIME__` is a substring.
 
 
@@ -74,8 +151,8 @@ Changes
 
 - Added a boolean `debug` (`CCACHE_DEBUG`) configuration option. When enabled,
   ccache will create per-object debug files that are helpful e.g. when
-  debugging unexpected cache misses. See also the new ``Cache debugging''
-  section in the manual.
+  debugging unexpected cache misses. See also the new “Cache debugging” section
+  in the manual.
 
 - Renamed `CCACHE_CC` to `CCACHE_COMPILER` (keeping the former as a deprecated
   alias).
@@ -91,21 +168,21 @@ Changes
 - Improved performance substantially when using `hash_dir = false` on platforms
   like macOS where `getcwd()` is slow.
 
-- Added ``stats updated'' timestamp in `ccache -s` output. This can be useful
-  if you wonder whether ccache actually was used for your last build.
+- Added “stats updated” timestamp in `ccache -s` output. This can be useful if
+  you wonder whether ccache actually was used for your last build.
 
-- Renamed ``stats zero time'' to ``stats zeroed'' and documented it. The
-  counter is also now only present in `ccache -s` output when `ccache -z`
-  actually has been called.
+- Renamed “stats zero time” to “stats zeroed” and documented it. The counter is
+  also now only present in `ccache -s` output when `ccache -z` actually has
+  been called.
 
 - The content of the `-fsanitize-blacklist` file is now included in the hash,
   so updates to the file will now correctly result in separate cache entries.
 
-- It's now possible to opt out of building and installing man pages when
+- Its now possible to opt out of building and installing man pages when
   running `make install` in the source repository.
 
-- If the compiler type can't be detected (e.g. if it is named `cc`), use safer
-  defaults that won't trip up Clang.
+- If the compiler type cant be detected (e.g. if it is named `cc`), use safer
+  defaults that wont trip up Clang.
 
 - Made the ccache test suite work on FreeBSD.
 
@@ -147,14 +224,14 @@ Bug fixes
   triggered at the same time, in extreme cases trimming the cache to a much
   smaller size than the configured limits.
 
-- Correctly hash preprocessed headers located in a ``.gch directory''.
+- Correctly hash preprocessed headers located in a “.gch directory”.
   Previously, ccache would not pick up changes to such precompiled headers,
   risking false positive cache hits.
 
 - Fixed build failure when using the bundled zlib sources.
 
 - ccache 3.3.5 added a workaround for not triggering Clang errors when a
-  precompiled header's dependency has an updated timestamp (but identical
+  precompiled headers dependency has an updated timestamp (but identical
   content). That workaround is now only applied when the compiler is Clang.
 
 - Made it possible to perform out-of-source builds in dev mode again.
@@ -182,7 +259,7 @@ New features and enhancements
 
 - Added support for caching `.su` files generated by GCC flag `-fstack-usage`.
 
-- ccache should now work with distcc's ``pump'' wrapper.
+- ccache should now work with distcc’s “pump” wrapper.
 
 - The optional unifier is no longer disabled when the direct mode is enabled.
 
@@ -191,7 +268,7 @@ New features and enhancements
 
 - Boolean environment variable settings no longer accept the following
   (case-insensitive) values: `0`, `false`, `disable` and `no`. All other values
-  are accepted and taken to mean ``true''. This is to stop users from setting
+  are accepted and taken to mean “true”. This is to stop users from setting
   e.g. `CCACHE_DISABLE=0` and then expect the cache to be used.
 
 - Improved support for `run_second_cpp = false`: If combined with passing
@@ -200,7 +277,7 @@ New features and enhancements
 
 - An implicit `-MQ` is now passed to the preprocessor only if the object file
   extension is non-standard. This should make it easier to use EDG-based
-  compilers (e.g. GHS) which don't understand `-MQ`.
+  compilers (e.g. GHS) which dont understand `-MQ`.
 
 - ccache now treats an unreadable configuration file just like a missing
   configuration file.
@@ -253,7 +330,7 @@ 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.
+  This reverts the “Improved parsing of `-g*` options” feature in ccache 3.3.
 
 - Multiple `-fdebug-prefix-map` options should now be handled correctly.
 
@@ -271,9 +348,9 @@ Bug fixes
 
 - `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.
+  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.
@@ -301,8 +378,8 @@ Bug fixes
 - Fixed a regression in ccache 3.3 related to potentially bad content of
   dependency files when compiling identical source code but with different
   source paths. This was only partially fixed in 3.3.2 and reverts the new
-  ``Names of included files are no longer included in the hash of the
-  compiler's preprocessed output'' feature in 3.3.
+  “Names of included files are no longer included in the hash of the compiler’s
+  preprocessed output” feature in 3.3.
 
 - Corrected statistics counter for `-optf`/`--options-file` failure.
 
@@ -342,9 +419,9 @@ Release date: 2016-09-07
 Bug fixes
 ~~~~~~~~~
 
-- Fixed a problem in the ``multiple `-arch` options'' support introduced in
-  3.3. When using the direct mode (the default), different combinations of
-  `-arch` options were not detected properly.
+- Fixed a problem in the “multiple `-arch` options” support introduced in 3.3.
+  When using the direct mode (the default), different combinations of `-arch`
+  options were not detected properly.
 
 - Fixed an issue when compiler option `-Wp,-MT,path` is used instead of `-MT
   path` (and similar for `-MF`, `-MP` and `-MQ`) and `run_second_cpp`
@@ -365,8 +442,8 @@ New features and enhancements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 - The configuration option `run_second_cpp` (`CCACHE_CPP2`) now defaults to
-  true. This improves ccache's out-of-the-box experience for compilers that
-  can't compile their own preprocessed output with the same outcome as if they
+  true. This improves ccaches out-of-the-box experience for compilers that
+  cant compile their own preprocessed output with the same outcome as if they
   compiled the real source code directly, e.g. newer versions of GCC and Clang.
 
 - The configuration option `hash_dir` (`CCACHE_HASHDIR`) now defaults to true.
@@ -390,16 +467,16 @@ New features and enhancements
 
 - Added a new statistics counter that tracks the number of performed cleanups
   due to the cache size being over the limit. The value is shown in the output
-  of ``ccache -s''.
+  of “ccache -s”.
 
 - Added support for relocating debug info directory using `-fdebug-prefix-map`.
   This allows for cache hits even when `hash_dir` is used in combination with
   `base_dir`.
 
-- Added a new ``cache hit rate'' field to the output of ``ccache -s''.
+- Added a new “cache hit rate” field to the output of “ccache -s”.
 
-- Added support for caching compilation of assembler code produced by e.g.
-  ``gcc -S file.c''.
+- Added support for caching compilation of assembler code produced by e.g. “gcc
+  -S file.c”.
 
 - Added support for cuda including the -optf/--options-file option.
 
@@ -427,7 +504,7 @@ New features and enhancements
 - ccache now understands the undocumented `-coverage` (only one dash) GCC
   option.
 
-- Names of included files are no longer included in the hash of the compiler's
+- Names of included files are no longer included in the hash of the compilers
   preprocessed output. This leads to more potential cache hits when not using
   the direct mode.
 
@@ -482,7 +559,7 @@ Bug fixes
 - Fixed a bug which could lead to false cache hits for compiler command lines
   with a missing argument to an option that takes an argument.
 
-- ccache now knows how to work around a glitch in the output of GCC 6's
+- ccache now knows how to work around a glitch in the output of GCC 6s
   preprocessor.
 
 
@@ -493,10 +570,10 @@ Release date: 2016-07-12
 Bug fixes
 ~~~~~~~~~
 
-- Fixed build problem on QNX, which lacks ``SA_RESTART''.
+- Fixed build problem on QNX, which lacks “SA_RESTART”.
 
 - Bail out on compiler option `-fstack-usage` since it creates a `.su` file
-  which ccache currently doesn't handle.
+  which ccache currently doesnt handle.
 
 - Fixed a bug where (due to ccache rewriting paths) the compiler could choose
   incorrect include files if `CCACHE_BASEDIR` is used and the source file path
@@ -515,7 +592,7 @@ New features and enhancements
 
 - Improved handling of stale NFS handles.
 
-- Made it harder to misinterpret documentation of boolean environment settings'
+- Made it harder to misinterpret documentation of boolean environment settings
   semantics.
 
 
@@ -531,17 +608,17 @@ Bug fixes
 
 - Fixed failure to create directories on QNX.
 
-- Don't (try to) update manifest file in ``read-only'' and ``read-only direct''
+- Don’t (try to) update manifest file in “read-only” and “read-only direct”
   modes.
 
-- Fixed a bug in caching of `stat` system calls in ``file_stat_matches
-  sloppiness mode''.
+- Fixed a bug in caching of `stat` system calls in file_stat_matches
+  sloppiness mode.
 
 - Fixed bug in hashing of Clang plugins, leading to unnecessary cache misses.
 
-- Fixed --print-config to show ``pch_defines sloppiness''.
+- Fixed --print-config to show “pch_defines sloppiness”.
 
-- The man page is now built when running ``make install'' from Git repository
+- The man page is now built when running “make install” from Git repository
   sources.
 
 
@@ -605,7 +682,7 @@ New features and enhancements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 - Added support for `CCACHE_COMPILERCHECK=string:<value>`. This is a faster
-  alternative to `CCACHE_COMPILERCHECK=<command>` if the command's output can
+  alternative to `CCACHE_COMPILERCHECK=<command>` if the commands output can
   be precalculated by the build system.
 
 - Add support for caching code coverage results (compiling for gcov).
@@ -618,9 +695,8 @@ Bug fixes
   This makes it possible to rebuild with `CCACHE_CPP2` set without having to
   clear the cache to get new results.
 
-- Don't try to reset a nonexistent stats file. This avoids ``No such file or
-  directory'' messages in the ccache log when the cache directory doesn't
-  exist.
+- Don’t try to reset a nonexistent stats file. This avoids “No such file or
+  directory” messages in the ccache log when the cache directory doesn’t exist.
 
 - Fixed a bug where ccache deleted Clang diagnostics after compiler failures.
 
@@ -690,7 +766,7 @@ New features and enhancements
 - Added support for several binaries (separated by space) in `CCACHE_PREFIX`.
 
 - The `-c` option is no longer passed to the preprocessor. This fixes problems
-  with Clang and Solaris's C++ compiler.
+  with Clang and Solariss C++ compiler.
 
 - ccache no longer passes preprocessor options like `-D` and `-I` to the
   compiler when compiling preprocessed output. This fixes warnings emitted by
@@ -699,7 +775,7 @@ New features and enhancements
 - Compiler options `-fprofile-generate`, `-fprofile-arcs`, `-fprofile-use` and
   `-fbranch-probabilities` are now handled without bailing.
 
-- Added support for Clang's `--serialize-diagnostic` option, storing the
+- Added support for Clangs `--serialize-diagnostic` option, storing the
   diagnostic file (`.dia`) in the cache.
 
 - Added support for precompiled headers when using Clang.
@@ -714,21 +790,21 @@ New features and enhancements
   the other way around. This is needed to support compiler options like
   `-fprofile-arcs` and `--serialize-diagnostics`.
 
-- ccache now checks that included files' ctimes aren't too new. This check can
-  be turned off by adding `include_file_ctime` to the ``ccache sloppiness''
+- ccache now checks that included files’ ctimes aren’t too new. This check can
+  be turned off by adding `include_file_ctime` to the “ccache sloppiness”
   setting.
 
 - Added possibility to get cache hits based on filename, size, mtime and ctime
   only. On other words, source code files are not even read, only stat-ed. This
-  operation mode is opt-in by adding `file_stat_matches` to the ``ccache
-  sloppiness'' setting.
+  operation mode is opt-in by adding `file_stat_matches` to the ccache
+  sloppiness setting.
 
 - The filename part of options like `-Wp,-MDfilename` is no longer included in
-  the hash since the filename doesn't have any bearing on the result.
+  the hash since the filename doesnt have any bearing on the result.
 
-- Added a ``read-only direct'' configuration setting, which is like the
-  ordinary read-only setting except that ccache will only try to retrieve
-  results from the cache using the direct mode, not the preprocessor mode.
+- Added a “read-only direct” configuration setting, which is like the ordinary
+  read-only setting except that ccache will only try to retrieve results from
+  the cache using the direct mode, not the preprocessor mode.
 
 - The display and interpretation of cache size has been changed to use SI
   units.
@@ -741,7 +817,7 @@ New features and enhancements
 - Added support for `@file` and `-@file` arguments (reading options from a
   file).
 
-- `-Wl,` options are no longer included in the hash since they don't affect
+- `-Wl,` options are no longer included in the hash since they dont affect
   compilation.
 
 - Bail out on too hard compiler option `-Wp,-P`.
@@ -805,9 +881,8 @@ Bug fixes
   This makes it possible to rebuild with `CCACHE_CPP2` set without having to
   clear the cache to get new results.
 
-- Don't try to reset a nonexistent stats file. This avoids ``No such file or
-  directory'' messages in the ccache log when the cache directory doesn't
-  exist.
+- Don’t try to reset a nonexistent stats file. This avoids “No such file or
+  directory” messages in the ccache log when the cache directory doesn’t exist.
 
 
 ccache 3.1.10
@@ -831,11 +906,11 @@ New features and enhancements
   `CCACHE_BASEDIR` to reuse results across different directories.)
 
 - Added note in documentation that `--ccache-skip` currently does not mean
-  ``don't hash the following option''.
+  “don’t hash the following option”.
 
 - To enable support for precompiled headers (PCH), `CCACHE_SLOPPINESS` now also
   needs to include the new `pch_defines` sloppiness. This is because ccache
-  can't detect changes in the source code when only defined macros have been
+  cant detect changes in the source code when only defined macros have been
   changed.
 
 - Stale files in the internal temporary directory (`<ccache_dir>/tmp`) are now
@@ -845,7 +920,7 @@ New features and enhancements
 Bug fixes
 ~~~~~~~~~
 
-- Fixed path canonicalization in `make_relative_path()` when path doesn't
+- Fixed path canonicalization in `make_relative_path()` when path doesnt
   exist.
 
 - Fixed bug in `common_dir_prefix_length()`. This corrects the `CCACHE_BASEDIR`
@@ -874,7 +949,7 @@ Bug fixes
 
 - Subdirectories in the cache are no longer created in read-only mode.
 
-- Fixed so that ccache's log file descriptor is not made available to the
+- Fixed so that ccaches log file descriptor is not made available to the
   compiler.
 
 - Improved error reporting when failing to create temporary stdout/stderr files
@@ -982,9 +1057,9 @@ New features and enhancements
 Bug fixes
 ~~~~~~~~~
 
-- Don't crash if `getcwd()` fails.
+- Dont crash if `getcwd()` fails.
 
-- Fixed alignment of ``called for preprocessing'' counter.
+- Fixed alignment of “called for preprocessing” counter.
 
 
 ccache 3.1.5
@@ -995,7 +1070,7 @@ Release date: 2011-05-29
 New features and enhancements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-- Added a new statistics counter named ``called for preprocessing''.
+- Added a new statistics counter named “called for preprocessing”.
 
 - The original command line is now logged to the file specified with
   `CCACHE_LOGFILE`.
@@ -1019,7 +1094,7 @@ Bug fixes
 
 - Fixed a minor memory leak.
 
-- Systems that lack (and don't need to be linked with) libm are now supported.
+- Systems that lack (and dont need to be linked with) libm are now supported.
 
 
 ccache 3.1.4
@@ -1032,10 +1107,10 @@ Bug fixes
 
 - Made a work-around for a bug in `gzputc()` in zlib 1.2.5.
 
-- Corrupt manifest files are now removed so that they won't block direct mode
+- Corrupt manifest files are now removed so that they wont block direct mode
   hits.
 
-- ccache now copes with file systems that don't know about symbolic links.
+- ccache now copes with file systems that dont know about symbolic links.
 
 - The file handle in now correctly closed on write error when trying to create
   a cache dir tag.
@@ -1080,7 +1155,7 @@ Other
 
 - Improved documentation on which information is included in the hash sum.
 
-- Made the ``too new header file'' test case work on file systems with
+- Made the “too new header file” test case work on file systems with
   unsynchronized clocks.
 
 - The test suite now also works on systems that lack a /dev/zero.
@@ -1107,7 +1182,7 @@ Bug fixes
 - Fixed configure detection of ar.
 
 - ccache development version (set by dev.mk) now works with gits whose
-  `describe` command doesn't understand `--dirty`.
+  `describe` command doesnt understand `--dirty`.
 
 
 Other
@@ -1127,7 +1202,7 @@ New features and enhancements
 - Added support for hashing the output of a custom command (e.g. `%compiler%
   --version`) to identify the compiler instead of stat-ing or hashing the
   compiler binary. This can improve robustness when the compiler (as seen by
-  ccache) actually isn't the real compiler but another compiler wrapper.
+  ccache) actually isnt the real compiler but another compiler wrapper.
 
 - Added support for caching compilations that use precompiled headers. (See the
   manual for important instructions regarding this.)
@@ -1146,9 +1221,9 @@ New features and enhancements
 - Reading and writing of statistics counters has been made forward-compatible
   (unknown counters are retained).
 
-- Files are now read without using `mmap()`. This has two benefits: it's more
+- Files are now read without using `mmap()`. This has two benefits: its more
   robust against file changes during reading and it improves performance on
-  poor systems where `mmap()` doesn't use the disk cache.
+  poor systems where `mmap()` doesnt use the disk cache.
 
 - Added `.cp` and `.CP` as known C++ suffixes.
 
@@ -1205,7 +1280,7 @@ Release date: 2010-07-15
 Bug fixes
 ~~~~~~~~~
 
-- The statistics counter ``called for link'' is now correctly updated when
+- The statistics counter “called for link” is now correctly updated when
   linking with a single object file.
 
 - Fixed a problem with out-of-source builds.
@@ -1226,7 +1301,7 @@ General
 Upgrade notes
 ~~~~~~~~~~~~~
 
-- The way the hashes are calculated has changed, so you won't get cache hits
+- The way the hashes are calculated has changed, so you wont get cache hits
   for compilation results stored by older ccache versions. Because of this, you
   might as well clear the old cache directory with `ccache --clear` if you
   want, unless you plan to keep using an older ccache version.
@@ -1235,7 +1310,7 @@ Upgrade notes
 New features and enhancements
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-- ccache now has a ``direct mode'' where it computes a hash of the source code
+- ccache now has a “direct mode” where it computes a hash of the source code
   (including all included files) and compiler options without running the
   preprocessor. By not running the preprocessor, CPU usage is reduced; the
   speed is somewhere between 1 and 5 times that of ccache running in
@@ -1253,19 +1328,19 @@ New features and enhancements
 - Object files are now optionally stored compressed in the cache. The runtime
   cost is negligible, and more files will fit in the ccache directory and in
   the disk cache. Set `CCACHE_COMPRESS` to enable object file compression. Note
-  that you can't use compression in combination with the hard link feature.
+  that you cant use compression in combination with the hard link feature.
 
 - A `CCACHE_COMPILERCHECK` option has been added. This option tells ccache what
   compiler-identifying information to hash to ensure that results retrieved
-  from the cache are accurate. Possible values are: none (don't hash anything),
-  mtime (hash the compiler's mtime and size) and content (hash the content of
+  from the cache are accurate. Possible values are: none (dont hash anything),
+  mtime (hash the compilers mtime and size) and content (hash the content of
   the compiler binary). The default is mtime.
 
 - It is now possible to specify extra files whose contents should be included
   in the hash sum by setting the `CCACHE_EXTRAFILES` option.
 
 - Added support for Objective-C and Objective-C\+\+. The statistics counter
-  ``not a C/C++ file'' has been renamed to ``unsupported source language''.
+  “not a C/C++ file” has been renamed to “unsupported source language”.
 
 - Added support for the `-x` compiler option.
 
@@ -1288,13 +1363,13 @@ New features and enhancements
 
 - Temporary files that later will be moved into the cache are now created in
   the cache directory they will end up in. This makes ccache more friendly to
-  Linux's directory layout.
+  Linuxs directory layout.
 
 - Improved the test suite and added tests for most of the new functionality.
-  It's now also possible to specify a subset of tests to run.
+  Its now also possible to specify a subset of tests to run.
 
 - Standard error output from the compiler is now only stored in the cache if
-  it's non-empty.
+  its non-empty.
 
 - If the compiler produces no object file or an empty object file, but gives a
   zero exit status (could be due to a file system problem, a buggy program
@@ -1302,7 +1377,7 @@ New features and enhancements
 
 - Added `installcheck` and `distcheck` make targets.
 
-- Clarified cache size limit options' and cleanup semantics.
+- Clarified cache size limit options and cleanup semantics.
 
 - Improved display of cache max size values.
 
@@ -1331,7 +1406,7 @@ Bug fixes
   `-save-temps`. Also bail out on `@file` style options.
 
 - Errors when using multiple `-arch` compiler options are now noted as
-  ``unsupported compiler option''.
+  “unsupported compiler option”.
 
 - `-MD`/`-MMD` options without `-MT`/`-MF` are now handled correctly.
 
index 1e4bf2aaf65114251f1d4e60cf796640472b54cb..94d41b4ed642bf724d3eb4d399b30edb9df48636 100644 (file)
@@ -735,7 +735,7 @@ asciidoc.install(2);
 <body class="article">\r
 <div id="header">\r
 <h1>ccache news</h1>\r
-<span id="revnumber">version 3.6</span>\r
+<span id="revnumber">version 3.7</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>
@@ -743,15 +743,167 @@ asciidoc.install(2);
 </div>\r
 <div id="content">\r
 <div class="sect1">\r
+<h2 id="_ccache_3_7">ccache 3.7</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>Release date: 2019-04-23</p></div>\r
+<div class="sect2">\r
+<h3 id="_changes">Changes</h3>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+Fixed crash when the debug mode is enabled and the output file is in a\r
+  non-writable directory, e.g. when the output file is <code>/dev/null</code>.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Fixed an issue when printing very large log messages to the debug log.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Fixed bugs related to support for <code>-gsplit-dwarf</code>. Previously ccache could\r
+  produce an incorrect link to the <code>.dwo</code> file in the <code>.o</code> file.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Compilations with /dev/null as the input file are now cached.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+ccache has learned how to contruct the object filename if no <code>-o</code> option is\r
+  given and the source filename does not include a <code>.</code> or ends with a <code>.</code>.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Fixed a temporary file leak when the depend mode is enabled and the compiler\r
+  produces standard error output.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Fixed a bug in the depend mode where a manifest hash only could be associated\r
+  with one set of header dependencies.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Manifest files did not get marked as used on direct cache hits, so the LRU\r
+  cache cleanup would incorrectly remove them eventually. This has been fixed.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+The rewriting of absolute paths into relative paths in the dependency file\r
+  has been enabled in the depend mode as well.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+ccache now ignores unknown keys in configuration files for forward\r
+  compatibility.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Rearranged command-line options into sections in the help text.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Documented the previously undocumented <code>--dump-manifest</code> and <code>--hash-file</code>\r
+  options (only useful for debugging ccache itself).\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Added missing documentation for the command-line option <code>-k/--get-config</code>\r
+  added in ccache 3.5.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Renamed the <code>--print-config</code> command to <code>--show-config</code>.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Added a new <code>--print-stats</code> command that prints statistics counters in\r
+  machine-parsable (tab-separated) format.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+ccache no longer creates a missing output directory, thus mimicking the\r
+  compiler behavior for <code>-o out/obj.o</code> when “out” doesn’t exist.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<code>-fdebug-prefix-map=ARG</code>, <code>-ffile-prefix-map=ARG</code> and\r
+  <code>-fmacro-prefix-map=ARG</code> are now included in the hash, but only the part\r
+  before “ARG”. This fixes a bug where compiler feature detection of said flags\r
+  would not work correctly with ccache.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Bail out on too hard compiler option <code>-gtoggle</code>.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Bail out on too hard Clang options <code>--analyze</code> and <code>-analyze</code>.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Improved debug logging of file hashes in depend mode.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Improved handling of various <code>-g*</code> options. In particular, ccache now\r
+  understands that <code>-g0</code> cancels out previous <code>-g* options</code>.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Worked around a problem with Automake related to <code>.d</code> files when using the\r
+  hard link mode.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Added opt-in (at configure time) support for enabling trace logs for\r
+  profiling ccache itself. See <code>doc/DEVELOPER.md</code> in the code tree for more\r
+  information\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Removed support for Fortran 77 again. Some Fortran support was added in\r
+  ccache 3.3, but the implementation did not work when Fortran modules are\r
+  involved.\r
+</p>\r
+</li>\r
+</ul></div>\r
+</div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
 <h2 id="_ccache_3_6">ccache 3.6</h2>\r
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2019-01-14</p></div>\r
 <div class="sect2">\r
-<h3 id="_changes">Changes</h3>\r
+<h3 id="_changes_2">Changes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
-ccache now has an opt-in &#8220;depend mode&#8221;. When enabled, ccache never executes\r
+ccache now has an opt-in “depend mode”. When enabled, ccache never executes\r
   the preprocessor, which results in much lower cache miss overhead at the\r
   expense of a lower potential cache hit rate. The depend mode is only possible\r
   to use when the compiler option <code>-MD</code> or <code>-MMD</code> is used.\r
@@ -759,7 +911,7 @@ ccache now has an opt-in &#8220;depend mode&#8221;. When enabled, ccache never e
 </li>\r
 <li>\r
 <p>\r
-Added support for GCC&#8217;s <code>-ffile-prefix-map</code> option. The <code>-fmacro-prefix-map</code>\r
+Added support for GCCs <code>-ffile-prefix-map</code> option. The <code>-fmacro-prefix-map</code>\r
   option is now also skipped from the hash.\r
 </p>\r
 </li>\r
@@ -798,7 +950,7 @@ ccache now handles several levels of nonexistent directories when rewriting
 A new sloppiness setting <code>clang_index_store</code> makes ccache skip the Clang\r
   compiler option <code>-index-store-path</code> and its argument when computing the\r
   manifest hash. This is useful if you use Xcode, which uses an index store\r
-  path derived from the local project path. Note that the index store won&#8217;t be\r
+  path derived from the local project path. Note that the index store wont be\r
   updated correctly on cache hits if you enable this option.\r
 </p>\r
 </li>\r
@@ -818,7 +970,7 @@ The GCC variables “DEPENDENCIES_OUTPUT” and “SUNPRO_DEPENDENCIES” are no
 <li>\r
 <p>\r
 The algorithm that scans for <code>__DATE_</code> and <code>__TIME__</code> tokens in the hashed\r
-  source code now doesn&#8217;t produce false positives for tokens where <code>__DATE__</code>\r
+  source code now doesnt produce false positives for tokens where <code>__DATE__</code>\r
   or <code>__TIME__</code> is a substring.\r
 </p>\r
 </li>\r
@@ -831,7 +983,7 @@ The algorithm that scans for <code>__DATE_</code> and <code>__TIME__</code> toke
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2019-01-02</p></div>\r
 <div class="sect2">\r
-<h3 id="_changes_2">Changes</h3>\r
+<h3 id="_changes_3">Changes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
@@ -862,14 +1014,14 @@ Improved development mode build flags.
 <div class="sectionbody">\r
 <div class="paragraph"><p>Release date: 2018-10-15</p></div>\r
 <div class="sect2">\r
-<h3 id="_changes_3">Changes</h3>\r
+<h3 id="_changes_4">Changes</h3>\r
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
 Added a boolean <code>debug</code> (<code>CCACHE_DEBUG</code>) configuration option. When enabled,\r
   ccache will create per-object debug files that are helpful e.g. when\r
-  debugging unexpected cache misses. See also the new &#8220;Cache debugging&#8221;\r
-  section in the manual.\r
+  debugging unexpected cache misses. See also the new “Cache debugging” section\r
+  in the manual.\r
 </p>\r
 </li>\r
 <li>\r
@@ -900,15 +1052,15 @@ Improved performance substantially when using <code>hash_dir = false</code> on p
 </li>\r
 <li>\r
 <p>\r
-Added &#8220;stats updated&#8221; timestamp in <code>ccache -s</code> output. This can be useful\r
-  if you wonder whether ccache actually was used for your last build.\r
+Added “stats updated” timestamp in <code>ccache -s</code> output. This can be useful if\r
+  you wonder whether ccache actually was used for your last build.\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Renamed &#8220;stats zero time&#8221; to &#8220;stats zeroed&#8221; and documented it. The\r
-  counter is also now only present in <code>ccache -s</code> output when <code>ccache -z</code>\r
-  actually has been called.\r
+Renamed “stats zero time” to “stats zeroed” and documented it. The counter is\r
+  also now only present in <code>ccache -s</code> output when <code>ccache -z</code> actually has\r
+  been called.\r
 </p>\r
 </li>\r
 <li>\r
@@ -919,14 +1071,14 @@ The content of the <code>-fsanitize-blacklist</code> file is now included in the
 </li>\r
 <li>\r
 <p>\r
-It&#8217;s now possible to opt out of building and installing man pages when\r
+Its now possible to opt out of building and installing man pages when\r
   running <code>make install</code> in the source repository.\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-If the compiler type can&#8217;t be detected (e.g. if it is named <code>cc</code>), use safer\r
-  defaults that won&#8217;t trip up Clang.\r
+If the compiler type cant be detected (e.g. if it is named <code>cc</code>), use safer\r
+  defaults that wont trip up Clang.\r
 </p>\r
 </li>\r
 <li>\r
@@ -1004,7 +1156,7 @@ The cleanup algorithm has been fixed to not misbehave when files are removed
 </li>\r
 <li>\r
 <p>\r
-Correctly hash preprocessed headers located in a &#8220;.gch directory&#8221;.\r
+Correctly hash preprocessed headers located in a “.gch directory”.\r
   Previously, ccache would not pick up changes to such precompiled headers,\r
   risking false positive cache hits.\r
 </p>\r
@@ -1017,7 +1169,7 @@ Fixed build failure when using the bundled zlib sources.
 <li>\r
 <p>\r
 ccache 3.3.5 added a workaround for not triggering Clang errors when a\r
-  precompiled header&#8217;s dependency has an updated timestamp (but identical\r
+  precompiled headers dependency has an updated timestamp (but identical\r
   content). That workaround is now only applied when the compiler is Clang.\r
 </p>\r
 </li>\r
@@ -1066,7 +1218,7 @@ Added support for caching <code>.su</code> files generated by GCC flag <code>-fs
 </li>\r
 <li>\r
 <p>\r
-ccache should now work with distcc&#8217;s &#8220;pump&#8221; wrapper.\r
+ccache should now work with distcc’s “pump” wrapper.\r
 </p>\r
 </li>\r
 <li>\r
@@ -1084,7 +1236,7 @@ Added support for NVCC compiler options <code>--compiler-bindir/-ccbin</code>,
 <p>\r
 Boolean environment variable settings no longer accept the following\r
   (case-insensitive) values: <code>0</code>, <code>false</code>, <code>disable</code> and <code>no</code>. All other values\r
-  are accepted and taken to mean &#8220;true&#8221;. This is to stop users from setting\r
+  are accepted and taken to mean “true”. This is to stop users from setting\r
   e.g. <code>CCACHE_DISABLE=0</code> and then expect the cache to be used.\r
 </p>\r
 </li>\r
@@ -1099,7 +1251,7 @@ Improved support for <code>run_second_cpp = false</code>: If combined with passi
 <p>\r
 An implicit <code>-MQ</code> is now passed to the preprocessor only if the object file\r
   extension is non-standard. This should make it easier to use EDG-based\r
-  compilers (e.g. GHS) which don&#8217;t understand <code>-MQ</code>.\r
+  compilers (e.g. GHS) which dont understand <code>-MQ</code>.\r
 </p>\r
 </li>\r
 <li>\r
@@ -1190,7 +1342,7 @@ Documented how automatic cache cleanup works.
 <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
+  This reverts the “Improved parsing of <code>-g*</code> options” feature in ccache 3.3.\r
 </p>\r
 </li>\r
 <li>\r
@@ -1226,9 +1378,9 @@ Fixed a bug related to erroneously storing a dependency file with absolute
 <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
+  limits. Previously, the forced cleanup took “limit_multiple” into account, so\r
+  that <code>ccache -c/--cleanup</code> by default would trim the cache to 80% of the max\r
+  limit.\r
 </p>\r
 </li>\r
 <li>\r
@@ -1275,8 +1427,8 @@ Documented the different cache statistics counters.
 Fixed a regression in ccache 3.3 related to potentially bad content of\r
   dependency files when compiling identical source code but with different\r
   source paths. This was only partially fixed in 3.3.2 and reverts the new\r
-  &#8220;Names of included files are no longer included in the hash of the\r
-  compiler&#8217;s preprocessed output&#8221; feature in 3.3.\r
+  “Names of included files are no longer included in the hash of the compiler’s\r
+  preprocessed output” feature in 3.3.\r
 </p>\r
 </li>\r
 <li>\r
@@ -1344,9 +1496,9 @@ Fixed a regression in ccache 3.3.1: ccache could get confused when using the
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
-Fixed a problem in the &#8220;multiple <code>-arch</code> options&#8221; support introduced in\r
-  3.3. When using the direct mode (the default), different combinations of\r
-  <code>-arch</code> options were not detected properly.\r
+Fixed a problem in the “multiple <code>-arch</code> options” support introduced in 3.3.\r
+  When using the direct mode (the default), different combinations of <code>-arch</code>\r
+  options were not detected properly.\r
 </p>\r
 </li>\r
 <li>\r
@@ -1380,8 +1532,8 @@ A C99-compatible compiler is now required to build ccache.
 <li>\r
 <p>\r
 The configuration option <code>run_second_cpp</code> (<code>CCACHE_CPP2</code>) now defaults to\r
-  true. This improves ccache&#8217;s out-of-the-box experience for compilers that\r
-  can&#8217;t compile their own preprocessed output with the same outcome as if they\r
+  true. This improves ccaches out-of-the-box experience for compilers that\r
+  cant compile their own preprocessed output with the same outcome as if they\r
   compiled the real source code directly, e.g. newer versions of GCC and Clang.\r
 </p>\r
 </li>\r
@@ -1426,7 +1578,7 @@ Added a new sloppiness option <code>no_system_headers</code>, which tells ccache
 <p>\r
 Added a new statistics counter that tracks the number of performed cleanups\r
   due to the cache size being over the limit. The value is shown in the output\r
-  of &#8220;ccache -s&#8221;.\r
+  of “ccache -s”.\r
 </p>\r
 </li>\r
 <li>\r
@@ -1438,13 +1590,13 @@ Added support for relocating debug info directory using <code>-fdebug-prefix-map
 </li>\r
 <li>\r
 <p>\r
-Added a new &#8220;cache hit rate&#8221; field to the output of &#8220;ccache -s&#8221;.\r
+Added a new “cache hit rate” field to the output of “ccache -s”.\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Added support for caching compilation of assembler code produced by e.g.\r
-  &#8220;gcc -S file.c&#8221;.\r
+Added support for caching compilation of assembler code produced by e.g. “gcc\r
+  -S file.c”.\r
 </p>\r
 </li>\r
 <li>\r
@@ -1508,7 +1660,7 @@ ccache now understands the undocumented <code>-coverage</code> (only one dash) G
 </li>\r
 <li>\r
 <p>\r
-Names of included files are no longer included in the hash of the compiler&#8217;s\r
+Names of included files are no longer included in the hash of the compilers\r
   preprocessed output. This leads to more potential cache hits when not using\r
   the direct mode.\r
 </p>\r
@@ -1600,7 +1752,7 @@ Fixed a bug which could lead to false cache hits for compiler command lines
 </li>\r
 <li>\r
 <p>\r
-ccache now knows how to work around a glitch in the output of GCC 6&#8217;s\r
+ccache now knows how to work around a glitch in the output of GCC 6s\r
   preprocessor.\r
 </p>\r
 </li>\r
@@ -1617,13 +1769,13 @@ ccache now knows how to work around a glitch in the output of GCC 6&#8217;s
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
-Fixed build problem on QNX, which lacks &#8220;SA_RESTART&#8221;.\r
+Fixed build problem on QNX, which lacks “SA_RESTART”.\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
 Bail out on compiler option <code>-fstack-usage</code> since it creates a <code>.su</code> file\r
-  which ccache currently doesn&#8217;t handle.\r
+  which ccache currently doesnt handle.\r
 </p>\r
 </li>\r
 <li>\r
@@ -1656,7 +1808,7 @@ Improved handling of stale NFS handles.
 </li>\r
 <li>\r
 <p>\r
-Made it harder to misinterpret documentation of boolean environment settings'\r
+Made it harder to misinterpret documentation of boolean environment settings\r
   semantics.\r
 </p>\r
 </li>\r
@@ -1688,14 +1840,14 @@ Fixed failure to create directories on QNX.
 </li>\r
 <li>\r
 <p>\r
-Don&#8217;t (try to) update manifest file in &#8220;read-only&#8221; and &#8220;read-only direct&#8221;\r
+Don’t (try to) update manifest file in “read-only” and “read-only direct”\r
   modes.\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Fixed a bug in caching of <code>stat</code> system calls in &#8220;file_stat_matches\r
-  sloppiness mode&#8221;.\r
+Fixed a bug in caching of <code>stat</code> system calls in file_stat_matches\r
+  sloppiness mode.\r
 </p>\r
 </li>\r
 <li>\r
@@ -1705,12 +1857,12 @@ Fixed bug in hashing of Clang plugins, leading to unnecessary cache misses.
 </li>\r
 <li>\r
 <p>\r
-Fixed --print-config to show &#8220;pch_defines sloppiness&#8221;.\r
+Fixed --print-config to show “pch_defines sloppiness”.\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-The man page is now built when running &#8220;make install&#8221; from Git repository\r
+The man page is now built when running “make install” from Git repository\r
   sources.\r
 </p>\r
 </li>\r
@@ -1820,7 +1972,7 @@ Only log "Disabling direct mode" once when failing to read potential include
 <li>\r
 <p>\r
 Added support for <code>CCACHE_COMPILERCHECK=string:&lt;value&gt;</code>. This is a faster\r
-  alternative to <code>CCACHE_COMPILERCHECK=&lt;command&gt;</code> if the command&#8217;s output can\r
+  alternative to <code>CCACHE_COMPILERCHECK=&lt;command&gt;</code> if the commands output can\r
   be precalculated by the build system.\r
 </p>\r
 </li>\r
@@ -1843,9 +1995,8 @@ Made hash of cached result created with and without <code>CCACHE_CPP2</code> dif
 </li>\r
 <li>\r
 <p>\r
-Don&#8217;t try to reset a nonexistent stats file. This avoids &#8220;No such file or\r
-  directory&#8221; messages in the ccache log when the cache directory doesn&#8217;t\r
-  exist.\r
+Don’t try to reset a nonexistent stats file. This avoids “No such file or\r
+  directory” messages in the ccache log when the cache directory doesn’t exist.\r
 </p>\r
 </li>\r
 <li>\r
@@ -1979,7 +2130,7 @@ Added support for several binaries (separated by space) in <code>CCACHE_PREFIX</
 <li>\r
 <p>\r
 The <code>-c</code> option is no longer passed to the preprocessor. This fixes problems\r
-  with Clang and Solaris&#8217;s C++ compiler.\r
+  with Clang and Solariss C++ compiler.\r
 </p>\r
 </li>\r
 <li>\r
@@ -1997,7 +2148,7 @@ Compiler options <code>-fprofile-generate</code>, <code>-fprofile-arcs</code>, <
 </li>\r
 <li>\r
 <p>\r
-Added support for Clang&#8217;s <code>--serialize-diagnostic</code> option, storing the\r
+Added support for Clangs <code>--serialize-diagnostic</code> option, storing the\r
   diagnostic file (<code>.dia</code>) in the cache.\r
 </p>\r
 </li>\r
@@ -2027,8 +2178,8 @@ On a cache miss, ccache now instructs the compiler to create the object file
 </li>\r
 <li>\r
 <p>\r
-ccache now checks that included files' ctimes aren&#8217;t too new. This check can\r
-  be turned off by adding <code>include_file_ctime</code> to the &#8220;ccache sloppiness&#8221;\r
+ccache now checks that included files’ ctimes aren’t too new. This check can\r
+  be turned off by adding <code>include_file_ctime</code> to the “ccache sloppiness”\r
   setting.\r
 </p>\r
 </li>\r
@@ -2036,21 +2187,21 @@ ccache now checks that included files' ctimes aren&#8217;t too new. This check c
 <p>\r
 Added possibility to get cache hits based on filename, size, mtime and ctime\r
   only. On other words, source code files are not even read, only stat-ed. This\r
-  operation mode is opt-in by adding <code>file_stat_matches</code> to the &#8220;ccache\r
-  sloppiness&#8221; setting.\r
+  operation mode is opt-in by adding <code>file_stat_matches</code> to the ccache\r
+  sloppiness setting.\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
 The filename part of options like <code>-Wp,-MDfilename</code> is no longer included in\r
-  the hash since the filename doesn&#8217;t have any bearing on the result.\r
+  the hash since the filename doesnt have any bearing on the result.\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Added a &#8220;read-only direct&#8221; configuration setting, which is like the\r
-  ordinary read-only setting except that ccache will only try to retrieve\r
-  results from the cache using the direct mode, not the preprocessor mode.\r
+Added a “read-only direct” configuration setting, which is like the ordinary\r
+  read-only setting except that ccache will only try to retrieve results from\r
+  the cache using the direct mode, not the preprocessor mode.\r
 </p>\r
 </li>\r
 <li>\r
@@ -2078,7 +2229,7 @@ Added support for <code>@file</code> and <code>-@file</code> arguments (reading
 </li>\r
 <li>\r
 <p>\r
-<code>-Wl,</code> options are no longer included in the hash since they don&#8217;t affect\r
+<code>-Wl,</code> options are no longer included in the hash since they dont affect\r
   compilation.\r
 </p>\r
 </li>\r
@@ -2201,9 +2352,8 @@ Made hash of cached result created with and without <code>CCACHE_CPP2</code> dif
 </li>\r
 <li>\r
 <p>\r
-Don&#8217;t try to reset a nonexistent stats file. This avoids &#8220;No such file or\r
-  directory&#8221; messages in the ccache log when the cache directory doesn&#8217;t\r
-  exist.\r
+Don’t try to reset a nonexistent stats file. This avoids “No such file or\r
+  directory” messages in the ccache log when the cache directory doesn’t exist.\r
 </p>\r
 </li>\r
 </ul></div>\r
@@ -2247,14 +2397,14 @@ Compiler option <code>-fdebug-prefix-map</code> is now ignored (not part of the
 <li>\r
 <p>\r
 Added note in documentation that <code>--ccache-skip</code> currently does not mean\r
-  &#8220;don&#8217;t hash the following option&#8221;.\r
+  “don’t hash the following option”.\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
 To enable support for precompiled headers (PCH), <code>CCACHE_SLOPPINESS</code> now also\r
   needs to include the new <code>pch_defines</code> sloppiness. This is because ccache\r
-  can&#8217;t detect changes in the source code when only defined macros have been\r
+  cant detect changes in the source code when only defined macros have been\r
   changed.\r
 </p>\r
 </li>\r
@@ -2271,7 +2421,7 @@ Stale files in the internal temporary directory (<code>&lt;ccache_dir&gt;/tmp</c
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
-Fixed path canonicalization in <code>make_relative_path()</code> when path doesn&#8217;t\r
+Fixed path canonicalization in <code>make_relative_path()</code> when path doesnt\r
   exist.\r
 </p>\r
 </li>\r
@@ -2323,7 +2473,7 @@ Subdirectories in the cache are no longer created in read-only mode.
 </li>\r
 <li>\r
 <p>\r
-Fixed so that ccache&#8217;s log file descriptor is not made available to the\r
+Fixed so that ccaches log file descriptor is not made available to the\r
   compiler.\r
 </p>\r
 </li>\r
@@ -2513,12 +2663,12 @@ Rewrite argument to <code>--sysroot</code> if <code>CCACHE_BASEDIR</code> is use
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
-Don&#8217;t crash if <code>getcwd()</code> fails.\r
+Dont crash if <code>getcwd()</code> fails.\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-Fixed alignment of &#8220;called for preprocessing&#8221; counter.\r
+Fixed alignment of “called for preprocessing” counter.\r
 </p>\r
 </li>\r
 </ul></div>\r
@@ -2534,7 +2684,7 @@ Fixed alignment of &#8220;called for preprocessing&#8221; counter.
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
-Added a new statistics counter named &#8220;called for preprocessing&#8221;.\r
+Added a new statistics counter named “called for preprocessing”.\r
 </p>\r
 </li>\r
 <li>\r
@@ -2583,7 +2733,7 @@ Fixed a minor memory leak.
 </li>\r
 <li>\r
 <p>\r
-Systems that lack (and don&#8217;t need to be linked with) libm are now supported.\r
+Systems that lack (and dont need to be linked with) libm are now supported.\r
 </p>\r
 </li>\r
 </ul></div>\r
@@ -2604,13 +2754,13 @@ Made a work-around for a bug in <code>gzputc()</code> in zlib 1.2.5.
 </li>\r
 <li>\r
 <p>\r
-Corrupt manifest files are now removed so that they won&#8217;t block direct mode\r
+Corrupt manifest files are now removed so that they wont block direct mode\r
   hits.\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
-ccache now copes with file systems that don&#8217;t know about symbolic links.\r
+ccache now copes with file systems that dont know about symbolic links.\r
 </p>\r
 </li>\r
 <li>\r
@@ -2685,7 +2835,7 @@ Improved documentation on which information is included in the hash sum.
 </li>\r
 <li>\r
 <p>\r
-Made the &#8220;too new header file&#8221; test case work on file systems with\r
+Made the “too new header file” test case work on file systems with\r
   unsynchronized clocks.\r
 </p>\r
 </li>\r
@@ -2735,7 +2885,7 @@ Fixed configure detection of ar.
 <li>\r
 <p>\r
 ccache development version (set by dev.mk) now works with gits whose\r
-  <code>describe</code> command doesn&#8217;t understand <code>--dirty</code>.\r
+  <code>describe</code> command doesnt understand <code>--dirty</code>.\r
 </p>\r
 </li>\r
 </ul></div>\r
@@ -2764,7 +2914,7 @@ Minor debug log message improvements.
 Added support for hashing the output of a custom command (e.g. <code>%compiler%\r
   --version</code>) to identify the compiler instead of stat-ing or hashing the\r
   compiler binary. This can improve robustness when the compiler (as seen by\r
-  ccache) actually isn&#8217;t the real compiler but another compiler wrapper.\r
+  ccache) actually isnt the real compiler but another compiler wrapper.\r
 </p>\r
 </li>\r
 <li>\r
@@ -2801,9 +2951,9 @@ Reading and writing of statistics counters has been made forward-compatible
 </li>\r
 <li>\r
 <p>\r
-Files are now read without using <code>mmap()</code>. This has two benefits: it&#8217;s more\r
+Files are now read without using <code>mmap()</code>. This has two benefits: its more\r
   robust against file changes during reading and it improves performance on\r
-  poor systems where <code>mmap()</code> doesn&#8217;t use the disk cache.\r
+  poor systems where <code>mmap()</code> doesnt use the disk cache.\r
 </p>\r
 </li>\r
 <li>\r
@@ -2915,7 +3065,7 @@ New <code>HACKING.txt</code> file with some notes about ccache code conventions.
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
-The statistics counter &#8220;called for link&#8221; is now correctly updated when\r
+The statistics counter “called for link” is now correctly updated when\r
   linking with a single object file.\r
 </p>\r
 </li>\r
@@ -2948,7 +3098,7 @@ ccache is now licensed under the GNU General Public License (GPL) version 3
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
-The way the hashes are calculated has changed, so you won&#8217;t get cache hits\r
+The way the hashes are calculated has changed, so you wont get cache hits\r
   for compilation results stored by older ccache versions. Because of this, you\r
   might as well clear the old cache directory with <code>ccache --clear</code> if you\r
   want, unless you plan to keep using an older ccache version.\r
@@ -2961,7 +3111,7 @@ The way the hashes are calculated has changed, so you won&#8217;t get cache hits
 <div class="ulist"><ul>\r
 <li>\r
 <p>\r
-ccache now has a &#8220;direct mode&#8221; where it computes a hash of the source code\r
+ccache now has a “direct mode” where it computes a hash of the source code\r
   (including all included files) and compiler options without running the\r
   preprocessor. By not running the preprocessor, CPU usage is reduced; the\r
   speed is somewhere between 1 and 5 times that of ccache running in\r
@@ -2985,15 +3135,15 @@ Support has been added for rewriting absolute paths to relative paths when
 Object files are now optionally stored compressed in the cache. The runtime\r
   cost is negligible, and more files will fit in the ccache directory and in\r
   the disk cache. Set <code>CCACHE_COMPRESS</code> to enable object file compression. Note\r
-  that you can&#8217;t use compression in combination with the hard link feature.\r
+  that you cant use compression in combination with the hard link feature.\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
 A <code>CCACHE_COMPILERCHECK</code> option has been added. This option tells ccache what\r
   compiler-identifying information to hash to ensure that results retrieved\r
-  from the cache are accurate. Possible values are: none (don&#8217;t hash anything),\r
-  mtime (hash the compiler&#8217;s mtime and size) and content (hash the content of\r
+  from the cache are accurate. Possible values are: none (dont hash anything),\r
+  mtime (hash the compilers mtime and size) and content (hash the content of\r
   the compiler binary). The default is mtime.\r
 </p>\r
 </li>\r
@@ -3006,7 +3156,7 @@ It is now possible to specify extra files whose contents should be included
 <li>\r
 <p>\r
 Added support for Objective-C and Objective-C++. The statistics counter\r
-  &#8220;not a C/C++ file&#8221; has been renamed to &#8220;unsupported source language&#8221;.\r
+  “not a C/C++ file” has been renamed to “unsupported source language”.\r
 </p>\r
 </li>\r
 <li>\r
@@ -3053,19 +3203,19 @@ The default value of <code>CCACHE_TEMPDIR</code> has been changed to <code>$CCAC
 <p>\r
 Temporary files that later will be moved into the cache are now created in\r
   the cache directory they will end up in. This makes ccache more friendly to\r
-  Linux&#8217;s directory layout.\r
+  Linuxs directory layout.\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
 Improved the test suite and added tests for most of the new functionality.\r
-  It&#8217;s now also possible to specify a subset of tests to run.\r
+  Its now also possible to specify a subset of tests to run.\r
 </p>\r
 </li>\r
 <li>\r
 <p>\r
 Standard error output from the compiler is now only stored in the cache if\r
-  it&#8217;s non-empty.\r
+  its non-empty.\r
 </p>\r
 </li>\r
 <li>\r
@@ -3082,7 +3232,7 @@ Added <code>installcheck</code> and <code>distcheck</code> make targets.
 </li>\r
 <li>\r
 <p>\r
-Clarified cache size limit options' and cleanup semantics.\r
+Clarified cache size limit options and cleanup semantics.\r
 </p>\r
 </li>\r
 <li>\r
@@ -3139,7 +3289,7 @@ Bail out on too hard compiler options <code>--coverage</code>, <code>-fprofile-a
 <li>\r
 <p>\r
 Errors when using multiple <code>-arch</code> compiler options are now noted as\r
-  &#8220;unsupported compiler option&#8221;.\r
+  “unsupported compiler option”.\r
 </p>\r
 </li>\r
 <li>\r
@@ -3245,9 +3395,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.6<br />\r
+Version 3.7<br />\r
 Last updated\r
- 2019-01-14 21:08:50 CET\r
+ 2019-04-23 21:35:11 CEST\r
 </div>\r
 </div>\r
 </body>\r
index 8ab6adcd99b23546b35d12fa30712deb19c694f0..c2b56cd54766d633960d095a879ef0961a645df9 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: ccache
 .\"    Author: [see the "Author" section]
 .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
-.\"      Date: 01/14/2019
+.\"      Date: 04/23/2019
 .\"    Manual: ccache Manual
-.\"    Source: ccache 3.6
+.\"    Source: ccache 3.7
 .\"  Language: English
 .\"
-.TH "CCACHE" "1" "01/14/2019" "ccache 3\&.6" "ccache Manual"
+.TH "CCACHE" "1" "04/23/2019" "ccache 3\&.7" "ccache Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -211,9 +211,23 @@ Clean up the cache by removing old cached files until the specified file number
 Clear the entire cache, removing all cached files, but keeping the configuration file\&.
 .RE
 .PP
-\fB\fB\-F, \-\-max\-files\fR\fR=\fIN\fR
+\fB\fB\-\-dump\-manifest\fR\fR=\fIPATH\fR
 .RS 4
-Set the maximum number of files allowed in the cache\&. Use 0 for no limit\&. The value is stored in a configuration file in the cache directory and applies to all future compilations\&.
+Dump manifest file at PATH in text format\&. This is only useful when debugging ccache and its behavior\&.
+.RE
+.PP
+\fB\fB\-k, \-\-get\-config\fR\fR=\fIKEY\fR
+.RS 4
+Print the value of configuration option
+\fIKEY\fR\&. See
+CONFIGURATION
+for more information\&.
+.RE
+.PP
+\fB\fB\-\-hash\-file\fR\fR=\fIPATH\fR
+.RS 4
+Print the hash (in format
+\fB<MD4>\-<size>\fR) of the file at PATH\&. This is only useful when debugging ccache and its behavior\&.
 .RE
 .PP
 \fB\fB\-h, \-\-help\fR\fR
@@ -221,6 +235,11 @@ Set the maximum number of files allowed in the cache\&. Use 0 for no limit\&. Th
 Print an options summary page\&.
 .RE
 .PP
+\fB\fB\-F, \-\-max\-files\fR\fR=\fIN\fR
+.RS 4
+Set the maximum number of files allowed in the cache\&. Use 0 for no limit\&. The value is stored in a configuration file in the cache directory and applies to all future compilations\&.
+.RE
+.PP
 \fB\fB\-M, \-\-max\-size\fR\fR=\fISIZE\fR
 .RS 4
 Set the maximum size of the files stored in the cache\&.
@@ -228,9 +247,14 @@ Set the maximum size of the files stored in the cache\&.
 should be a number followed by an optional suffix: k, M, G, T (decimal), Ki, Mi, Gi or Ti (binary)\&. The default suffix is G\&. Use 0 for no limit\&. The value is stored in a configuration file in the cache directory and applies to all future compilations\&.
 .RE
 .PP
+\fB\fB\-\-print\-stats\fR\fR
+.RS 4
+Print statistics counter IDs and corresponding values machine\-parsable (tab\-separated) format\&.
+.RE
+.PP
 \fB\fB\-o, \-\-set\-config\fR\fR=\fIKEY=VALUE\fR
 .RS 4
-Set configuration
+Set configuration option
 \fIKEY\fR
 to
 \fIVALUE\fR\&. See
@@ -238,14 +262,14 @@ CONFIGURATION
 for more information\&.
 .RE
 .PP
-\fB\fB\-p, \-\-print\-config\fR\fR
+\fB\fB\-p, \-\-show\-config\fR\fR
 .RS 4
-Print current configuration options and from where they originate (environment variable, configuration file or compile\-time default)\&.
+Print current configuration options and from where they originate (environment variable, configuration file or compile\-time default) in human\-readable format\&.
 .RE
 .PP
 \fB\fB\-s, \-\-show\-stats\fR\fR
 .RS 4
-Print the current statistics summary for the cache\&.
+Print a summary of configuration and statistics counters in human\-readable format\&.
 .RE
 .PP
 \fB\fB\-V, \-\-version\fR\fR
@@ -1984,7 +2008,7 @@ is set as mentioned above\&. If you want to share cache hits, you can pass
 .SH "TROUBLESHOOTING"
 .SS "General"
 .sp
-A general tip for getting information about what ccache is doing is to enable debug logging by setting \fBlog_file\fR\&. The log contains executed commands, important decisions that ccache makes, read and written files, etc\&. Another way of keeping track of what is happening is to check the output of \fBccache \-s\fR\&.
+A general tip for getting information about what ccache is doing is to enable debug logging by setting the configuration option \fBdebug\fR (or the environment variable \fBCCACHE_DEBUG\fR); see debugging for more information\&. Another way of keeping track of what is happening is to check the output of \fBccache \-s\fR\&.
 .SS "Performance"
 .sp
 ccache has been written to perform well out of the box, but sometimes you may have to do some adjustments of how you use the compiler and ccache in order to improve performance\&.
@@ -2249,7 +2273,7 @@ An alternative is to clear the whole cache with \fBccache \-C\fR if you don\(cqt
 There are no reported issues about ccache producing broken object files reproducibly\&. That doesn\(cqt mean it can\(cqt happen, so if you find a repeatable case, please report it\&.
 .SH "MORE INFORMATION"
 .sp
-Credits, mailing list information, bug reporting instructions, source code, etc, can be found on ccache\(cqs web site: https://ccache\&.samba\&.org\&.
+Credits, mailing list information, bug reporting instructions, source code, etc, can be found on ccache\(cqs web site: https://ccache\&.dev\&.
 .SH "AUTHOR"
 .sp
-ccache was originally written by Andrew Tridgell and is currently developed and maintained by Joel Rosdahl\&. See AUTHORS\&.txt or AUTHORS\&.html and https://ccache\&.samba\&.org/credits\&.html for a list of contributors\&.
+ccache was originally written by Andrew Tridgell and is currently developed and maintained by Joel Rosdahl\&. See AUTHORS\&.txt or AUTHORS\&.html and https://ccache\&.dev/credits\&.html for a list of contributors\&.
index b4cdb865f81fc62f247a01d838af9b8ddcd30e39..ca5249523fd3d3be997fea0acda9d607bd5fc92b 100644 (file)
@@ -60,25 +60,34 @@ static const char USAGE_TEXT[] =
        "    " MYNAME " compiler [compiler options]\n"
        "    compiler [compiler options]          (via symbolic link)\n"
        "\n"
-       "Options:\n"
-       "    -c, --cleanup         delete old files and recalculate size counters\n"
-       "                          (normally not needed as this is done automatically)\n"
-       "    -C, --clear           clear the cache completely (except configuration)\n"
-       "    -F, --max-files=N     set maximum number of files in cache to N (use 0 for\n"
-       "                          no limit)\n"
-       "    -k, --get-config=K    get the value of the configuration key K\n"
-       "    -M, --max-size=SIZE   set maximum size of cache to SIZE (use 0 for no\n"
-       "                          limit); available suffixes: k, M, G, T (decimal) and\n"
-       "                          Ki, Mi, Gi, Ti (binary); default suffix: G\n"
-       "    -o, --set-config=K=V  set configuration key K to value V\n"
-       "    -p, --print-config    print current configuration options\n"
-       "    -s, --show-stats      show statistics summary\n"
-       "    -z, --zero-stats      zero statistics counters\n"
+       "Common options:\n"
+       "    -c, --cleanup             delete old files and recalculate size counters\n"
+       "                              (normally not needed as this is done\n"
+       "                              automatically)\n"
+       "    -C, --clear               clear the cache completely (except configuration)\n"
+       "    -F, --max-files=N         set maximum number of files in cache to N (use 0\n"
+       "                              for no limit)\n"
+       "    -M, --max-size=SIZE       set maximum size of cache to SIZE (use 0 for no\n"
+       "                              limit); available suffixes: k, M, G, T (decimal)\n"
+       "                              and Ki, Mi, Gi, Ti (binary); default suffix: G\n"
+       "    -p, --show-config         show current configuration options in\n"
+       "                              human-readable format\n"
+       "    -s, --show-stats          show summary of configuration and statistics\n"
+       "                              counters in human-readable format\n"
+       "    -z, --zero-stats          zero statistics counters\n"
        "\n"
-       "    -h, --help            print this help text\n"
-       "    -V, --version         print version and copyright information\n"
+       "    -h, --help                print this help text\n"
+       "    -V, --version             print version and copyright information\n"
        "\n"
-       "See also <https://ccache.samba.org>.\n";
+       "Options for scripting or debugging:\n"
+       "        --dump-manifest=PATH  dump manifest file at PATH in text format\n"
+       "    -k, --get-config=K        print the value of configuration key K\n"
+       "        --hash-file=PATH      print the hash (<MD4>-<size>) of the file at PATH\n"
+       "        --print-stats         print statistics counter IDs and corresponding\n"
+       "                              values in machine-parsable format\n"
+       "    -o, --set-config=K=V      set configuration item K to value V\n"
+       "\n"
+       "See also <https://ccache.dev>.\n";
 
 // Global configuration data.
 struct conf *conf = NULL;
@@ -182,6 +191,9 @@ static size_t ignore_headers_len;
 // Is the compiler being asked to output debug info?
 static bool generating_debuginfo;
 
+// Is the compiler being asked to output debug info on level 3?
+static bool generating_debuginfo_level_3;
+
 // Is the compiler being asked to output dependencies?
 static bool generating_dependencies;
 
@@ -500,14 +512,14 @@ fclose_exitfn(void *context)
 }
 
 static void
-dump_log_buffer_exitfn(void *context)
+dump_debug_log_buffer_exitfn(void *context)
 {
        if (!conf->debug) {
                return;
        }
 
        char *path = format("%s.ccache-log", (const char *)context);
-       cc_dump_log_buffer(path);
+       cc_dump_debug_log_buffer(path);
        free(path);
 }
 
@@ -521,9 +533,13 @@ init_hash_debug(struct hash *hash, const char *obj_path, char type,
 
        char *path = format("%s.ccache-input-%c", obj_path, type);
        FILE *debug_binary_file = fopen(path, "wb");
-       hash_enable_debug(hash, section_name, debug_binary_file, debug_text_file);
+       if (debug_binary_file) {
+               hash_enable_debug(hash, section_name, debug_binary_file, debug_text_file);
+               exitfn_add(fclose_exitfn, debug_binary_file);
+       } else {
+               cc_log("Failed to open %s: %s", path, strerror(errno));
+       }
        free(path);
-       exitfn_add(fclose_exitfn, debug_binary_file);
 }
 
 static enum guessed_compiler
@@ -729,7 +745,9 @@ remember_include_file(char *path, struct hash *cpp_hash, bool system,
 
                if (depend_mode_hash) {
                        hash_delimiter(depend_mode_hash, "include");
-                       hash_buffer(depend_mode_hash, h->hash, sizeof(h->hash));
+                       char *result = format_hash_as_string(h->hash, h->size);
+                       hash_string(depend_mode_hash, result);
+                       free(result);
                }
        }
 
@@ -1131,7 +1149,11 @@ object_hash_from_depfile(const char *depfile, struct hash *hash)
                        if (str_endswith(token, ":") || str_eq(token, "\\")) {
                                continue;
                        }
-                       remember_include_file(x_strdup(token), hash, false, hash);
+                       if (!has_absolute_include_headers) {
+                               has_absolute_include_headers = is_absolute_path(token);
+                       }
+                       char *path = make_relative_path(x_strdup(token));
+                       remember_include_file(path, hash, false, hash);
                }
        }
 
@@ -1148,7 +1170,7 @@ object_hash_from_depfile(const char *depfile, struct hash *hash)
        return result;
 }
 
-// Helper method for copy_file_to_cache and move_file_to_cache_same_fs.
+// Helper function for copy_file_to_cache and move_file_to_cache_same_fs.
 static void
 do_copy_or_move_file_to_cache(const char *source, const char *dest, bool copy)
 {
@@ -1228,12 +1250,12 @@ move_file_to_cache_same_fs(const char *source, const char *dest)
        do_copy_or_move_file_to_cache(source, dest, false);
 }
 
-// Copy or link a file from the cache.
+// Helper function for get_file_from_cache and copy_file_from_cache.
 static void
-get_file_from_cache(const char *source, const char *dest)
+do_copy_or_link_file_from_cache(const char *source, const char *dest, bool copy)
 {
        int ret;
-       bool do_link = conf->hard_link && !file_is_compressed(source);
+       bool do_link = !copy && conf->hard_link && !file_is_compressed(source);
        if (do_link) {
                x_unlink(dest);
                ret = link(source, dest);
@@ -1270,6 +1292,27 @@ get_file_from_cache(const char *source, const char *dest)
        cc_log("Created from cache: %s -> %s", source, dest);
 }
 
+// Copy or link a file from the cache.
+//
+// source must be a path in the cache (see get_path_in_cache). dest does not
+// have to be on the same file system as source.
+//
+// An attempt will be made to hard link source to dest if conf->hard_link is
+// true and conf->compression is false, otherwise copy. dest will be compressed
+// if conf->compression is true.
+static void
+get_file_from_cache(const char *source, const char *dest)
+{
+       do_copy_or_link_file_from_cache(source, dest, false);
+}
+
+// Copy a file from the cache.
+static void
+copy_file_from_cache(const char *source, const char *dest)
+{
+       do_copy_or_link_file_from_cache(source, dest, true);
+}
+
 // Send cached stderr, if any, to stderr.
 static void
 send_cached_stderr(void)
@@ -1297,15 +1340,16 @@ update_manifest_file(void)
        if (stat(manifest_path, &st) == 0) {
                old_size = file_size(&st);
        }
+       MTR_BEGIN("manifest", "manifest_put");
        if (manifest_put(manifest_path, cached_obj_hash, included_files)) {
                cc_log("Added object file hash to %s", manifest_path);
-               update_mtime(manifest_path);
                if (x_stat(manifest_path, &st) == 0) {
                        stats_update_size(file_size(&st) - old_size, old_size == 0 ? 1 : 0);
                }
        } else {
                cc_log("Failed to add object file hash to %s", manifest_path);
        }
+       MTR_END("manifest", "manifest_put");
 }
 
 static void
@@ -1355,6 +1399,7 @@ to_cache(struct args *args, struct hash *depend_mode_hash)
        }
 
        cc_log("Running real compiler");
+       MTR_BEGIN("execute", "compiler");
        char *tmp_stdout;
        int tmp_stdout_fd;
        char *tmp_stderr;
@@ -1387,6 +1432,7 @@ to_cache(struct args *args, struct hash *depend_mode_hash)
                        depend_mode_args->argv, tmp_stdout_fd, tmp_stderr_fd, &compiler_pid);
                args_free(depend_mode_args);
        }
+       MTR_END("execute", "compiler");
 
        struct stat st;
        if (x_stat(tmp_stdout, &st) != 0) {
@@ -1464,10 +1510,6 @@ to_cache(struct args *args, struct hash *depend_mode_hash)
                failed();
        }
 
-       if (generating_dependencies) {
-               use_relative_paths_in_depfile(output_dep);
-       }
-
        if (conf->depend_mode) {
                struct file_hash *object_hash =
                        object_hash_from_depfile(output_dep, depend_mode_hash);
@@ -1475,10 +1517,10 @@ to_cache(struct args *args, struct hash *depend_mode_hash)
                        failed();
                }
                update_cached_result_globals(object_hash);
+       }
 
-               // It does not make sense to update an existing manifest file in the depend
-               // mode.
-               x_unlink(manifest_path);
+       if (generating_dependencies) {
+               use_relative_paths_in_depfile(output_dep);
        }
 
        if (stat(output_obj, &st) != 0) {
@@ -1502,14 +1544,16 @@ to_cache(struct args *args, struct hash *depend_mode_hash)
                } else {
                        copy_file_to_cache(tmp_stderr, cached_stderr);
                }
-       } else {
+       } else if (conf->recache) {
+               // If recaching, we need to remove any previous .stderr.
+               x_unlink(cached_stderr);
+       }
+       if (st.st_size == 0 || conf->depend_mode) {
                tmp_unlink(tmp_stderr);
-               if (conf->recache) {
-                       // If recaching, we need to remove any previous .stderr.
-                       x_unlink(cached_stderr);
-               }
        }
 
+       MTR_BEGIN("file", "file_put");
+
        copy_file_to_cache(output_obj, cached_obj);
        if (generating_dependencies) {
                copy_file_to_cache(output_dep, cached_dep);
@@ -1527,6 +1571,8 @@ to_cache(struct args *args, struct hash *depend_mode_hash)
                copy_file_to_cache(output_dwo, cached_dwo);
        }
 
+       MTR_END("file", "file_put");
+
        stats_update(STATS_TOCACHE);
 
        // Make sure we have a CACHEDIR.TAG in the cache part of cache_dir. This can
@@ -1606,7 +1652,9 @@ get_object_name_from_cpp(struct args *args, struct hash *hash)
                args_add(args, input_file);
                add_prefix(args, conf->prefix_command_cpp);
                cc_log("Running preprocessor");
+               MTR_BEGIN("execute", "preprocessor");
                status = execute(args->argv, path_stdout_fd, path_stderr_fd, &compiler_pid);
+               MTR_END("execute", "preprocessor");
                args_pop(args, args_added);
        }
 
@@ -1833,6 +1881,15 @@ calculate_common_hash(struct args *args, struct hash *hash)
                }
        }
 
+       if (using_split_dwarf) {
+               // When using -gsplit-dwarf, object files include a link to the
+               // corresponding .dwo file based on the target object filename, so we need
+               // to include the target filename in the hash to avoid handing out an
+               // object file with an incorrect .dwo link.
+               hash_delimiter(hash, "filename");
+               hash_string(hash, basename(output_obj));
+       }
+
        // Possibly hash the coverage data file path.
        if (generating_coverage && profile_arcs) {
                char *dir = dirname(output_obj);
@@ -1929,15 +1986,22 @@ calculate_object_hash(struct args *args, struct hash *hash, int direct_mode)
                }
 
                // The -fdebug-prefix-map option may be used in combination with
-               // CCACHE_BASEDIR to reuse results across different directories. Skip it
-               // from hashing.
+               // CCACHE_BASEDIR to reuse results across different directories. Skip using
+               // the value of the option from hashing but still hash the existence of the
+               // option.
                if (str_startswith(args->argv[i], "-fdebug-prefix-map=")) {
+                       hash_delimiter(hash, "arg");
+                       hash_string(hash, "-fdebug-prefix-map=");
                        continue;
                }
                if (str_startswith(args->argv[i], "-ffile-prefix-map=")) {
+                       hash_delimiter(hash, "arg");
+                       hash_string(hash, "-ffile-prefix-map=");
                        continue;
                }
                if (str_startswith(args->argv[i], "-fmacro-prefix-map=")) {
+                       hash_delimiter(hash, "arg");
+                       hash_string(hash, "-fmacro-prefix-map=");
                        continue;
                }
 
@@ -2121,13 +2185,18 @@ calculate_object_hash(struct args *args, struct hash *hash, int direct_mode)
                        conf->direct_mode = false;
                        return NULL;
                }
+
                char *manifest_name = hash_result(hash);
                manifest_path = get_path_in_cache(manifest_name, ".manifest");
                free(manifest_name);
+
                cc_log("Looking for object file hash in %s", manifest_path);
+               MTR_BEGIN("manifest", "manifest_get");
                object_hash = manifest_get(conf, manifest_path);
+               MTR_END("manifest", "manifest_get");
                if (object_hash) {
                        cc_log("Got object file hash from manifest");
+                       update_mtime(manifest_path);
                } else {
                        cc_log("Did not find object file hash in manifest");
                }
@@ -2195,10 +2264,14 @@ from_cache(enum fromcache_call_mode mode, bool put_object_in_manifest)
                return;
        }
 
+       MTR_BEGIN("cache", "from_cache");
+
        // (If mode != FROMCACHE_DIRECT_MODE, the dependency file is created by gcc.)
        bool produce_dep_file =
                generating_dependencies && mode == FROMCACHE_DIRECT_MODE;
 
+       MTR_BEGIN("file", "file_get");
+
        // Get result from cache.
        if (!str_eq(output_obj, "/dev/null")) {
                get_file_from_cache(cached_obj, output_obj);
@@ -2207,7 +2280,9 @@ from_cache(enum fromcache_call_mode mode, bool put_object_in_manifest)
                }
        }
        if (produce_dep_file) {
-               get_file_from_cache(cached_dep, output_dep);
+               // Never hardlink the .d file since automake fails to move a foo.d.tmp file
+               // to foo.d if they have the same i-node.
+               copy_file_from_cache(cached_dep, output_dep);
        }
        if (generating_coverage) {
                get_file_from_cache(cached_cov, output_cov);
@@ -2219,6 +2294,8 @@ from_cache(enum fromcache_call_mode mode, bool put_object_in_manifest)
                get_file_from_cache(cached_dia, output_dia);
        }
 
+       MTR_END("file", "file_get");
+
        // Update modification timestamps to save files from LRU cleanup. Also gives
        // files a sensible mtime when hard-linking.
        update_mtime(cached_obj);
@@ -2258,6 +2335,8 @@ from_cache(enum fromcache_call_mode mode, bool put_object_in_manifest)
                break;
        }
 
+       MTR_END("cache", "from_cache");
+
        // And exit with the right status code.
        x_exit(0);
 }
@@ -2600,12 +2679,6 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                        continue;
                }
 
-               if (str_eq(argv[i], "-gsplit-dwarf")) {
-                       cc_log("Enabling caching of dwarf files since -gsplit-dwarf is used");
-                       using_split_dwarf = true;
-                       args_add(stripped_args, argv[i]);
-                       continue;
-               }
                if (str_startswith(argv[i], "-fdebug-prefix-map=")
                    || str_startswith(argv[i], "-ffile-prefix-map=")) {
                        debug_prefix_maps = x_realloc(
@@ -2620,15 +2693,22 @@ 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")) {
-                       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;
+
+                       char last_char = argv[i][strlen(argv[i]) - 1];
+                       if (last_char == '0') {
+                               // "-g0", "-ggdb0" or similar: All debug information disabled.
+                               // "-gsplit-dwarf" is still in effect if given previously, though.
+                               generating_debuginfo = false;
+                               generating_debuginfo_level_3 = false;
+                       } else {
+                               generating_debuginfo = true;
+                               if (last_char == '3') {
+                                       generating_debuginfo_level_3 = true;
+                               }
+                               if (str_eq(argv[i], "-gsplit-dwarf")) {
+                                       using_split_dwarf = true;
+                               }
                        }
                        continue;
                }
@@ -3034,8 +3114,12 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
 
                // If an argument isn't a plain file then assume its an option, not an
                // input file. This allows us to cope better with unusual compiler options.
+               //
+               // Note that "/dev/null" is an exception that is sometimes used as an input
+               // file when code is testing compiler flags.
                struct stat st;
-               if (stat(argv[i], &st) != 0 || !S_ISREG(st.st_mode)) {
+               if (!str_eq(argv[i], "/dev/null")
+                   && (stat(argv[i], &st) != 0 || !S_ISREG(st.st_mode))) {
                        cc_log("%s is not a regular file, not considering as input file",
                               argv[i]);
                        args_add(stripped_args, argv[i]);
@@ -3079,6 +3163,16 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                }
        } // for
 
+       if (generating_debuginfo && conf->unify) {
+               cc_log("Generating debug info; disabling unify mode");
+               conf->unify = false;
+       }
+
+       if (generating_debuginfo_level_3 && !conf->run_second_cpp) {
+               cc_log("Generating debug info level 3; not compiling preprocessed code");
+               conf->run_second_cpp = true;
+       }
+
        // See <http://gcc.gnu.org/onlinedocs/cpp/Environment-Variables.html>.
        // Contrary to what the documentation seems to imply the compiler still
        // creates object files with these defined (confirmed with GCC 8.2.1), i.e.
@@ -3237,16 +3331,17 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
                if (output_is_precompiled_header) {
                        output_obj = format("%s.gch", input_file);
                } else {
+                       char extension = found_S_opt ? 's' : 'o';
                        output_obj = basename(input_file);
                        char *p = strrchr(output_obj, '.');
-                       if (!p || !p[1]) {
-                               cc_log("Badly formed object filename");
-                               stats_update(STATS_ARGS);
-                               result = false;
-                               goto out;
+                       if (!p) {
+                               reformat(&output_obj, "%s.%c", output_obj, extension);
+                       } else if (!p[1]) {
+                               reformat(&output_obj, "%s%c", output_obj, extension);
+                       } else {
+                               p[1] = extension;
+                               p[2] = 0;
                        }
-                       p[1] = found_S_opt ? 's' : 'o';
-                       p[2] = 0;
                }
        }
 
@@ -3270,11 +3365,21 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
            && stat(output_obj, &st) == 0
            && !S_ISREG(st.st_mode)) {
                cc_log("Not a regular file: %s", output_obj);
-               stats_update(STATS_DEVICE);
+               stats_update(STATS_BADOUTPUTFILE);
                result = false;
                goto out;
        }
 
+       char *output_dir = dirname(output_obj);
+       if (stat(output_dir, &st) != 0 || !S_ISDIR(st.st_mode)) {
+               cc_log("Directory does not exist: %s", output_dir);
+               stats_update(STATS_BADOUTPUTFILE);
+               result = false;
+               free(output_dir);
+               goto out;
+       }
+       free(output_dir);
+
        // Some options shouldn't be passed to the real compiler when it compiles
        // preprocessed code:
        //
@@ -3432,13 +3537,77 @@ create_initial_config_file(const char *path)
        fclose(f);
 }
 
+#ifdef MTR_ENABLED
+static void *trace_id;
+static const char *trace_file;
+
+static void
+trace_init(const char *json)
+{
+       trace_file = json;
+       mtr_init(json);
+       char *s = format("%f", time_seconds());
+       MTR_INSTANT_C("", "", "time", s);
+}
+
+static void
+trace_start(const char *tracefile)
+{
+       trace_file = tracefile;
+       MTR_META_PROCESS_NAME(MYNAME);
+       trace_id = (void *) ((long) getpid());
+       MTR_START("program", "ccache", trace_id);
+}
+
+static void
+trace_stop(void)
+{
+       const char *json = format("%s%s", output_obj, ".ccache-trace");
+       MTR_FINISH("program", "ccache", trace_id);
+       mtr_flush();
+       mtr_shutdown();
+       move_file(trace_file, json, 0);
+}
+
+static const char *
+tmpdir()
+{
+#ifndef _WIN32
+       const char *tmpdir = getenv("TMPDIR");
+       if (tmpdir != NULL) {
+               return tmpdir;
+       }
+#else
+       static char dirbuf[PATH_MAX];
+       DWORD retval = GetTempPath(PATH_MAX, dirbuf);
+       if (retval > 0 && retval < PATH_MAX) {
+               return dirbuf;
+       }
+#endif
+       return "/tmp";
+}
+
+#endif // MTR_ENABLED
+
 // Read config file(s), populate variables, create configuration file in cache
 // directory if missing, etc.
 static void
 initialize(void)
 {
+       char *tracefile = getenv("CCACHE_INTERNAL_TRACE");
+       if (tracefile != NULL) {
+#ifdef MTR_ENABLED
+               // We don't have any conf yet, so we can't use temp_dir() here.
+               tracefile = format("%s/trace.%d.json", tmpdir(), (int)getpid());
+
+               trace_init(tracefile);
+#endif
+       }
+
        conf_free(conf);
+       MTR_BEGIN("config", "conf_create");
        conf = conf_create();
+       MTR_END("config", "conf_create");
 
        char *errmsg;
        char *p = getenv("CCACHE_CONFIGPATH");
@@ -3446,6 +3615,7 @@ initialize(void)
                primary_config_path = x_strdup(p);
        } else {
                secondary_config_path = format("%s/ccache.conf", TO_STRING(SYSCONFDIR));
+               MTR_BEGIN("config", "conf_read_secondary");
                if (!conf_read(conf, secondary_config_path, &errmsg)) {
                        if (errno == 0) {
                                // We could read the file but it contained errors.
@@ -3454,6 +3624,7 @@ initialize(void)
                        // A missing config file in SYSCONFDIR is OK.
                        free(errmsg);
                }
+               MTR_END("config", "conf_read_secondary");
 
                if (str_eq(conf->cache_dir, "")) {
                        fatal("configuration setting \"cache_dir\" must not be the empty string");
@@ -3470,6 +3641,7 @@ initialize(void)
        }
 
        bool should_create_initial_config = false;
+       MTR_BEGIN("config", "conf_read_primary");
        if (!conf_read(conf, primary_config_path, &errmsg)) {
                if (errno == 0) {
                        // We could read the file but it contained errors.
@@ -3479,10 +3651,13 @@ initialize(void)
                        should_create_initial_config = true;
                }
        }
+       MTR_END("config", "conf_read_primary");
 
+       MTR_BEGIN("config", "conf_update_from_environment");
        if (!conf_update_from_environment(conf, &errmsg)) {
                fatal("%s", errmsg);
        }
+       MTR_END("config", "conf_update_from_environment");
 
        if (should_create_initial_config) {
                create_initial_config_file(primary_config_path);
@@ -3498,6 +3673,15 @@ initialize(void)
        if (conf->umask != UINT_MAX) {
                umask(conf->umask);
        }
+
+       if (tracefile != NULL) {
+#ifdef MTR_ENABLED
+               trace_start(tracefile);
+               exitfn_add_nullary(trace_stop);
+#else
+               cc_log("Error: tracing is not enabled!");
+#endif
+       }
 }
 
 // Reset the global state. Used by the test suite.
@@ -3551,6 +3735,7 @@ cc_reset(void)
        }
        has_absolute_include_headers = false;
        generating_debuginfo = false;
+       generating_debuginfo_level_3 = false;
        generating_dependencies = false;
        generating_coverage = false;
        generating_stackusage = false;
@@ -3602,14 +3787,21 @@ ccache(int argc, char *argv[])
        set_up_signal_handlers();
 #endif
 
+       // Needed for portability when using localtime_r.
+       tzset();
+
        orig_args = args_init(argc, argv);
 
        initialize();
+       MTR_BEGIN("main", "find_compiler");
        find_compiler(argv);
+       MTR_END("main", "find_compiler");
 
+       MTR_BEGIN("main", "clean_up_internal_tempdir");
        if (str_eq(conf->temporary_dir, "")) {
                clean_up_internal_tempdir();
        }
+       MTR_END("main", "clean_up_internal_tempdir");
 
        if (!str_eq(conf->log_file, "") || conf->debug) {
                conf_print_items(conf, configuration_logger, NULL);
@@ -3620,7 +3812,9 @@ ccache(int argc, char *argv[])
                failed();
        }
 
+       MTR_BEGIN("main", "set_up_uncached_err");
        set_up_uncached_err();
+       MTR_END("main", "set_up_uncached_err");
 
        cc_log_argv("Command line: ", argv);
        cc_log("Hostname: %s", get_hostname());
@@ -3628,15 +3822,19 @@ ccache(int argc, char *argv[])
 
        conf->limit_multiple = MIN(MAX(conf->limit_multiple, 0.0), 1.0);
 
+       MTR_BEGIN("main", "guess_compiler");
        guessed_compiler = guess_compiler(orig_args->argv[0]);
+       MTR_END("main", "guess_compiler");
 
        // Arguments (except -E) to send to the preprocessor.
        struct args *preprocessor_args;
        // Arguments to send to the real compiler.
        struct args *compiler_args;
+       MTR_BEGIN("main", "process_args");
        if (!cc_process_args(orig_args, &preprocessor_args, &compiler_args)) {
                failed();
        }
+       MTR_END("main", "process_args");
 
        if (conf->depend_mode
            && (!generating_dependencies || !conf->run_second_cpp || conf->unify)) {
@@ -3662,22 +3860,29 @@ ccache(int argc, char *argv[])
        }
 
        cc_log("Object file: %s", output_obj);
+       MTR_META_THREAD_NAME(output_obj);
 
        // Need to dump log buffer as the last exit function to not lose any logs.
-       exitfn_add_last(dump_log_buffer_exitfn, output_obj);
+       exitfn_add_last(dump_debug_log_buffer_exitfn, output_obj);
 
        FILE *debug_text_file = NULL;
        if (conf->debug) {
                char *path = format("%s.ccache-input-text", output_obj);
                debug_text_file = fopen(path, "w");
+               if (debug_text_file) {
+                       exitfn_add(fclose_exitfn, debug_text_file);
+               } else {
+                       cc_log("Failed to open %s: %s", path, strerror(errno));
+               }
                free(path);
-               exitfn_add(fclose_exitfn, debug_text_file);
        }
 
        struct hash *common_hash = hash_init();
        init_hash_debug(common_hash, output_obj, 'c', "COMMON", debug_text_file);
 
+       MTR_BEGIN("hash", "common_hash");
        calculate_common_hash(preprocessor_args, common_hash);
+       MTR_END("hash", "common_hash");
 
        // Try to find the hash using the manifest.
        struct hash *direct_hash = hash_copy(common_hash);
@@ -3689,7 +3894,9 @@ ccache(int argc, char *argv[])
        struct file_hash *object_hash_from_manifest = NULL;
        if (conf->direct_mode) {
                cc_log("Trying direct lookup");
+               MTR_BEGIN("hash", "direct_hash");
                object_hash = calculate_object_hash(preprocessor_args, direct_hash, 1);
+               MTR_END("hash", "direct_hash");
                if (object_hash) {
                        update_cached_result_globals(object_hash);
 
@@ -3719,7 +3926,9 @@ ccache(int argc, char *argv[])
                init_hash_debug(
                        cpp_hash, output_obj, 'p', "PREPROCESSOR MODE", debug_text_file);
 
+               MTR_BEGIN("hash", "cpp_hash");
                object_hash = calculate_object_hash(preprocessor_args, cpp_hash, 0);
+               MTR_END("hash", "cpp_hash");
                if (!object_hash) {
                        fatal("internal error: object hash from cpp returned NULL");
                }
@@ -3762,7 +3971,9 @@ ccache(int argc, char *argv[])
        struct hash *depend_mode_hash = conf->depend_mode ? direct_hash : NULL;
 
        // Run real compiler, sending output to cache.
+       MTR_BEGIN("cache", "to_cache");
        to_cache(compiler_args, depend_mode_hash);
+       MTR_END("cache", "to_cache");
 
        x_exit(0);
 }
@@ -3780,7 +3991,8 @@ ccache_main_options(int argc, char *argv[])
 {
        enum longopts {
                DUMP_MANIFEST,
-               HASH_FILE
+               HASH_FILE,
+               PRINT_STATS,
        };
        static const struct option options[] = {
                {"cleanup",       no_argument,       0, 'c'},
@@ -3791,8 +4003,9 @@ ccache_main_options(int argc, char *argv[])
                {"help",          no_argument,       0, 'h'},
                {"max-files",     required_argument, 0, 'F'},
                {"max-size",      required_argument, 0, 'M'},
-               {"print-config",  no_argument,       0, 'p'},
+               {"print-stats",   no_argument,       0, PRINT_STATS},
                {"set-config",    required_argument, 0, 'o'},
+               {"show-config",   no_argument,       0, 'p'},
                {"show-stats",    no_argument,       0, 's'},
                {"version",       no_argument,       0, 'V'},
                {"zero-stats",    no_argument,       0, 'z'},
@@ -3823,6 +4036,11 @@ ccache_main_options(int argc, char *argv[])
                        break;
                }
 
+               case PRINT_STATS:
+                       initialize();
+                       stats_print();
+                       break;
+
                case 'c': // --cleanup
                        initialize();
                        clean_up_all(conf);
@@ -3907,7 +4125,7 @@ ccache_main_options(int argc, char *argv[])
                }
                break;
 
-               case 'p': // --print-config
+               case 'p': // --show-config
                        initialize();
                        conf_print_items(conf, configuration_printer, stdout);
                        break;
index 70c18b38da871e3c8ff45541216b2a72456956ec..39e4b0ca9e6046a943433b2579f76e2517088ef8 100644 (file)
@@ -21,6 +21,7 @@
 #include "system.h"
 #include "conf.h"
 #include "counters.h"
+#include "minitrace.h"
 
 #ifdef __GNUC__
 #define ATTR_FORMAT(x, y, z) __attribute__((format (x, y, z)))
@@ -54,7 +55,7 @@ enum stats {
        STATS_OBSOLETE_MAXFILES = 13,
        STATS_OBSOLETE_MAXSIZE = 14,
        STATS_SOURCELANG = 15,
-       STATS_DEVICE = 16,
+       STATS_BADOUTPUTFILE = 16,
        STATS_NOINPUT = 17,
        STATS_MULTIPLE = 18,
        STATS_CONFTEST = 19,
@@ -144,7 +145,7 @@ bool args_equal(struct args *args1, struct args *args2);
 void cc_log(const char *format, ...) ATTR_FORMAT(printf, 1, 2);
 void cc_bulklog(const char *format, ...) ATTR_FORMAT(printf, 1, 2);
 void cc_log_argv(const char *prefix, char **argv);
-void cc_dump_log_buffer(const char *path);
+void cc_dump_debug_log_buffer(const char *path);
 void fatal(const char *format, ...) ATTR_FORMAT(printf, 1, 2) ATTR_NORETURN;
 void warn(const char *format, ...) ATTR_FORMAT(printf, 1, 2);
 
@@ -183,6 +184,9 @@ char *format_parsable_size_with_suffix(uint64_t size);
 bool parse_size_with_suffix(const char *str, uint64_t *size);
 char *x_realpath(const char *path);
 char *gnu_getcwd(void);
+#ifndef HAVE_LOCALTIME_R
+struct tm *localtime_r(const time_t *timep, struct tm *result);
+#endif
 #ifndef HAVE_STRTOK_R
 char *strtok_r(char *str, const char *delim, char **saveptr);
 #endif
@@ -209,6 +213,7 @@ 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);
+double time_seconds(void);
 
 // ----------------------------------------------------------------------------
 // stats.c
@@ -218,6 +223,7 @@ void stats_flush(void);
 unsigned stats_get_pending(enum stats stat);
 void stats_zero(void);
 void stats_summary(void);
+void stats_print(void);
 void stats_update_size(int64_t size, int files);
 void stats_get_obsolete_limits(const char *dir, unsigned *maxfiles,
                                uint64_t *maxsize);
index dbf32f0cdfc2a76b8d5a5df61fcd9482992c9a9d..2106df3da1405280da6609662a039484acf877b6 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2018 Joel Rosdahl
+// Copyright (C) 2010-2019 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -30,6 +30,7 @@ struct compopt {
 };
 
 static const struct compopt compopts[] = {
+       {"--analyze",       TOO_HARD}, // clang
        {"--compiler-bindir", AFFECTS_CPP | TAKES_ARG}, // nvcc
        {"--libdevice-directory", AFFECTS_CPP | TAKES_ARG}, // nvcc
        {"--output-directory", AFFECTS_CPP | TAKES_ARG}, // nvcc
@@ -59,6 +60,7 @@ static const struct compopt compopts[] = {
        {"-Xclang",         TAKES_ARG},
        {"-Xlinker",        TAKES_ARG},
        {"-Xpreprocessor",  AFFECTS_CPP | TOO_HARD_DIRECT | TAKES_ARG},
+       {"-analyze",        TOO_HARD}, // clang
        {"-arch",           TAKES_ARG},
        {"-aux-info",       TAKES_ARG},
        {"-b",              TAKES_ARG},
@@ -68,6 +70,7 @@ static const struct compopt compopts[] = {
        {"-fplugin=libcc1plugin", TOO_HARD}, // interaction with GDB
        {"-frepo",          TOO_HARD},
        {"-fworking-directory", AFFECTS_CPP},
+       {"-gtoggle",        TOO_HARD},
        {"-idirafter",      AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
        {"-iframework",     AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
        {"-imacros",        AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
index 4c7d35df34c9b4ece15dd00bcf2d867cfcc3d9d6..61e4a4be756ee9bdaf135d5481d26bbc5ad2e6d7 100644 (file)
 #include "envtoconfitems.h"
 #include "ccache.h"
 
+enum handle_conf_result {
+       HANDLE_CONF_OK,
+       HANDLE_CONF_UNKNOWN,
+       HANDLE_CONF_FAIL
+};
+
 static const struct conf_item *
 find_conf(const char *name)
 {
@@ -31,15 +37,14 @@ find_env_to_conf(const char *name)
        return envtoconfitems_get(name, strlen(name));
 }
 
-static bool
+static enum handle_conf_result
 handle_conf_setting(struct conf *conf, const char *key, const char *value,
                     char **errmsg, bool from_env_variable, bool negate_boolean,
                     const char *origin)
 {
        const struct conf_item *item = find_conf(key);
        if (!item) {
-               *errmsg = format("unknown configuration option \"%s\"", key);
-               return false;
+               return HANDLE_CONF_UNKNOWN;
        }
 
        if (from_env_variable && item->parser == confitem_parse_bool) {
@@ -61,15 +66,15 @@ handle_conf_setting(struct conf *conf, const char *key, const char *value,
        }
 
        if (!item->parser(value, (char *)conf + item->offset, errmsg)) {
-               return false;
+               return HANDLE_CONF_FAIL;
        }
        if (item->verifier && !item->verifier((char *)conf + item->offset, errmsg)) {
-               return false;
+               return HANDLE_CONF_FAIL;
        }
 
 out:
        conf->item_origins[item->number] = origin;
-       return true;
+       return HANDLE_CONF_OK;
 }
 
 static bool
@@ -210,9 +215,12 @@ conf_read(struct conf *conf, const char *path, char **errmsg)
                char *key;
                char *value;
                char *errmsg2;
+               enum handle_conf_result hcr = HANDLE_CONF_OK;
                bool ok = parse_line(buf, &key, &value, &errmsg2);
                if (ok && key) { // key == NULL if comment or blank line.
-                       ok = handle_conf_setting(conf, key, value, &errmsg2, false, false, path);
+                       hcr =
+                               handle_conf_setting(conf, key, value, &errmsg2, false, false, path);
+                       ok = hcr != HANDLE_CONF_FAIL; // unknown is OK
                }
                free(key);
                free(value);
@@ -265,11 +273,11 @@ conf_update_from_environment(struct conf *conf, char **errmsg)
                        continue;
                }
 
-               char *errmsg2;
-               bool ok = handle_conf_setting(
+               char *errmsg2 = NULL;
+               enum handle_conf_result hcr = handle_conf_setting(
                        conf, env_to_conf_item->conf_name, q, &errmsg2, true, negate,
                        "environment");
-               if (!ok) {
+               if (hcr != HANDLE_CONF_OK) {
                        *errmsg = format("%s: %s", key, errmsg2);
                        free(errmsg2);
                        free(key);
index ae303322a2b893b13b1ada5eed69464a8a9b6a72..bf067620a36a59ede53e1c980c4306bf2054f58f 100644 (file)
@@ -1,5 +1,5 @@
 // Copyright (C) 2002 Andrew Tridgell
-// Copyright (C) 2010-2018 Joel Rosdahl
+// Copyright (C) 2010-2019 Joel Rosdahl
 //
 // This program is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by the Free
@@ -30,6 +30,8 @@ struct hash {
 static void
 do_hash_buffer(struct hash *hash, const void *s, size_t len)
 {
+       assert(s);
+
        mdfour_update(&hash->md, (const unsigned char *)s, len);
        if (len > 0 && hash->debug_binary) {
                (void) fwrite(s, 1, len, hash->debug_binary);
@@ -84,7 +86,7 @@ void hash_enable_debug(
 size_t
 hash_input_size(struct hash *hash)
 {
-       return hash->md.totalN;
+       return hash->md.totalN + hash->md.tail_len;
 }
 
 void
@@ -100,13 +102,12 @@ hash_result(struct hash *hash)
        unsigned char sum[16];
 
        hash_result_as_bytes(hash, sum);
-       return format_hash_as_string(sum, (unsigned) hash->md.totalN);
+       return format_hash_as_string(sum, hash_input_size(hash));
 }
 
 void
 hash_result_as_bytes(struct hash *hash, unsigned char *out)
 {
-       mdfour_update(&hash->md, NULL, 0);
        mdfour_result(&hash->md, out);
 }
 
index 789bf437b51efcffe869a5eb67e89f540ba9aa7e..289ba1717e23372fea291cf105612854e5af116c 100644 (file)
@@ -107,12 +107,13 @@ hash_source_code_string(
                // Make sure that the hash sum changes if the (potential) expansion of
                // __DATE__ changes.
                time_t t = time(NULL);
-               struct tm *now = localtime(&t);
+               struct tm now;
+               localtime_r(&t, &now);
                cc_log("Found __DATE__ in %s", path);
                hash_delimiter(hash, "date");
-               hash_int(hash, now->tm_year);
-               hash_int(hash, now->tm_mon);
-               hash_int(hash, now->tm_mday);
+               hash_int(hash, now.tm_year);
+               hash_int(hash, now.tm_mon);
+               hash_int(hash, now.tm_mday);
        }
        if (result & HASH_SOURCE_CODE_FOUND_TIME) {
                // We don't know for sure that the program actually uses the __TIME__
index 4c4a998bc8461ac9fe2a385ff7a1dbd9dc9ddad1..cfc4398e80c6222a7acf8d1cab9a76f6719b5628 100644 (file)
@@ -64,30 +64,6 @@ static const struct {
        {".TCC", "c++-header"},
        {".cu",  "cuda"},
        {".ic",  "cuda-output"},
-       // Fixed form Fortran without preprocessing:
-       {".f",   "f77"},
-       {".for", "f77"},
-       {".ftn", "f77"},
-       // Fixed form Fortran with traditional preprocessing:
-       {".F",   "f77-cpp-input"},
-       {".FOR", "f77-cpp-input"},
-       {".fpp", "f77-cpp-input"},
-       {".FPP", "f77-cpp-input"},
-       {".FTN", "f77-cpp-input"},
-       // Free form Fortran without preprocessing:
-#if 0 // Could generate modules, ignore for now!
-       {".f90", "f95"},
-       {".f95", "f95"},
-       {".f03", "f95"},
-       {".f08", "f95"},
-#endif
-       // Free form Fortran with traditional preprocessing:
-#if 0 // Could generate modules, ignore for now!
-       {".F90", "f95-cpp-input"},
-       {".F95", "f95-cpp-input"},
-       {".F03", "f95-cpp-input"},
-       {".F08", "f95-cpp-input"},
-#endif
        {NULL,  NULL}
 };
 
@@ -113,12 +89,6 @@ static const struct {
        {"cuda",                     "cuda-output"},
        {"assembler-with-cpp",       "assembler"},
        {"assembler",                "assembler"},
-       {"f77-cpp-input",            "f77"},
-       {"f77",                      "f77"},
-#if 0 // Could generate module files, ignore for now!
-       {"f95-cpp-input",            "f95"},
-       {"f95",                      "f95"},
-#endif
        {NULL,  NULL}
 };
 
index 11e0fba1ef5f910f5c237f316401c9a9fdfbeccb..c0aec6bc28a59e31f8a029b3ce2f46cfc0714f93 100644 (file)
@@ -1,5 +1,5 @@
 // Copyright (C) 1997-1998 Andrew Tridgell
-// Copyright (C) 2009-2018 Joel Rosdahl
+// Copyright (C) 2009-2019 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
@@ -129,7 +129,6 @@ mdfour_begin(struct mdfour *md)
        md->D = 0x10325476;
        md->totalN = 0;
        md->tail_len = 0;
-       md->finalized = 0;
 }
 
 static
@@ -160,13 +159,7 @@ void mdfour_tail(struct mdfour *md, const unsigned char *in, size_t n)
 void
 mdfour_update(struct mdfour *md, const unsigned char *in, size_t n)
 {
-       if (!in) {
-               if (!md->finalized) {
-                       mdfour_tail(md, md->tail, md->tail_len);
-                       md->finalized = 1;
-               }
-               return;
-       }
+       assert(in);
 
        uint32_t M[16];
        if (md->tail_len) {
@@ -203,8 +196,18 @@ mdfour_update(struct mdfour *md, const unsigned char *in, size_t n)
 void
 mdfour_result(struct mdfour *md, unsigned char *out)
 {
-       copy4(out, md->A);
-       copy4(out+4, md->B);
-       copy4(out+8, md->C);
-       copy4(out+12, md->D);
+       struct mdfour result;
+       result.A = md->A;
+       result.B = md->B;
+       result.C = md->C;
+       result.D = md->D;
+       result.totalN = md->totalN;
+       result.tail_len = md->tail_len;
+       memcpy(result.tail, md->tail, result.tail_len);
+
+       mdfour_tail(&result, result.tail, result.tail_len);
+       copy4(out, result.A);
+       copy4(out+4, result.B);
+       copy4(out+8, result.C);
+       copy4(out+12, result.D);
 }
index c196a09e952ef7b164caa94d272ca031d02e32f4..761a19ee569000d08d0637ad5037385103e7e41d 100644 (file)
@@ -7,9 +7,8 @@
 struct mdfour {
        uint32_t A, B, C, D;
        size_t totalN;
-       unsigned char tail[64];
        size_t tail_len;
-       int finalized;
+       unsigned char tail[64];
 };
 
 void mdfour_begin(struct mdfour *md);
diff --git a/src/minitrace.c b/src/minitrace.c
new file mode 100644 (file)
index 0000000..df1a3ac
--- /dev/null
@@ -0,0 +1,395 @@
+// minitrace
+// Copyright 2014 by Henrik Rydgård
+// http://www.github.com/hrydgard/minitrace
+// Released under the MIT license.
+
+// See minitrace.h for basic documentation.
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef _WIN32
+#pragma warning (disable:4996)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#define __thread __declspec(thread)
+#define pthread_mutex_t CRITICAL_SECTION
+#define pthread_mutex_init(a, b) InitializeCriticalSection(a)
+#define pthread_mutex_lock(a) EnterCriticalSection(a)
+#define pthread_mutex_unlock(a) LeaveCriticalSection(a)
+#define pthread_mutex_destroy(a) DeleteCriticalSection(a)
+#else
+#include <signal.h>
+#include <pthread.h>
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+
+#include "minitrace.h"
+
+#ifdef __GNUC__
+#define ATTR_NORETURN __attribute__((noreturn))
+#else
+#define ATTR_NORETURN
+#endif
+
+#define ARRAY_SIZE(x) sizeof(x)/sizeof(x[0])
+
+// Ugh, this struct is already pretty heavy.
+// Will probably need to move arguments to a second buffer to support more than one.
+typedef struct raw_event {
+       const char *name;
+       const char *cat;
+       void *id;
+       int64_t ts;
+       uint32_t pid;
+       uint32_t tid;
+       char ph;
+       mtr_arg_type arg_type;
+       const char *arg_name;
+       union {
+               const char *a_str;
+               int a_int;
+               double a_double;
+       };
+} raw_event_t;
+
+static raw_event_t *buffer;
+static volatile int count;
+static int is_tracing = 0;
+static int64_t time_offset;
+static int first_line = 1;
+static FILE *f;
+static __thread int cur_thread_id;     // Thread local storage
+static int cur_process_id;
+static pthread_mutex_t mutex;
+
+#define STRING_POOL_SIZE 100
+static char *str_pool[100];
+
+// Tiny portability layer.
+// Exposes:
+//      get_cur_thread_id()
+//      get_cur_process_id()
+//      mtr_time_s()
+//      pthread basics
+#ifdef _WIN32
+static int get_cur_thread_id() {
+       return (int)GetCurrentThreadId();
+}
+static int get_cur_process_id() {
+       return (int)GetCurrentProcessId();
+}
+
+static uint64_t _frequency = 0;
+static uint64_t _starttime = 0;
+double mtr_time_s() {
+       if (_frequency == 0) {
+               QueryPerformanceFrequency((LARGE_INTEGER*)&_frequency);
+               QueryPerformanceCounter((LARGE_INTEGER*)&_starttime);
+       }
+       __int64 time;
+       QueryPerformanceCounter((LARGE_INTEGER*)&time);
+       return ((double) (time - _starttime) / (double) _frequency);
+}
+
+// Ctrl+C handling for Windows console apps
+static BOOL WINAPI CtrlHandler(DWORD fdwCtrlType) {
+       if (is_tracing && fdwCtrlType == CTRL_C_EVENT) {
+               printf("Ctrl-C detected! Flushing trace and shutting down.\n\n");
+               mtr_flush();
+               mtr_shutdown();
+       }
+       ExitProcess(1);
+}
+
+void mtr_register_sigint_handler() {
+       // For console apps:
+       SetConsoleCtrlHandler(&CtrlHandler, TRUE);
+}
+
+#else
+
+static inline int get_cur_thread_id() {
+       return (int)(intptr_t)pthread_self();
+}
+static inline int get_cur_process_id() {
+       return (int)getpid();
+}
+
+#if defined(BLACKBERRY)
+double mtr_time_s() {
+       struct timespec time;
+       clock_gettime(CLOCK_MONOTONIC, &time); // Linux must use CLOCK_MONOTONIC_RAW due to time warps
+       return time.tv_sec + time.tv_nsec / 1.0e9;
+}
+#else
+double mtr_time_s() {
+       static time_t start;
+       struct timeval tv;
+       gettimeofday(&tv, NULL);
+       if (start == 0) {
+               start = tv.tv_sec;
+       }
+       tv.tv_sec -= start;
+       return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0;
+}
+#endif // !BLACKBERRY
+
+static void termination_handler(int signum) ATTR_NORETURN;
+static void termination_handler(int signum) {
+       (void) signum;
+       if (is_tracing) {
+               printf("Ctrl-C detected! Flushing trace and shutting down.\n\n");
+               mtr_flush();
+               fwrite("\n]}\n", 1, 4, f);
+               fclose(f);
+       }
+       exit(1);
+}
+
+void mtr_register_sigint_handler() {
+#ifndef MTR_ENABLED
+       return;
+#endif
+       // Avoid altering set-to-be-ignored handlers while registering.
+       if (signal(SIGINT, &termination_handler) == SIG_IGN)
+               signal(SIGINT, SIG_IGN);
+}
+
+#endif
+
+void mtr_init_from_stream(void *stream) {
+#ifndef MTR_ENABLED
+       return;
+#endif
+       buffer = (raw_event_t *)malloc(INTERNAL_MINITRACE_BUFFER_SIZE * sizeof(raw_event_t));
+       is_tracing = 1;
+       count = 0;
+       f = (FILE *)stream;
+       const char *header = "{\"traceEvents\":[\n";
+       fwrite(header, 1, strlen(header), f);
+       time_offset = (uint64_t)(mtr_time_s() * 1000000);
+       first_line = 1;
+       pthread_mutex_init(&mutex, 0);
+}
+
+void mtr_init(const char *json_file) {
+#ifndef MTR_ENABLED
+       return;
+#endif
+       mtr_init_from_stream(fopen(json_file, "wb"));
+}
+
+void mtr_shutdown() {
+       int i;
+#ifndef MTR_ENABLED
+       return;
+#endif
+       is_tracing = 0;
+       mtr_flush();
+       fwrite("\n]}\n", 1, 4, f);
+       fclose(f);
+       pthread_mutex_destroy(&mutex);
+       f = 0;
+       free(buffer);
+       buffer = 0;
+       for (i = 0; i < STRING_POOL_SIZE; i++) {
+               if (str_pool[i]) {
+                       free(str_pool[i]);
+                       str_pool[i] = 0;
+               }
+       }
+}
+
+const char *mtr_pool_string(const char *str) {
+       int i;
+       for (i = 0; i < STRING_POOL_SIZE; i++) {
+               if (!str_pool[i]) {
+                       str_pool[i] = (char*)malloc(strlen(str) + 1);
+                       strcpy(str_pool[i], str);
+                       return str_pool[i];
+               } else {
+                       if (!strcmp(str, str_pool[i]))
+                               return str_pool[i];
+               }
+       }
+       return "string pool full";
+}
+
+void mtr_start() {
+#ifndef MTR_ENABLED
+       return;
+#endif
+       is_tracing = 1;
+}
+
+void mtr_stop() {
+#ifndef MTR_ENABLED
+       return;
+#endif
+       is_tracing = 0;
+}
+
+// TODO: fwrite more than one line at a time.
+void mtr_flush() {
+#ifndef MTR_ENABLED
+       return;
+#endif
+       int i = 0;
+       char linebuf[1024];
+       char arg_buf[1024];
+       char id_buf[256];
+       // We have to lock while flushing. So we really should avoid flushing as much as possible.
+
+
+       pthread_mutex_lock(&mutex);
+       int old_tracing = is_tracing;
+       is_tracing = 0; // Stop logging even if using interlocked increments instead of the mutex. Can cause data loss.
+
+       for (i = 0; i < count; i++) {
+               raw_event_t *raw = &buffer[i];
+               int len;
+               switch (raw->arg_type) {
+               case MTR_ARG_TYPE_INT:
+                       snprintf(arg_buf, ARRAY_SIZE(arg_buf), "\"%s\":%i", raw->arg_name, raw->a_int);
+                       break;
+               case MTR_ARG_TYPE_STRING_CONST:
+                       snprintf(arg_buf, ARRAY_SIZE(arg_buf), "\"%s\":\"%s\"", raw->arg_name, raw->a_str);
+                       break;
+               case MTR_ARG_TYPE_STRING_COPY:
+                       if (strlen(raw->a_str) > 700) {
+                               snprintf(arg_buf, ARRAY_SIZE(arg_buf), "\"%s\":\"%.*s\"", raw->arg_name, 700, raw->a_str);
+                       } else {
+                               snprintf(arg_buf, ARRAY_SIZE(arg_buf), "\"%s\":\"%s\"", raw->arg_name, raw->a_str);
+                       }
+                       break;
+               case MTR_ARG_TYPE_NONE:
+                       arg_buf[0] = '\0';
+                       break;
+               }
+               if (raw->id) {
+                       switch (raw->ph) {
+                       case 'S':
+                       case 'T':
+                       case 'F':
+                               // TODO: Support full 64-bit pointers
+                               snprintf(id_buf, ARRAY_SIZE(id_buf), ",\"id\":\"0x%08x\"", (uint32_t)(uintptr_t)raw->id);
+                               break;
+                       case 'X':
+                               snprintf(id_buf, ARRAY_SIZE(id_buf), ",\"dur\":%i", (int)raw->a_double);
+                               break;
+                       }
+               } else {
+                       id_buf[0] = 0;
+               }
+               const char *cat = raw->cat;
+#ifdef _WIN32
+               // On Windows, we often end up with backslashes in category.
+               char temp[256];
+               {
+                       int len = (int)strlen(cat);
+                       int i;
+                       if (len > 255) len = 255;
+                       for (i = 0; i < len; i++) {
+                               temp[i] = cat[i] == '\\' ? '/' : cat[i];
+                       }
+                       temp[len] = 0;
+                       cat = temp;
+               }
+#endif
+
+               len = snprintf(linebuf, ARRAY_SIZE(linebuf), "%s{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64 ",\"ph\":\"%c\",\"name\":\"%s\",\"args\":{%s}%s}",
+                               first_line ? "" : ",\n",
+                               cat, raw->pid, raw->tid, raw->ts - time_offset, raw->ph, raw->name, arg_buf, id_buf);
+               fwrite(linebuf, 1, len, f);
+               first_line = 0;
+       }
+       count = 0;
+       is_tracing = old_tracing;
+       pthread_mutex_unlock(&mutex);
+}
+
+void internal_mtr_raw_event(const char *category, const char *name, char ph, void *id) {
+#ifndef MTR_ENABLED
+       return;
+#endif
+       if (!is_tracing || count >= INTERNAL_MINITRACE_BUFFER_SIZE)
+               return;
+       double ts = mtr_time_s();
+       if (!cur_thread_id) {
+               cur_thread_id = get_cur_thread_id();
+       }
+       if (!cur_process_id) {
+               cur_process_id = get_cur_process_id();
+       }
+
+#if 0 && _WIN32        // This should work, feel free to enable if you're adventurous and need performance.
+       int bufPos = InterlockedExchangeAdd((LONG volatile *)&count, 1);
+       raw_event_t *ev = &buffer[bufPos];
+#else
+       pthread_mutex_lock(&mutex);
+       raw_event_t *ev = &buffer[count];
+       count++;
+       pthread_mutex_unlock(&mutex);
+#endif
+
+       ev->cat = category;
+       ev->name = name;
+       ev->id = id;
+       ev->ph = ph;
+       if (ev->ph == 'X') {
+               double x;
+               memcpy(&x, id, sizeof(double));
+               ev->ts = (int64_t)(x * 1000000);
+               ev->a_double = (ts - x) * 1000000;
+       } else {
+               ev->ts = (int64_t)(ts * 1000000);
+       }
+       ev->tid = cur_thread_id;
+       ev->pid = cur_process_id;
+       ev->arg_type = MTR_ARG_TYPE_NONE;
+}
+
+void internal_mtr_raw_event_arg(const char *category, const char *name, char ph, void *id, mtr_arg_type arg_type, const char *arg_name, void *arg_value) {
+#ifndef MTR_ENABLED
+       return;
+#endif
+       if (!is_tracing || count >= INTERNAL_MINITRACE_BUFFER_SIZE)
+               return;
+       if (!cur_thread_id) {
+               cur_thread_id = get_cur_thread_id();
+       }
+       if (!cur_process_id) {
+               cur_process_id = get_cur_process_id();
+       }
+       double ts = mtr_time_s();
+
+#if 0 && _WIN32        // This should work, feel free to enable if you're adventurous and need performance.
+       int bufPos = InterlockedExchangeAdd((LONG volatile *)&count, 1);
+       raw_event_t *ev = &buffer[bufPos];
+#else
+       pthread_mutex_lock(&mutex);
+       raw_event_t *ev = &buffer[count];
+       count++;
+       pthread_mutex_unlock(&mutex);
+#endif
+
+       ev->cat = category;
+       ev->name = name;
+       ev->id = id;
+       ev->ts = (int64_t)(ts * 1000000);
+       ev->ph = ph;
+       ev->tid = cur_thread_id;
+       ev->pid = cur_process_id;
+       ev->arg_type = arg_type;
+       ev->arg_name = arg_name;
+       switch (arg_type) {
+       case MTR_ARG_TYPE_INT: ev->a_int = (int)(uintptr_t)arg_value; break;
+       case MTR_ARG_TYPE_STRING_CONST: ev->a_str = (const char*)arg_value; break;
+       case MTR_ARG_TYPE_STRING_COPY: ev->a_str = strdup((const char*)arg_value); break;
+       case MTR_ARG_TYPE_NONE: break;
+       }
+}
+
diff --git a/src/minitrace.h b/src/minitrace.h
new file mode 100644 (file)
index 0000000..2047eed
--- /dev/null
@@ -0,0 +1,270 @@
+// Minitrace
+//
+// Copyright 2014 by Henrik Rydgård
+// http://www.github.com/hrydgard/minitrace
+// Released under the MIT license.
+//
+// Ultra-light dependency free library for performance tracing C/C++ applications.
+// Produces traces compatible with Google Chrome's trace viewer.
+// Simply open "about:tracing" in Chrome and load the produced JSON.
+//
+// This contains far less template magic than the original libraries from Chrome
+// because this is meant to be usable from C.
+//
+// See README.md for a tutorial.
+//
+// The trace format is documented here:
+// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/edit
+// More:
+// http://www.altdevblogaday.com/2012/08/21/using-chrometracing-to-view-your-inline-profiling-data/
+
+#ifndef MINITRACE_H
+#define MINITRACE_H
+
+#include <inttypes.h>
+
+// If MTR_ENABLED is not defined, Minitrace does nothing and has near zero overhead.
+// Preferably, set this flag in your build system. If you can't just uncomment this line.
+// #define MTR_ENABLED
+
+// By default, will collect up to 1000000 events, then you must flush.
+// It's recommended that you simply call mtr_flush on a background thread
+// occasionally. It's safe...ish.
+#define INTERNAL_MINITRACE_BUFFER_SIZE 1000000
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Initializes Minitrace. Must be called very early during startup of your executable,
+// before any MTR_ statements.
+void mtr_init(const char *json_file);
+// Same as above, but allows passing in a custom stream (FILE *), as returned by
+// fopen(). It should be opened for writing, preferably in binary mode to avoid
+// processing of line endings (i.e. the "wb" mode).
+void mtr_init_from_stream(void *stream);
+
+// Shuts down minitrace cleanly, flushing the trace buffer.
+void mtr_shutdown(void);
+
+// Lets you enable and disable Minitrace at runtime.
+// May cause strange discontinuities in the output.
+// Minitrace is enabled on startup by default.
+void mtr_start(void);
+void mtr_stop(void);
+
+// Flushes the collected data to disk, clearing the buffer for new data.
+void mtr_flush(void);
+
+// Returns the current time in seconds. Used internally by Minitrace. No caching.
+double mtr_time_s(void);
+
+// Registers a handler that will flush the trace on Ctrl+C.
+// Works on Linux and MacOSX, and in Win32 console applications.
+void mtr_register_sigint_handler(void);
+
+// Utility function that should rarely be used.
+// If str is semi dynamic, store it permanently in a small pool so we don't need to malloc it.
+// The pool fills up fast though and performance isn't great.
+// Returns a fixed string if the pool is full.
+const char *mtr_pool_string(const char *str);
+
+// Commented-out types will be supported in the future.
+typedef enum {
+       MTR_ARG_TYPE_NONE = 0,
+       MTR_ARG_TYPE_INT = 1,   // I
+       // MTR_ARG_TYPE_FLOAT = 2,  // TODO
+       // MTR_ARG_TYPE_DOUBLE = 3,  // TODO
+       MTR_ARG_TYPE_STRING_CONST = 8,  // C
+       MTR_ARG_TYPE_STRING_COPY = 9,
+       // MTR_ARG_TYPE_JSON_COPY = 10,
+} mtr_arg_type;
+
+// TODO: Add support for more than one argument (metadata) per event
+// Having more costs speed and memory.
+#define MTR_MAX_ARGS 1
+
+// Only use the macros to call these.
+void internal_mtr_raw_event(const char *category, const char *name, char ph, void *id);
+void internal_mtr_raw_event_arg(const char *category, const char *name, char ph, void *id, mtr_arg_type arg_type, const char *arg_name, void *arg_value);
+
+#ifdef MTR_ENABLED
+
+// c - category. Can be filtered by in trace viewer (or at least that's the intention).
+//     A good use is to pass __FILE__, there are macros further below that will do it for you.
+// n - name. Pass __FUNCTION__ in most cases, unless you are marking up parts of one.
+
+// Scopes. In C++, use MTR_SCOPE. In C, always match them within the same scope.
+#define MTR_BEGIN(c, n) internal_mtr_raw_event(c, n, 'B', 0)
+#define MTR_END(c, n) internal_mtr_raw_event(c, n, 'E', 0)
+#define MTR_SCOPE(c, n) MTRScopedTrace ____mtr_scope(c, n)
+#define MTR_SCOPE_LIMIT(c, n, l) MTRScopedTraceLimit ____mtr_scope(c, n, l)
+
+// Async events. Can span threads. ID identifies which events to connect in the view.
+#define MTR_START(c, n, id) internal_mtr_raw_event(c, n, 'S', (void *)(id))
+#define MTR_STEP(c, n, id, step) internal_mtr_raw_event_arg(c, n, 'T', (void *)(id), MTR_ARG_TYPE_STRING_CONST, "step", (void *)(step))
+#define MTR_FINISH(c, n, id) internal_mtr_raw_event(c, n, 'F', (void *)(id))
+
+// Flow events. Like async events, but displayed in a more fancy way in the viewer.
+#define MTR_FLOW_START(c, n, id) internal_mtr_raw_event(c, n, 's', (void *)(id))
+#define MTR_FLOW_STEP(c, n, id, step) internal_mtr_raw_event_arg(c, n, 't', (void *)(id), MTR_ARG_TYPE_STRING_CONST, "step", (void *)(step))
+#define MTR_FLOW_FINISH(c, n, id) internal_mtr_raw_event(c, n, 'f', (void *)(id))
+
+// The same macros, but with a single named argument which shows up as metadata in the viewer.
+// _I for int.
+// _C is for a const string arg.
+// _S will copy the string, freeing on flush (expensive but sometimes necessary).
+// but required if the string was generated dynamically.
+
+// Note that it's fine to match BEGIN_S with END and BEGIN with END_S, etc.
+#define MTR_BEGIN_C(c, n, aname, astrval) internal_mtr_raw_event_arg(c, n, 'B', 0, MTR_ARG_TYPE_STRING_CONST, aname, (void *)(astrval))
+#define MTR_END_C(c, n, aname, astrval) internal_mtr_raw_event_arg(c, n, 'E', 0, MTR_ARG_TYPE_STRING_CONST, aname, (void *)(astrval))
+#define MTR_SCOPE_C(c, n, aname, astrval) MTRScopedTraceArg ____mtr_scope(c, n, MTR_ARG_TYPE_STRING_CONST, aname, (void *)(astrval))
+
+#define MTR_BEGIN_S(c, n, aname, astrval) internal_mtr_raw_event_arg(c, n, 'B', 0, MTR_ARG_TYPE_STRING_COPY, aname, (void *)(astrval))
+#define MTR_END_S(c, n, aname, astrval) internal_mtr_raw_event_arg(c, n, 'E', 0, MTR_ARG_TYPE_STRING_COPY, aname, (void *)(astrval))
+#define MTR_SCOPE_S(c, n, aname, astrval) MTRScopedTraceArg ____mtr_scope(c, n, MTR_ARG_TYPE_STRING_COPY, aname, (void *)(astrval))
+
+#define MTR_BEGIN_I(c, n, aname, aintval) internal_mtr_raw_event_arg(c, n, 'B', 0, MTR_ARG_TYPE_INT, aname, (void*)(intptr_t)(aintval))
+#define MTR_END_I(c, n, aname, aintval) internal_mtr_raw_event_arg(c, n, 'E', 0, MTR_ARG_TYPE_INT, aname, (void*)(intptr_t)(aintval))
+#define MTR_SCOPE_I(c, n, aname, aintval) MTRScopedTraceArg ____mtr_scope(c, n, MTR_ARG_TYPE_INT, aname, (void*)(intptr_t)(aintval))
+
+// Instant events. For things with no duration.
+#define MTR_INSTANT(c, n) internal_mtr_raw_event(c, n, 'I', 0)
+#define MTR_INSTANT_C(c, n, aname, astrval) internal_mtr_raw_event_arg(c, n, 'I', 0, MTR_ARG_TYPE_STRING_CONST, aname, (void *)(astrval))
+#define MTR_INSTANT_I(c, n, aname, aintval) internal_mtr_raw_event_arg(c, n, 'I', 0, MTR_ARG_TYPE_INT, aname, (void *)(aintval))
+
+// Counters (can't do multi-value counters yet)
+#define MTR_COUNTER(c, n, val) internal_mtr_raw_event_arg(c, n, 'C', 0, MTR_ARG_TYPE_INT, n, (void *)(intptr_t)(val))
+
+// Metadata. Call at the start preferably. Must be const strings.
+
+#define MTR_META_PROCESS_NAME(n) internal_mtr_raw_event_arg("", "process_name", 'M', 0, MTR_ARG_TYPE_STRING_COPY, "name", (void *)(n))
+#define MTR_META_THREAD_NAME(n) internal_mtr_raw_event_arg("", "thread_name", 'M', 0, MTR_ARG_TYPE_STRING_COPY, "name", (void *)(n))
+#define MTR_META_THREAD_SORT_INDEX(i) internal_mtr_raw_event_arg("", "thread_sort_index", 'M', 0, MTR_ARG_TYPE_INT, "sort_index", (void *)(i))
+
+#else
+
+#define MTR_BEGIN(c, n)
+#define MTR_END(c, n)
+#define MTR_SCOPE(c, n)
+#define MTR_START(c, n, id)
+#define MTR_STEP(c, n, id, step)
+#define MTR_FINISH(c, n, id)
+#define MTR_FLOW_START(c, n, id)
+#define MTR_FLOW_STEP(c, n, id, step)
+#define MTR_FLOW_FINISH(c, n, id)
+#define MTR_INSTANT(c, n)
+
+#define MTR_BEGIN_C(c, n, aname, astrval)
+#define MTR_END_C(c, n, aname, astrval)
+#define MTR_SCOPE_C(c, n, aname, astrval)
+
+#define MTR_BEGIN_S(c, n, aname, astrval)
+#define MTR_END_S(c, n, aname, astrval)
+#define MTR_SCOPE_S(c, n, aname, astrval)
+
+#define MTR_BEGIN_I(c, n, aname, aintval)
+#define MTR_END_I(c, n, aname, aintval)
+#define MTR_SCOPE_I(c, n, aname, aintval)
+
+#define MTR_INSTANT(c, n)
+#define MTR_INSTANT_C(c, n, aname, astrval)
+#define MTR_INSTANT_I(c, n, aname, aintval)
+
+// Counters (can't do multi-value counters yet)
+#define MTR_COUNTER(c, n, val)
+
+// Metadata. Call at the start preferably. Must be const strings.
+
+#define MTR_META_PROCESS_NAME(n)
+
+#define MTR_META_THREAD_NAME(n)
+#define MTR_META_THREAD_SORT_INDEX(i)
+
+#endif
+
+// Shortcuts for simple function timing with automatic categories and names.
+
+#define MTR_BEGIN_FUNC() MTR_BEGIN(__FILE__, __FUNCTION__)
+#define MTR_END_FUNC() MTR_END(__FILE__, __FUNCTION__)
+#define MTR_SCOPE_FUNC() MTR_SCOPE(__FILE__, __FUNCTION__)
+#define MTR_INSTANT_FUNC() MTR_INSTANT(__FILE__, __FUNCTION__)
+#define MTR_SCOPE_FUNC_LIMIT_S(l) MTRScopedTraceLimit ____mtr_scope(__FILE__, __FUNCTION__, l)
+#define MTR_SCOPE_FUNC_LIMIT_MS(l) MTRScopedTraceLimit ____mtr_scope(__FILE__, __FUNCTION__, (double)l * 0.000001)
+
+// Same, but with a single argument of the usual types.
+#define MTR_BEGIN_FUNC_S(aname, arg) MTR_BEGIN_S(__FILE__, __FUNCTION__, aname, arg)
+#define MTR_END_FUNC_S(aname, arg) MTR_END_S(__FILE__, __FUNCTION__, aname, arg)
+#define MTR_SCOPE_FUNC_S(aname, arg) MTR_SCOPE_S(__FILE__, __FUNCTION__, aname, arg)
+
+#define MTR_BEGIN_FUNC_C(aname, arg) MTR_BEGIN_C(__FILE__, __FUNCTION__, aname, arg)
+#define MTR_END_FUNC_C(aname, arg) MTR_END_C(__FILE__, __FUNCTION__, aname, arg)
+#define MTR_SCOPE_FUNC_C(aname, arg) MTR_SCOPE_C(__FILE__, __FUNCTION__, aname, arg)
+
+#define MTR_BEGIN_FUNC_I(aname, arg) MTR_BEGIN_I(__FILE__, __FUNCTION__, aname, arg)
+#define MTR_END_FUNC_I(aname, arg) MTR_END_I(__FILE__, __FUNCTION__, aname, arg)
+#define MTR_SCOPE_FUNC_I(aname, arg) MTR_SCOPE_I(__FILE__, __FUNCTION__, aname, arg)
+
+#ifdef __cplusplus
+}
+
+#ifdef MTR_ENABLED
+// These are optimized to use X events (combined B and E). Much easier to do in C++ than in C.
+class MTRScopedTrace {
+public:
+       MTRScopedTrace(const char *category, const char *name)
+               : category_(category), name_(name) {
+               start_time_ = mtr_time_s();
+       }
+       ~MTRScopedTrace() {
+               internal_mtr_raw_event(category_, name_, 'X', &start_time_);
+       }
+
+private:
+       const char *category_;
+       const char *name_;
+       double start_time_;
+};
+
+// Only outputs a block if execution time exceeded the limit.
+// TODO: This will effectively call mtr_time_s twice at the end, which is bad.
+class MTRScopedTraceLimit {
+public:
+       MTRScopedTraceLimit(const char *category, const char *name, double limit_s)
+               : category_(category), name_(name), limit_(limit_s) {
+               start_time_ = mtr_time_s();
+       }
+       ~MTRScopedTraceLimit() {
+               double end_time = mtr_time_s();
+               if (end_time - start_time_ >= limit_) {
+                       internal_mtr_raw_event(category_, name_, 'X', &start_time_);
+               }
+       }
+
+private:
+       const char *category_;
+       const char *name_;
+       double start_time_;
+       double limit_;
+};
+
+class MTRScopedTraceArg {
+public:
+       MTRScopedTraceArg(const char *category, const char *name, mtr_arg_type arg_type, const char *arg_name, void *arg_value)
+               : category_(category), name_(name) {
+               internal_mtr_raw_event_arg(category, name, 'B', 0, arg_type, arg_name, arg_value);
+       }
+       ~MTRScopedTraceArg() {
+               internal_mtr_raw_event(category_, name_, 'E', 0);
+       }
+
+private:
+       const char *category_;
+       const char *name_;
+};
+#endif
+
+#endif
+
+#endif
index 51265aa252951b1e2b22eee0f87f0cd0ffa9ecd5..aadb2ac158308ba38cd59a1074a4dd015cc3bc6f 100644 (file)
@@ -1,5 +1,5 @@
 // Copyright (C) 2002-2004 Andrew Tridgell
-// Copyright (C) 2009-2018 Joel Rosdahl
+// Copyright (C) 2009-2019 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
@@ -51,180 +51,210 @@ static format_fn format_timestamp;
 // Statistics fields in display order.
 static struct {
        enum stats stat;
-       const char *message;
+       const char *id; // for --print-stats
+       const char *message; // for --show-stats
        format_fn *format_fn; // NULL -> use plain integer format
        unsigned flags;
 } stats_info[] = {
        {
                STATS_ZEROTIMESTAMP,
+               "stats_zeroed_timestamp",
                "stats zeroed",
                format_timestamp,
                FLAG_ALWAYS
        },
        {
                STATS_CACHEHIT_DIR,
+               "direct_cache_hit",
                "cache hit (direct)",
                NULL,
                FLAG_ALWAYS
        },
        {
                STATS_CACHEHIT_CPP,
+               "preprocessed_cache_hit",
                "cache hit (preprocessed)",
                NULL,
                FLAG_ALWAYS
        },
        {
                STATS_TOCACHE,
+               "cache_miss",
                "cache miss",
                NULL,
                FLAG_ALWAYS
        },
        {
                STATS_LINK,
+               "called_for_link",
                "called for link",
                NULL,
                0
        },
        {
                STATS_PREPROCESSING,
+               "called_for_preprocessing",
                "called for preprocessing",
                NULL,
                0
        },
        {
                STATS_MULTIPLE,
+               "multiple_source_files",
                "multiple source files",
                NULL,
                0
        },
        {
                STATS_STDOUT,
+               "compiler_produced_stdout",
                "compiler produced stdout",
                NULL,
                0
        },
        {
                STATS_NOOUTPUT,
+               "compiler_produced_no_output",
                "compiler produced no output",
                NULL,
                0
        },
        {
                STATS_EMPTYOUTPUT,
+               "compiler_produced_empty_output",
                "compiler produced empty output",
                NULL,
                0
        },
        {
                STATS_STATUS,
+               "compile_failed",
                "compile failed",
                NULL,
                0
        },
        {
                STATS_ERROR,
+               "internal_error",
                "ccache internal error",
                NULL,
                0
        },
        {
                STATS_PREPROCESSOR,
+               "preprocessor_error",
                "preprocessor error",
                NULL,
                0
        },
        {
                STATS_CANTUSEPCH,
+               "could_not_use_precompiled_header",
                "can't use precompiled header",
                NULL,
                0
        },
        {
                STATS_COMPILER,
+               "could_not_find_compiler",
                "couldn't find the compiler",
                NULL,
                0
        },
        {
                STATS_MISSING,
+               "missing_cache_file",
                "cache file missing",
                NULL,
                0
        },
        {
                STATS_ARGS,
+               "bad_compiler_arguments",
                "bad compiler arguments",
                NULL,
                0
        },
        {
                STATS_SOURCELANG,
+               "unsupported_source_language",
                "unsupported source language",
                NULL,
                0
        },
        {
                STATS_COMPCHECK,
+               "compiler_check_failed",
                "compiler check failed",
                NULL,
                0
        },
        {
                STATS_CONFTEST,
+               "autoconf_test",
                "autoconf compile/link",
                NULL,
                0
        },
        {
                STATS_UNSUPPORTED_OPTION,
+               "unsupported_compiler_option",
                "unsupported compiler option",
                NULL,
                0
        },
        {
                STATS_UNSUPPORTED_DIRECTIVE,
+               "unsupported_code_directive",
                "unsupported code directive",
                NULL,
                0
        },
        {
                STATS_OUTSTDOUT,
+               "output_to_stdout",
                "output to stdout",
                NULL,
                0
        },
        {
-               STATS_DEVICE,
-               "output to a non-regular file",
+               STATS_BADOUTPUTFILE,
+               "bad_output_file",
+               "could not write to output file",
                NULL,
                0
        },
        {
                STATS_NOINPUT,
+               "no_input_file",
                "no input file",
                NULL,
                0
        },
        {
                STATS_BADEXTRAFILE,
+               "error_hashing_extra_file",
                "error hashing extra file",
                NULL,
                0
        },
        {
                STATS_NUMCLEANUPS,
+               "cleanups_performed",
                "cleanups performed",
                NULL,
                FLAG_ALWAYS
        },
        {
                STATS_NUMFILES,
+               "files_in_cache",
                "files in cache",
                NULL,
                FLAG_NOZERO|FLAG_ALWAYS
        },
        {
                STATS_TOTALSIZE,
+               "cache_size_kibibyte",
                "cache size",
                format_size_times_1024,
                FLAG_NOZERO|FLAG_ALWAYS
@@ -232,12 +262,14 @@ static struct {
        {
                STATS_OBSOLETE_MAXFILES,
                "OBSOLETE",
+               "OBSOLETE",
                NULL,
                FLAG_NOZERO|FLAG_NEVER
        },
        {
                STATS_OBSOLETE_MAXSIZE,
                "OBSOLETE",
+               "OBSOLETE",
                NULL,
                FLAG_NOZERO|FLAG_NEVER
        },
@@ -245,6 +277,7 @@ static struct {
                STATS_NONE,
                NULL,
                NULL,
+               NULL,
                0
        }
 };
@@ -267,9 +300,10 @@ static char *
 format_timestamp(uint64_t timestamp)
 {
        if (timestamp > 0) {
-               struct tm *tm = localtime((time_t *)&timestamp);
+               struct tm tm;
+               localtime_r((time_t *)&timestamp, &tm);
                char buffer[100];
-               strftime(buffer, sizeof(buffer), "%c", tm);
+               strftime(buffer, sizeof(buffer), "%c", &tm);
                return format("    %s", buffer);
        } else {
                return NULL;
@@ -321,6 +355,47 @@ init_counter_updates(void)
        }
 }
 
+static double
+stats_hit_rate(struct counters *counters)
+{
+       unsigned direct = counters->data[STATS_CACHEHIT_DIR];
+       unsigned preprocessed = counters->data[STATS_CACHEHIT_CPP];
+       unsigned hit = direct + preprocessed;
+       unsigned miss = counters->data[STATS_TOCACHE];
+       unsigned total = hit + miss;
+       return total > 0 ? (100.0 * hit) / total : 0.0;
+}
+
+static void
+stats_collect(struct counters *counters, time_t *last_updated)
+{
+       struct stat st;
+       unsigned zero_timestamp = 0;
+
+       *last_updated = 0;
+
+       // Add up the stats in each directory.
+       for (int dir = -1; dir <= 0xF; dir++) {
+               char *fname;
+
+               if (dir == -1) {
+                       fname = format("%s/stats", conf->cache_dir);
+               } else {
+                       fname = format("%s/%1x/stats", conf->cache_dir, dir);
+               }
+
+               counters->data[STATS_ZEROTIMESTAMP] = 0; // Don't add
+               stats_read(fname, counters);
+               zero_timestamp = MAX(counters->data[STATS_ZEROTIMESTAMP], zero_timestamp);
+               if (stat(fname, &st) == 0 && st.st_mtime > *last_updated) {
+                       *last_updated = st.st_mtime;
+               }
+               free(fname);
+       }
+
+       counters->data[STATS_ZEROTIMESTAMP] = zero_timestamp;
+}
+
 // Record that a number of bytes and files have been added to the cache. Size
 // is in bytes.
 void
@@ -447,43 +522,22 @@ stats_get_pending(enum stats stat)
 void
 stats_summary(void)
 {
-       struct counters *counters = counters_init(STATS_END);
-       time_t updated = 0;
-       struct stat st;
-       unsigned zero_timestamp = 0;
-
        assert(conf);
 
-       // Add up the stats in each directory.
-       for (int dir = -1; dir <= 0xF; dir++) {
-               char *fname;
-
-               if (dir == -1) {
-                       fname = format("%s/stats", conf->cache_dir);
-               } else {
-                       fname = format("%s/%1x/stats", conf->cache_dir, dir);
-               }
-
-               counters->data[STATS_ZEROTIMESTAMP] = 0; // Don't add
-               stats_read(fname, counters);
-               zero_timestamp = MAX(counters->data[STATS_ZEROTIMESTAMP], zero_timestamp);
-               if (stat(fname, &st) == 0 && st.st_mtime > updated) {
-                       updated = st.st_mtime;
-               }
-               free(fname);
-       }
-
-       counters->data[STATS_ZEROTIMESTAMP] = zero_timestamp;
+       struct counters *counters = counters_init(STATS_END);
+       time_t last_updated;
+       stats_collect(counters, &last_updated);
 
        printf("cache directory                     %s\n", conf->cache_dir);
        printf("primary config                      %s\n",
               primary_config_path ? primary_config_path : "");
        printf("secondary config      (readonly)    %s\n",
               secondary_config_path ? secondary_config_path : "");
-       if (updated) {
-               struct tm *tm = localtime(&updated);
+       if (last_updated > 0) {
+               struct tm tm;
+               localtime_r(&last_updated, &tm);
                char timestamp[100];
-               strftime(timestamp, sizeof(timestamp), "%c", tm);
+               strftime(timestamp, sizeof(timestamp), "%c", &tm);
                printf("stats updated                       %s\n", timestamp);
        }
 
@@ -510,12 +564,7 @@ stats_summary(void)
                }
 
                if (stat == STATS_TOCACHE) {
-                       unsigned direct = counters->data[STATS_CACHEHIT_DIR];
-                       unsigned preprocessed = counters->data[STATS_CACHEHIT_CPP];
-                       unsigned hit = direct + preprocessed;
-                       unsigned miss = counters->data[STATS_TOCACHE];
-                       unsigned total = hit + miss;
-                       double percent = total > 0 ? (100.0 * hit) / total : 0.0;
+                       double percent = stats_hit_rate(counters);
                        printf("cache hit rate                    %6.2f %%\n", percent);
                }
        }
@@ -532,6 +581,27 @@ stats_summary(void)
        counters_free(counters);
 }
 
+// Print machine-parsable (tab-separated) statistics counters.
+void
+stats_print(void)
+{
+       assert(conf);
+
+       struct counters *counters = counters_init(STATS_END);
+       time_t last_updated;
+       stats_collect(counters, &last_updated);
+
+       printf("stats_updated_timestamp\t%llu\n", (unsigned long long)last_updated);
+
+       for (int i = 0; stats_info[i].message; i++) {
+               if (!(stats_info[i].flags & FLAG_NEVER)) {
+                       printf("%s\t%u\n", stats_info[i].id, counters->data[stats_info[i].stat]);
+               }
+       }
+
+       counters_free(counters);
+}
+
 // Zero all the stats structures.
 void
 stats_zero(void)
index 7e2cd4775c4a8d2fcea5a906b08d2202a7146b66..4b727842fc378cf2be0d11537f853695b2d2f9d9 100644 (file)
@@ -1,5 +1,5 @@
 // Copyright (C) 2002 Andrew Tridgell
-// Copyright (C) 2009-2018 Joel Rosdahl
+// Copyright (C) 2009-2019 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
@@ -117,7 +117,6 @@ pushchar(struct hash *hash, unsigned char c)
                        }
                        len = 0;
                }
-               hash_buffer(hash, NULL, 0);
                return;
        }
 
index e442cc42b9450db343371eef9b14cfba36c060a9..233c932f4a3ddae81067eeefaf09c77158bf7a20 100644 (file)
@@ -1,5 +1,5 @@
 // Copyright (C) 2002 Andrew Tridgell
-// Copyright (C) 2009-2018 Joel Rosdahl
+// Copyright (C) 2009-2019 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
 #include <tchar.h>
 #endif
 
+// Destination for conf->log_file.
 static FILE *logfile;
-static char *logbuffer;
-static size_t logbufsize;
-static size_t logsize;
 
-#define LOGBUFSIZ 1024
+// Buffer used for logs in conf->debug mode.
+static char *debug_log_buffer;
+
+// Allocated debug_log_buffer size.
+static size_t debug_log_buffer_capacity;
+
+// The amount of log data stored in debug_log_buffer.
+static size_t debug_log_size;
+
+#define DEBUG_LOG_BUFFER_MARGIN 1024
 
 static bool
 init_log(void)
 {
        extern struct conf *conf;
 
-       if (logbuffer || logfile) {
+       if (debug_log_buffer || logfile) {
                return true;
        }
        assert(conf);
        if (conf->debug) {
-               logbufsize = LOGBUFSIZ;
-               logbuffer = x_malloc(logbufsize);
-               logsize = 0;
+               debug_log_buffer_capacity = DEBUG_LOG_BUFFER_MARGIN;
+               debug_log_buffer = x_malloc(debug_log_buffer_capacity);
+               debug_log_size = 0;
        }
        if (str_eq(conf->log_file, "")) {
                return conf->debug;
@@ -69,15 +76,15 @@ init_log(void)
 }
 
 static void
-append_log(const char *s, size_t len)
+append_to_debug_log(const char *s, size_t len)
 {
-       assert(logbuffer);
-       if (logsize + len + 1 > logbufsize) {
-               logbufsize = logbufsize + len + 1 + LOGBUFSIZ;
-               logbuffer = x_realloc(logbuffer, logbufsize);
+       assert(debug_log_buffer);
+       if (debug_log_size + len + 1 > debug_log_buffer_capacity) {
+               debug_log_buffer_capacity += len + 1 + DEBUG_LOG_BUFFER_MARGIN;
+               debug_log_buffer = x_realloc(debug_log_buffer, debug_log_buffer_capacity);
        }
-       memcpy(logbuffer + logsize, s, len);
-       logsize += len;
+       memcpy(debug_log_buffer + debug_log_size, s, len);
+       debug_log_size += len;
 }
 
 static void
@@ -87,15 +94,15 @@ log_prefix(bool log_updated_time)
 #ifdef HAVE_GETTIMEOFDAY
        if (log_updated_time) {
                char timestamp[100];
-               struct tm *tm;
+               struct tm tm;
                struct timeval tv;
                gettimeofday(&tv, NULL);
 #ifdef __MINGW64_VERSION_MAJOR
-               tm = localtime((time_t *)&tv.tv_sec);
+               localtime_r((time_t *)&tv.tv_sec, &tm);
 #else
-               tm = localtime(&tv.tv_sec);
+               localtime_r(&tv.tv_sec, &tm);
 #endif
-               strftime(timestamp, sizeof(timestamp), "%Y-%m-%dT%H:%M:%S", tm);
+               strftime(timestamp, sizeof(timestamp), "%Y-%m-%dT%H:%M:%S", &tm);
                snprintf(prefix, sizeof(prefix),
                         "[%s.%06d %-5d] ", timestamp, (int)tv.tv_usec, (int)getpid());
        }
@@ -105,8 +112,8 @@ log_prefix(bool log_updated_time)
        if (logfile) {
                fputs(prefix, logfile);
        }
-       if (logbuffer) {
-               append_log(prefix, strlen(prefix));
+       if (debug_log_buffer) {
+               append_to_debug_log(prefix, strlen(prefix));
        }
 }
 
@@ -156,11 +163,13 @@ vlog(const char *format, va_list ap, bool log_updated_time)
                        warn_log_fail();
                }
        }
-       if (logbuffer) {
-               char buf[1024];
-               size_t len = vsnprintf(buf, sizeof(buf), format, aq);
-               append_log(buf, len);
-               append_log("\n", 1);
+       if (debug_log_buffer) {
+               char buf[8192];
+               int len = vsnprintf(buf, sizeof(buf), format, aq);
+               if (len >= 0) {
+                       append_to_debug_log(buf, MIN((size_t)len, sizeof(buf) - 1));
+                       append_to_debug_log("\n", 1);
+               }
        }
        va_end(aq);
 }
@@ -206,21 +215,25 @@ cc_log_argv(const char *prefix, char **argv)
                        warn_log_fail();
                }
        }
-       if (logbuffer) {
-               append_log(prefix, strlen(prefix));
+       if (debug_log_buffer) {
+               append_to_debug_log(prefix, strlen(prefix));
                char *s = format_command(argv);
-               append_log(s, strlen(s));
+               append_to_debug_log(s, strlen(s));
                free(s);
        }
 }
 
 // Copy the current log memory buffer to an output file.
 void
-cc_dump_log_buffer(const char *path)
+cc_dump_debug_log_buffer(const char *path)
 {
        FILE *file = fopen(path, "w");
-       (void) fwrite(logbuffer, 1, logsize, file);
-       fclose(file);
+       if (file) {
+               (void) fwrite(debug_log_buffer, 1, debug_log_size, file);
+               fclose(file);
+       } else {
+               cc_log("Failed to open %s: %s", path, strerror(errno));
+       }
 }
 
 // Something went badly wrong!
@@ -229,7 +242,7 @@ fatal(const char *format, ...)
 {
        va_list ap;
        va_start(ap, format);
-       char msg[1000];
+       char msg[8192];
        vsnprintf(msg, sizeof(msg), format, ap);
        va_end(ap);
 
@@ -1210,6 +1223,17 @@ gnu_getcwd(void)
        }
 }
 
+#ifndef HAVE_LOCALTIME_R
+// localtime_r replacement.
+struct tm *
+localtime_r(const time_t *timep, struct tm *result)
+{
+       struct tm *tm = localtime(timep);
+       *result = *tm;
+       return result;
+}
+#endif
+
 #ifndef HAVE_STRTOK_R
 // strtok_r replacement.
 char *
@@ -1758,3 +1782,14 @@ set_cloexec_flag(int fd)
        (void)fd;
 #endif
 }
+
+double time_seconds(void)
+{
+#ifdef HAVE_GETTIMEOFDAY
+       struct timeval tv;
+       gettimeofday(&tv, NULL);
+       return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0;
+#else
+       return (double)time(NULL);
+#endif
+}
index 29a6c5f8425958455dde3a90ec59bd816d1ebed0..0887428a431863ec96de8f0b372a057ead61230f 100644 (file)
@@ -1 +1 @@
-extern const char CCACHE_VERSION[]; const char CCACHE_VERSION[] = "3.6";
+extern const char CCACHE_VERSION[]; const char CCACHE_VERSION[] = "3.7";
index 10666c6a4977aadd6c26c89f8eb0e430ef3561b3..b4a96b471894cf736492227a50bcfd470442a304 100755 (executable)
--- a/test/run
+++ b/test/run
@@ -3,7 +3,7 @@
 # A simple test suite for ccache.
 #
 # Copyright (C) 2002-2007 Andrew Tridgell
-# Copyright (C) 2009-2018 Joel Rosdahl
+# Copyright (C) 2009-2019 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
@@ -152,7 +152,7 @@ expect_different_files() {
     fi
 }
 
-expect_equal_object_files() {
+is_equal_object_files() {
     if $HOST_OS_LINUX && $COMPILER_TYPE_CLANG; then
         if ! which eu-elfcmp >/dev/null 2>&1; then
             test_failed "Please install elfutils to get eu-elfcmp"
@@ -166,6 +166,10 @@ expect_equal_object_files() {
     else
         cmp -s "$1" "$2"
     fi
+}
+
+expect_equal_object_files() {
+    is_equal_object_files "$1" "$2"
     if [ $? -ne 0 ]; then
         test_failed "Objects differ: $1 != $2"
     fi
@@ -193,6 +197,15 @@ expect_file_count() {
     fi
 }
 
+# Verify that $1 is newer than (or same age as) $2.
+expect_file_newer_than() {
+    local newer_file=$1
+    local older_file=$2
+    if [ "$newer_file" -ot "$older_file" ]; then
+        test_failed "$newer_file is older than $older_file"
+    fi
+}
+
 run_suite() {
     local suite_name=$1
 
@@ -375,6 +388,7 @@ multi_arch
 serialize_diagnostics
 sanitize_blacklist
 debug_prefix_map
+split_dwarf
 masquerading
 hardlink
 direct
index 212e148ff2b821e1d0218435fbeddae2c8777dc9..6fb76d84066747e90b44ae7a1d24d2f2dddf9fed 100644 (file)
@@ -125,12 +125,28 @@ base_tests() {
     expect_stat 'compiler produced stdout' 1
 
     # -------------------------------------------------------------------------
-    TEST "Output to a non-regular file"
+    TEST "Output to directory"
 
     mkdir testd
     $CCACHE_COMPILE -o testd -c test1.c >/dev/null 2>&1
     rmdir testd >/dev/null 2>&1
-    expect_stat 'output to a non-regular file' 1
+    expect_stat 'could not write to output file' 1
+
+    # -------------------------------------------------------------------------
+    TEST "Output to file in nonexistent directory"
+
+    mkdir out
+
+    $CCACHE_COMPILE -c test1.c -o out/foo.o
+    expect_stat 'could not write to output file' ""
+    expect_stat 'cache miss' 1
+
+    rm -rf out
+
+    $CCACHE_COMPILE -c test1.c -o out/foo.o 2>/dev/null
+    expect_stat 'could not write to output file' 1
+    expect_stat 'cache miss' 1
+    expect_file_missing out/foo.o
 
     # -------------------------------------------------------------------------
     TEST "No input file"
@@ -138,6 +154,66 @@ base_tests() {
     $CCACHE_COMPILE -c -O2 2>/dev/null
     expect_stat 'no input file' 1
 
+    # -------------------------------------------------------------------------
+    TEST "No file extension"
+
+    mkdir src
+    touch src/foo
+
+    $CCACHE_COMPILE -x c -c src/foo
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_file_exists foo.o
+    rm foo.o
+
+    $CCACHE_COMPILE -x c -c src/foo
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_file_exists foo.o
+    rm foo.o
+
+    rm -rf src
+
+    # -------------------------------------------------------------------------
+    TEST "Source file ending with dot"
+
+    mkdir src
+    touch src/foo.
+
+    $CCACHE_COMPILE -x c -c src/foo.
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_file_exists foo.o
+    rm foo.o
+
+    $CCACHE_COMPILE -x c -c src/foo.
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_file_exists foo.o
+    rm foo.o
+
+    rm -rf src
+
+    # -------------------------------------------------------------------------
+    TEST "Multiple file extensions"
+
+    mkdir src
+    touch src/foo.c.c
+
+    $CCACHE_COMPILE -c src/foo.c.c
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_file_exists foo.c.o
+    rm foo.c.o
+
+    $CCACHE_COMPILE -c src/foo.c.c
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+    expect_file_exists foo.c.o
+    rm foo.c.o
+
+    rm -rf src
+
     # -------------------------------------------------------------------------
     TEST "LANG"
 
@@ -274,6 +350,26 @@ base_tests() {
     expect_stat 'cache hit (preprocessed)' 2
     expect_stat 'cache miss' 1
 
+    # -------------------------------------------------------------------------
+    TEST "Directory is not hashed if using -g -g0"
+
+    mkdir dir1 dir2
+    cp test1.c dir1
+    cp test1.c dir2
+
+    cd dir1
+    $CCACHE_COMPILE -c test1.c -g -g0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    $CCACHE_COMPILE -c test1.c -g -g0
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
+    cd ../dir2
+    $CCACHE_COMPILE -c test1.c -g -g0
+    expect_stat 'cache hit (preprocessed)' 2
+    expect_stat 'cache miss' 1
+
     # -------------------------------------------------------------------------
     TEST "CCACHE_NOHASHDIR"
 
@@ -486,6 +582,17 @@ b"
     expect_stat 'cache miss' 0
     expect_stat 'unsupported source language' 1
 
+    # -------------------------------------------------------------------------
+    TEST "-x c -c /dev/null"
+
+    $CCACHE_COMPILE -x c -c /dev/null -o null.o 2>/dev/null
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+
+    $CCACHE_COMPILE -x c -c /dev/null -o null.o 2>/dev/null
+    expect_stat 'cache hit (preprocessed)' 1
+    expect_stat 'cache miss' 1
+
     # -------------------------------------------------------------------------
     TEST "-D not hashed"
 
index f59b36c4c35250fc03c9c01689d82be590970a4e..3d2f2adc1ce41b83988a063f8a041311eae875b9 100644 (file)
@@ -26,6 +26,68 @@ EOF
     DEPSFLAGS_CCACHE="-MP -MMD -MF test.d"
 }
 
+set_up_different_sets_of_headers_test() {
+    BASEDIR=$(pwd)
+    BASEDIR1="$BASEDIR/test/dir1"
+    BASEDIR2="$BASEDIR/test/dir2"
+    BASEDIR3="$BASEDIR/test/dir3"
+    BASEDIR4="$BASEDIR/test/dir4"
+
+    mkdir -p $BASEDIR1 $BASEDIR2 $BASEDIR3 $BASEDIR4
+
+    cat <<EOF >$BASEDIR1/test.c
+#include "header.h"
+#include <stdio.h>
+
+void test(){
+#ifdef CHANGE_THAT_AFFECTS_OBJECT_FILE
+printf("with change");
+#else
+printf("no change");
+#endif
+}
+EOF
+    cp -f "$BASEDIR1/test.c" $BASEDIR2
+    cp -f "$BASEDIR1/test.c" $BASEDIR3
+    cp -f "$BASEDIR1/test.c" $BASEDIR4
+
+    cat <<EOF >"$BASEDIR1/header.h"
+void test();
+EOF
+
+    cat <<EOF >"$BASEDIR2/header.h"
+#define CHANGE_THAT_AFFECTS_OBJECT_FILE
+void test();
+EOF
+
+    cat <<EOF >"$BASEDIR3/header.h"
+#define CHANGE_THAT_DOES_NOT_AFFECT_OBJECT_FILE
+void test();
+EOF
+
+    cat <<EOF >"$BASEDIR4/header.h"
+#include "header2.h"
+void test();
+EOF
+    cat <<EOF >"$BASEDIR4/header2.h"
+static void some_function(){};
+EOF
+
+    backdate "$BASEDIR1/header.h" "$BASEDIR1/test.c"
+    backdate "$BASEDIR2/header.h" "$BASEDIR2/test.c"
+    backdate "$BASEDIR3/header.h" "$BASEDIR3/test.c"
+    backdate "$BASEDIR4/header.h" "$BASEDIR4/test.c" "$BASEDIR4/header2.h"
+
+    DEPFLAGS="-MD -MF test.d"
+}
+
+generate_reference_compiler_output() {
+    rm -f *.o *.d
+    $REAL_COMPILER $DEPFLAGS -c -o test.o test.c
+    mv test.o reference_test.o
+    mv test.d reference_test.d
+}
+
 SUITE_depend() {
     # -------------------------------------------------------------------------
     TEST "Base case"
@@ -39,7 +101,6 @@ SUITE_depend() {
     expect_stat 'cache miss' 1
     expect_stat 'files in cache' 3 # .o + .manifest + .d
 
-
     CCACHE_DEPEND=1 $CCACHE_COMPILE $DEPSFLAGS_CCACHE -c test.c
     expect_equal_object_files reference_test.o test.o
     expect_stat 'cache hit (direct)' 1
@@ -66,6 +127,14 @@ SUITE_depend() {
     expect_stat 'cache miss' 1
     expect_stat 'files in cache' 3
 
+    # -------------------------------------------------------------------------
+    TEST "Dependency file paths converted to relative if CCACHE_BASEDIR specified"
+        
+    CCACHE_DEPEND=1 CCACHE_BASEDIR="`pwd`" $CCACHE_COMPILE $DEPSFLAGS_CCACHE -c "`pwd`/test.c"
+    if grep -q "[^.]/test.c" "test.d"; then
+        test_failed "Dependency file does not contain relative path to test.c"
+    fi
+
     # -------------------------------------------------------------------------
     TEST "stderr from both preprocessor and compiler"
 
@@ -92,5 +161,124 @@ EOF
     expect_stat 'cache miss' 1
     expect_file_content stderr-mf.txt "`cat stderr-baseline.txt`"
 
+    # -------------------------------------------------------------------------
+    # This test case covers a case in depend mode with unchanged source file
+    # between compilations, but with changed headers. Header contents do not
+    # affect the common hash (by which .manifest is stored in cache), only the
+    # object's hash.
+    #
+    # dir1 is baseline
+    # dir2 has a change in header which affects object file
+    # dir3 has a change in header which does not affect object file
+    # dir4 has an additional include header which should change the dependency file
+    TEST "Different sets of headers for the same source code"
+
+    set_up_different_sets_of_headers_test
+
+    # Compile dir1.
+    cd $BASEDIR1
+
+    generate_reference_compiler_output
+    CCACHE_DEPEND=1 CCACHE_BASEDIR=$BASEDIR1 $CCACHE_COMPILE $DEPFLAGS -c test.c
+    expect_equal_object_files reference_test.o test.o
+    expect_equal_files reference_test.d test.d
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 3      # .o + .manifest + .d
+
+    # Recompile dir1 first time.
+    generate_reference_compiler_output
+    CCACHE_DEPEND=1 CCACHE_BASEDIR=$BASEDIR1 $CCACHE_COMPILE $DEPFLAGS -c test.c
+    expect_equal_object_files reference_test.o test.o
+    expect_equal_files reference_test.d test.d
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 1
+    expect_stat 'files in cache' 3
+
+    # Compile dir2. dir2 header changes the object file compared to dir1.
+    cd $BASEDIR2
+    generate_reference_compiler_output
+    CCACHE_DEPEND=1 CCACHE_BASEDIR=$BASEDIR2 $CCACHE_COMPILE $DEPFLAGS -c test.c
+    expect_equal_object_files reference_test.o test.o
+    expect_equal_files reference_test.d test.d
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 2
+    expect_stat 'files in cache' 5      # 2x .o, 2x .d, 1x manifest
+
+    # Compile dir3. dir3 header change does not change object file compared to
+    # dir1, but ccache still adds an additional .o/.d file in the cache due to
+    # different contents of the header file.
+    cd $BASEDIR3
+    generate_reference_compiler_output
+    CCACHE_DEPEND=1 CCACHE_BASEDIR=$BASEDIR3 $CCACHE_COMPILE $DEPFLAGS -c test.c
+    expect_equal_object_files reference_test.o test.o
+    expect_equal_files reference_test.d test.d
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 3
+    expect_stat 'files in cache' 7      # 3x .o, 3x .d, 1x manifest
+
+    # Compile dir4. dir4 header adds a new dependency.
+    cd $BASEDIR4
+    generate_reference_compiler_output
+    CCACHE_DEPEND=1 CCACHE_BASEDIR=$BASEDIR4 $CCACHE_COMPILE $DEPFLAGS -c test.c
+    expect_equal_object_files reference_test.o test.o
+    expect_equal_files reference_test.d test.d
+    expect_different_files reference_test.d $BASEDIR1/test.d
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 4
+    expect_stat 'files in cache' 9      # 4x .o, 4x .d, 1x manifest
+
+    # Recompile dir1 second time.
+    cd $BASEDIR1
+    generate_reference_compiler_output
+    CCACHE_DEPEND=1 CCACHE_BASEDIR=$BASEDIR1 $CCACHE_COMPILE $DEPFLAGS -c test.c
+    expect_equal_object_files reference_test.o test.o
+    expect_equal_files reference_test.d test.d
+    expect_stat 'cache hit (direct)' 2
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 4
+    expect_stat 'files in cache' 9
+
+    # Recompile dir2.
+    cd $BASEDIR2
+    generate_reference_compiler_output
+    CCACHE_DEPEND=1 CCACHE_BASEDIR=$BASEDIR2 $CCACHE_COMPILE $DEPFLAGS -c test.c
+    expect_equal_object_files test.o test.o
+    expect_equal_files reference_test.d test.d
+    expect_stat 'cache hit (direct)' 3
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 4
+    expect_stat 'files in cache' 9
+
+    # Recompile dir3.
+    cd $BASEDIR3
+    generate_reference_compiler_output
+    CCACHE_DEPEND=1 CCACHE_BASEDIR=$BASEDIR3 $CCACHE_COMPILE $DEPFLAGS -c test.c
+    expect_equal_object_files reference_test.o test.o
+    expect_equal_files reference_test.d test.d
+    expect_stat 'cache hit (direct)' 4
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 4
+    expect_stat 'files in cache' 9
+
+    # Recompile dir4.
+    cd $BASEDIR4
+    generate_reference_compiler_output
+    CCACHE_DEPEND=1 CCACHE_BASEDIR=$BASEDIR4 $CCACHE_COMPILE $DEPFLAGS -c test.c
+    expect_equal_object_files reference_test.o test.o
+    expect_equal_files reference_test.d test.d
+    expect_different_files reference_test.d $BASEDIR1/test.d
+    expect_stat 'cache hit (direct)' 5
+    expect_stat 'cache hit (preprocessed)' 0
+    expect_stat 'cache miss' 4
+    expect_stat 'files in cache' 9
+
+    # -------------------------------------------------------------------------
+
     # TODO: Add more test cases (see direct.bash for inspiration)
 }
index f3025b139d8ac47c08b3da18b6accfcd1329894c..643471c1885c0724d021628b7f9567891d77c6bb 100644 (file)
@@ -36,12 +36,16 @@ SUITE_direct() {
     expect_stat 'files in cache' 2 # .o + .manifest
     expect_equal_object_files reference_test.o test.o
 
+    manifest_file=$(find $CCACHE_DIR -name '*.manifest')
+    backdate $manifest_file
+
     $CCACHE_COMPILE -c test.c
     expect_stat 'cache hit (direct)' 1
     expect_stat 'cache hit (preprocessed)' 0
     expect_stat 'cache miss' 1
     expect_stat 'files in cache' 2
     expect_equal_object_files reference_test.o test.o
+    expect_file_newer_than $manifest_file test.c
 
     # -------------------------------------------------------------------------
     TEST "Corrupt manifest file"
index bc93018572520a40c92b782d7edc721c7cb248c7..388bd1f9db251206c0a733a26d28b30ff4ded55d 100644 (file)
@@ -60,4 +60,20 @@ SUITE_hardlink() {
     expect_stat 'cache miss' 2
     expect_stat 'files in cache' 2
     expect_equal_object_files reference_test1.o test1.o
+
+    # -------------------------------------------------------------------------
+    TEST "Automake depend move"
+
+    unset CCACHE_NODIRECT
+
+    generate_code 1 test1.c
+
+    CCACHE_HARDLINK=1 CCACHE_DEPEND=1 $CCACHE_COMPILE -c -MMD -MF test1.d.tmp test1.c
+    expect_stat 'cache hit (direct)' 0
+    mv test1.d.tmp test1.d || test_failed "first mv failed"
+
+    CCACHE_HARDLINK=1 CCACHE_DEPEND=1 $CCACHE_COMPILE -c -MMD -MF test1.d.tmp test1.c
+    expect_stat 'cache hit (direct)' 1
+    mv test1.d.tmp test1.d || test_failed "second mv failed"
+
 }
diff --git a/test/suites/pch.bash~ b/test/suites/pch.bash~
deleted file mode 100644 (file)
index c098e7f..0000000
+++ /dev/null
@@ -1,585 +0,0 @@
-SUITE_pch_PROBE() {
-    touch pch.h
-    if ! $REAL_COMPILER $SYSROOT -fpch-preprocess pch.h 2>/dev/null \
-            || [ ! -f pch.h.gch ]; then
-        echo "compiler ($($COMPILER --version | head -1)) doesn't support precompiled headers"
-    fi
-}
-
-SUITE_pch_SETUP() {
-    unset CCACHE_NODIRECT
-
-    cat <<EOF >pch.c
-#include "pch.h"
-int main()
-{
-  void *p = NULL;
-  return 0;
-}
-EOF
-    cat <<EOF >pch.h
-#include <stdlib.h>
-EOF
-    backdate pch.h
-    cat <<EOF >pch2.c
-int main()
-{
-  void *p = NULL;
-  return 0;
-}
-EOF
-}
-
-SUITE_pch() {
-    # Clang and GCC handle precompiled headers similarly, but GCC is much more
-    # forgiving with precompiled headers. Both GCC and Clang keep an absolute
-    # path reference to the original file except that Clang uses that reference
-    # to validate the pch and GCC ignores the reference. Also, Clang has an
-    # additional feature: pre-tokenized headers. For these reasons, Clang
-    # should be tested differently from GCC. Clang can only use pch or pth
-    # headers on the command line and not as an #include statement inside a
-    # source file.
-
-    if $COMPILER_TYPE_CLANG; then
-        pch_suite_clang
-    else
-        pch_suite_gcc
-    fi
-}
-
-pch_suite_gcc() {
-    # -------------------------------------------------------------------------
-    TEST "Create .gch, -c, no -o, without opt-in"
-
-    $CCACHE_COMPILE $SYSROOT -c pch.h
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    expect_stat "can't use precompiled header" 1
-
-    # -------------------------------------------------------------------------
-    TEST "Create .gch, no -c, -o, without opt-in"
-
-    $CCACHE_COMPILE pch.h -o pch.gch
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    expect_stat "can't use precompiled header" 1
-
-    # -------------------------------------------------------------------------
-    TEST "Create .gch, -c, no -o, with opt-in"
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines" $CCACHE_COMPILE $SYSROOT -c pch.h
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    rm pch.h.gch
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines" $CCACHE_COMPILE $SYSROOT -c pch.h
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    if [ ! -f pch.h.gch ]; then
-        test_failed "pch.h.gch missing"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "Create .gch, no -c, -o, with opt-in"
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT pch.h -o pch.gch
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT pch.h -o pch.gch
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    if [ ! -f pch.gch ]; then
-        test_failed "pch.gch missing"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, no -fpch-preprocess, #include"
-
-    $REAL_COMPILER $SYSROOT -c pch.h
-    backdate pch.h.gch
-    rm pch.h
-
-    $CCACHE_COMPILE $SYSROOT -c pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    # Preprocessor error because GCC can't find the real include file when
-    # trying to preprocess:
-    expect_stat 'preprocessor error' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, no -fpch-preprocess, -include, no sloppiness"
-
-    $REAL_COMPILER $SYSROOT -c pch.h
-    backdate pch.h.gch
-    rm pch.h
-
-    $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    # Must enable sloppy time macros:
-    expect_stat "can't use precompiled header" 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, no -fpch-preprocess, -include, sloppiness"
-
-    $REAL_COMPILER $SYSROOT -c pch.h
-    backdate pch.h.gch
-    rm pch.h
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, -fpch-preprocess, #include, no sloppiness"
-
-    $REAL_COMPILER $SYSROOT -c pch.h
-    backdate pch.h.gch
-    rm pch.h
-
-    $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    # Must enable sloppy time macros:
-    expect_stat "can't use precompiled header" 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, -fpch-preprocess, #include, sloppiness"
-
-    $REAL_COMPILER $SYSROOT -c pch.h
-    backdate pch.h.gch
-    rm pch.h
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, -fpch-preprocess, #include, file changed"
-
-    $REAL_COMPILER $SYSROOT -c pch.h
-    backdate pch.h.gch
-    rm pch.h
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    echo "updated" >>pch.h.gch # GCC seems to cope with this...
-    backdate pch.h.gch
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 2
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, preprocessor mode"
-
-    $REAL_COMPILER $SYSROOT -c pch.h
-    backdate pch.h.gch
-    rm pch.h
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, preprocessor mode, file changed"
-
-    $REAL_COMPILER $SYSROOT -c pch.h
-    backdate pch.h.gch
-    rm pch.h
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    echo "updated" >>pch.h.gch # GCC seems to cope with this...
-    backdate pch.h.gch
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "Create and use .gch directory"
-
-    mkdir pch.h.gch
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -x c-header -c pch.h -o pch.h.gch/foo
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    rm pch.h.gch/foo
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -x c-header -c pch.h -o pch.h.gch/foo
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    if [ ! -f pch.h.gch/foo ]; then
-        test_failed "pch.h.gch/foo missing"
-    fi
-
-    backdate pch.h.gch/foo
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
-    expect_stat 'cache hit (direct)' 2
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    echo "updated" >>pch.h.gch/foo # GCC seems to cope with this...
-    backdate pch.h.gch/foo
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
-    expect_stat 'cache hit (direct)' 2
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 3
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
-    expect_stat 'cache hit (direct)' 3
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 3
-}
-
-pch_suite_clang() {
-    # -------------------------------------------------------------------------
-    TEST "Create .gch, -c, no -o, without opt-in"
-
-    $CCACHE_COMPILE $SYSROOT -c pch.h
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    expect_stat "can't use precompiled header" 1
-
-    # -------------------------------------------------------------------------
-    TEST "Create .gch, no -c, -o, without opt-in"
-
-    $CCACHE_COMPILE pch.h -o pch.gch
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    expect_stat "can't use precompiled header" 1
-
-    # -------------------------------------------------------------------------
-    TEST "Create .gch, -c, no -o, with opt-in"
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch.h
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    rm pch.h.gch
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch.h
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    if [ ! -f pch.h.gch ]; then
-        test_failed "pch.h.gch missing"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "Create .gch, no -c, -o, with opt-in"
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT pch.h -o pch.gch
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT pch.h -o pch.gch
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    if [ ! -f pch.gch ]; then
-        test_failed "pch.gch missing"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "Create .gch, include file mtime changed"
-
-    backdate test.h
-    cat <<EOF >pch2.h
-    #include <stdlib.h>
-    #include "test.h"
-EOF
-
-    # Make sure time_of_compilation is at least one second larger than the ctime
-    # of the test.h include, otherwise we might not cache its ctime/mtime.
-    sleep 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch2.h
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    touch test.h
-    sleep 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch2.h
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    $REAL_COMPILER $SYSROOT -c -include pch2.h pch2.c
-    if [ ! -f pch2.o ]; then
-        test_failed "pch.o missing"
-    fi
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch2.h
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, no -fpch-preprocess, -include, no sloppiness"
-
-    $REAL_COMPILER $SYSROOT -c pch.h
-    backdate pch.h.gch
-
-    $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c 2>/dev/null
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    # Must enable sloppy time macros:
-    expect_stat "can't use precompiled header" 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, no -fpch-preprocess, -include, sloppiness"
-
-    $REAL_COMPILER $SYSROOT -c pch.h
-    backdate pch.h.gch
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, -fpch-preprocess, -include, file changed"
-
-    $REAL_COMPILER $SYSROOT -c pch.h
-    backdate pch.h.gch
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    echo "updated" >>pch.h.gch # clang seems to cope with this...
-    backdate pch.h.gch
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, preprocessor mode"
-
-    $REAL_COMPILER $SYSROOT -c pch.h
-    backdate pch.h.gch
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .gch, preprocessor mode, file changed"
-
-    $REAL_COMPILER $SYSROOT -c pch.h
-    backdate pch.h.gch
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    echo "updated" >>pch.h.gch # clang seems to cope with this...
-    backdate pch.h.gch
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "Create .pth, -c, -o"
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch.h -o pch.h.pth
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    rm -f pch.h.pth
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c pch.h -o pch.h.pth
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-    if [ ! -f pch.h.pth ]; then
-        test_failed "pch.h.pth missing"
-    fi
-
-    # -------------------------------------------------------------------------
-    TEST "Use .pth, no -fpch-preprocess, -include, no sloppiness"
-
-    $REAL_COMPILER $SYSROOT -c pch.h -o pch.h.pth
-    backdate pch.h.pth
-
-    $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 0
-    # Must enable sloppy time macros:
-    expect_stat "can't use precompiled header" 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .pth, no -fpch-preprocess, -include, sloppiness"
-
-    $REAL_COMPILER $SYSROOT -c pch.h -o pch.h.pth
-    backdate pch.h.pth
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h pch2.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .pth, -fpch-preprocess, -include, file changed"
-
-    $REAL_COMPILER $SYSROOT -c pch.h -o pch.h.pth
-    backdate pch.h.pth
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    echo "updated" >>pch.h.pth # clang seems to cope with this...
-    backdate pch.h.pth
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 1
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    # -------------------------------------------------------------------------
-    TEST "Use .pth, preprocessor mode"
-
-    $REAL_COMPILER $SYSROOT -c pch.h -o pch.h.pth
-    backdate pch.h.pth
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 1
-
-    # -------------------------------------------------------------------------
-    TEST "Use .pth, preprocessor mode, file changed"
-
-    $REAL_COMPILER $SYSROOT -c pch.h -o pch.h.pth
-    backdate pch.h.pth
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 1
-
-    echo "updated" >>pch.h.pth # clang seems to cope with this...
-    backdate pch.h.pth
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 0
-    expect_stat 'cache miss' 2
-
-    CCACHE_NODIRECT=1 CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS pch_defines time_macros" $CCACHE_COMPILE $SYSROOT -c -include pch.h -fpch-preprocess pch.c
-    expect_stat 'cache hit (direct)' 0
-    expect_stat 'cache hit (preprocessed)' 1
-    expect_stat 'cache miss' 2
-}
diff --git a/test/suites/split_dwarf.bash b/test/suites/split_dwarf.bash
new file mode 100644 (file)
index 0000000..54a8576
--- /dev/null
@@ -0,0 +1,120 @@
+SUITE_split_dwarf_PROBE() {
+    touch test.c
+    if ! $REAL_COMPILER -c -gsplit-dwarf test.c 2>/dev/null || [ ! -e test.dwo ]; then
+        echo "-gsplit-dwarf not supported by compiler"
+    fi
+}
+
+
+SUITE_split_dwarf_SETUP() {
+    unset CCACHE_NODIRECT
+
+    mkdir -p dir1/src dir1/include
+    cat <<EOF >dir1/src/test.c
+#include <stdarg.h>
+#include <test.h>
+EOF
+    cat <<EOF >dir1/include/test.h
+int test;
+EOF
+    cp -r dir1 dir2
+    backdate dir1/include/test.h dir2/include/test.h
+}
+
+SUITE_split_dwarf() {
+    # -------------------------------------------------------------------------
+    TEST "Directory is hashed if using -gsplit-dwarf"
+
+    cd dir1
+    $CCACHE_COMPILE -I$(pwd)/include -c src/test.c -gsplit-dwarf
+    expect_stat 'cache hit (direct)' 0
+    expect_stat 'cache miss' 1
+    $CCACHE_COMPILE -I$(pwd)/include -c src/test.c -gsplit-dwarf
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache miss' 1
+
+    cd ../dir2
+    $CCACHE_COMPILE -I$(pwd)/include -c src/test.c -gsplit-dwarf
+    expect_stat 'cache hit (direct)' 1
+    expect_stat 'cache miss' 2
+    $CCACHE_COMPILE -I$(pwd)/include -c src/test.c -gsplit-dwarf
+    expect_stat 'cache hit (direct)' 2
+    expect_stat 'cache miss' 2
+
+    # -------------------------------------------------------------------------
+    TEST "Output filename is hashed if using -gsplit-dwarf"
+
+    cd dir1
+
+    $REAL_COMPILER -I$(pwd)/include -c src/test.c -o test.o -gsplit-dwarf
+    mv test.o reference.o
+    mv test.dwo reference.dwo
+
+    $REAL_COMPILER -I$(pwd)/include -c src/test.c -o test.o -gsplit-dwarf
+    mv test.o reference2.o
+    mv test.dwo reference2.dwo
+
+    if is_equal_object_files reference.o reference2.o; then
+        $CCACHE_COMPILE -I$(pwd)/include -c src/test.c -o test.o -gsplit-dwarf
+        expect_equal_object_files reference.o test.o
+        expect_equal_object_files reference.dwo test.dwo
+        expect_stat 'cache hit (direct)' 0
+        expect_stat 'cache hit (preprocessed)' 0
+        expect_stat 'cache miss' 1
+        expect_stat 'files in cache' 3
+
+        $CCACHE_COMPILE -I$(pwd)/include -c src/test.c -o test.o -gsplit-dwarf
+        expect_equal_object_files reference.o test.o
+        expect_equal_object_files reference.dwo test.dwo
+        expect_stat 'cache hit (direct)' 1
+        expect_stat 'cache hit (preprocessed)' 0
+        expect_stat 'cache miss' 1
+        expect_stat 'files in cache' 3
+
+        $REAL_COMPILER -I$(pwd)/include -c src/test.c -o test2.o -gsplit-dwarf
+        mv test2.o reference2.o
+        mv test2.dwo reference2.dwo
+
+        $CCACHE_COMPILE -I$(pwd)/include -c src/test.c -o test2.o -gsplit-dwarf
+        expect_equal_object_files reference2.o test2.o
+        expect_equal_object_files reference2.dwo test2.dwo
+        expect_stat 'cache hit (direct)' 1
+        expect_stat 'cache hit (preprocessed)' 0
+        expect_stat 'cache miss' 2
+        expect_stat 'files in cache' 6
+
+        $CCACHE_COMPILE -I$(pwd)/include -c src/test.c -o test2.o -gsplit-dwarf
+        expect_equal_object_files reference2.o test2.o
+        expect_equal_object_files reference2.dwo test2.dwo
+        expect_stat 'cache hit (direct)' 2
+        expect_stat 'cache hit (preprocessed)' 0
+        expect_stat 'cache miss' 2
+        expect_stat 'files in cache' 6
+    fi
+    # Else: Compiler does not produce stable object file output when compiling
+    # the same source to the same output filename twice (DW_AT_GNU_dwo_id
+    # differs), so we can't verify filename hashing.
+
+    # -------------------------------------------------------------------------
+    TEST "-fdebug-prefix-map and -gsplit-dwarf"
+
+    cd dir1
+    CCACHE_BASEDIR=$(pwd) $CCACHE_COMPILE -I$(pwd)/include -gsplit-dwarf -fdebug-prefix-map=$(pwd)=. -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' 3
+    if objdump_cmd test.o | grep_cmd "$(pwd)" >/dev/null 2>&1; then
+        test_failed "Source dir ($(pwd)) found in test.o"
+    fi
+
+    cd ../dir2
+    CCACHE_BASEDIR=$(pwd) $CCACHE_COMPILE -I$(pwd)/include -gsplit-dwarf -fdebug-prefix-map=$(pwd)=. -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' 3
+    if objdump_cmd test.o | grep_cmd "$(pwd)" >/dev/null 2>&1; then
+        test_failed "Source dir ($(pwd)) found in test.o"
+    fi
+}
index 94dc2dd491f1d1d1abb9c9300cfd61ae4fd31619..c9ae789b5b6b434d3a31251443644f4532e7fb3b 100644 (file)
@@ -125,4 +125,14 @@ TEST(dash_iframework_prefix_affects_cpp)
        CHECK(compopt_prefix_affects_cpp("-iframework"));
 }
 
+TEST(dash_analyze_too_hard)
+{
+       CHECK(compopt_too_hard("-analyze"));
+}
+
+TEST(dash_dash_analyze_too_hard)
+{
+       CHECK(compopt_too_hard("--analyze"));
+}
+
 TEST_SUITE_END
index 371a3951607e4ddd8f368a9591d469279422571a..9ef6708574256294e625b8d2f1260f73b12c4c3d 100644 (file)
@@ -203,15 +203,12 @@ TEST(conf_read_with_missing_equal_sign)
        conf_free(conf);
 }
 
-TEST(conf_read_with_bad_config_key)
+TEST(conf_read_with_unknown_config_key)
 {
        struct conf *conf = conf_create();
        char *errmsg;
        create_file("ccache.conf", "# Comment\nfoo = bar");
-       CHECK(!conf_read(conf, "ccache.conf", &errmsg));
-       CHECK_INT_EQ(errno, 0);
-       CHECK_STR_EQ_FREE2("ccache.conf:2: unknown configuration option \"foo\"",
-                          errmsg);
+       CHECK(conf_read(conf, "ccache.conf", &errmsg));
        conf_free(conf);
 }
 
@@ -392,6 +389,21 @@ TEST(conf_set_existing_value)
        CHECK_STR_EQ_FREE2("path = vanilla\nstats = chocolate\n", data);
 }
 
+TEST(conf_set_unknown_option)
+{
+       char *errmsg;
+       char *data;
+
+       create_file("ccache.conf", "path = chocolate\nstats = chocolate\n");
+       CHECKM(!conf_set_value_in_file("ccache.conf", "foo", "bar", &errmsg),
+              errmsg);
+       CHECK_STR_EQ_FREE2("unknown configuration option \"foo\"", errmsg);
+
+       data = read_text_file("ccache.conf", 0);
+       CHECK(data);
+       CHECK_STR_EQ_FREE2("path = chocolate\nstats = chocolate\n", data);
+}
+
 TEST(conf_print_existing_value)
 {
        struct conf *conf = conf_create();
index 5278560e2e32377a28c5b8f422d31e8d0f29595c..2e9502dfd2592b5185002e0b0c236b77405ab719 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2010-2018 Joel Rosdahl
+// Copyright (C) 2010-2019 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
@@ -56,6 +56,16 @@ TEST(test_vectors_from_rfc_1320_should_be_correct)
        }
 }
 
+TEST(hash_result_should_not_alter_state)
+{
+       struct hash *h = hash_init();
+       hash_string(h, "message");
+       free(hash_result(h));
+       hash_string(h, " digest");
+       CHECK_STR_EQ_FREE2("d9130a8164549fe818874806e1c7014b-14", hash_result(h));
+       hash_free(h);
+}
+
 TEST(hash_result_should_be_idempotent)
 {
        struct hash *h = hash_init();