]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Merge branch 'master' into config
authorJoel Rosdahl <joel@rosdahl.net>
Mon, 15 Aug 2011 06:26:36 +0000 (08:26 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Mon, 15 Aug 2011 06:26:36 +0000 (08:26 +0200)
* master: (22 commits)
  Add the newest contributors
  Fix potential free() of non-heap memory
  Plug minor memory leak
  Minor code-style cleanup
  Correct win32 ifndefs
  Don't crash when getcwd() fails
  rework profile directory handling
  set output_to_real_object default to false, we get errors handling hardlinks
  Using hardlinks if requested
  comment
  Make sure we only handle known -fprofile flags. Rewrite profile directory to use absolute paths on commandline to increase direct / preprocessed hit rate.
  Move -fprofile handling into cc_process_args
  Look for .gcda files in profile directory when using profile
  Fix profile_use directory, and valgrind warning
  refactor to handle profile directories
  Use hash_delimeter before hashing profile data
  Avoid output_obj being freed by accident
  Fix comment style
  Hash the cwd if we're outputting to our object file first
  handle -fprofile-use
  ...

Conflicts:
ccache.c
util.c

1  2 
ccache.c
test.sh
util.c

diff --cc ccache.c
index ddec7d1356c95ead8c91221c5f5aa0134637dd4c,339ce5fe6db2c67b81a49f76f01f4693b7ef73e8..e8ddf6c019c2020d31f7c5e744d8e5305ed38da5
+++ b/ccache.c
@@@ -665,7 -703,20 +680,20 @@@ to_cache(struct args *args
        } else {
                tmp_unlink(tmp_stderr);
        }
-       if (move_uncompressed_file(tmp_obj, cached_obj, conf->compression) != 0) {
+       if (output_to_real_object_first) {
+               int ret;
 -              if (getenv("CCACHE_HARDLINK") && !enable_compression) {
++              if (getenv("CCACHE_HARDLINK") && !conf->compression) {
+                       ret = link(tmp_obj, cached_obj);
+               } else {
 -                      ret = copy_file(tmp_obj, cached_obj, enable_compression);
++                      ret = copy_file(tmp_obj, cached_obj, conf->compression);
+               }
+               if (ret != 0) {
+                       cc_log("Failed to copy/link %s to %s: %s", tmp_obj, cached_obj, strerror(errno));
+                       stats_update(STATS_ERROR);
+                       failed();
+               }
 -      } else if (move_uncompressed_file(tmp_obj, cached_obj, enable_compression) != 0) {
++      } else if (move_uncompressed_file(tmp_obj, cached_obj, conf->compression) != 0) {
                cc_log("Failed to move %s to %s: %s", tmp_obj, cached_obj, strerror(errno));
                stats_update(STATS_ERROR);
                failed();
@@@ -972,8 -1027,54 +999,54 @@@ calculate_object_hash(struct args *args
                hash_string(hash, args->argv[i]);
        }
  
+       /*
+        * For profile generation (-fprofile-arcs, -fprofile-generate):
+        * - hash profile directory
+        * - output to the real file first
+        *
+        * For profile usage (-fprofile-use):
+        * - hash profile data
+        *
+        * -fbranch-probabilities and -fvpt usage is covered by
+        * -fprofile-generate/-fprofile-use.
+        *
+        * The profile directory can be specified as an argument to
+        * -fprofile-generate=, -fprofile-use=, or -fprofile-dir=.
+        */
+       /*
+        * We need to output to the real object first here, otherwise runtime
+        * artifacts will be produced in the wrong place.
+        */
+       if (profile_generate) {
+               output_to_real_object_first = true;
+               if (!profile_dir) {
+                       profile_dir = get_cwd();
+               }
+               cc_log("Adding profile directory %s to our hash", profile_dir);
+               hash_delimiter(hash, "-fprofile-dir");
+               hash_string(hash, profile_dir);
+       }
+       if (profile_use) {
+               /* Calculate gcda name */
+               char *gcda_name;
+               char *base_name;
+               output_to_real_object_first = true;
+               base_name = remove_extension(output_obj);
+               if (!profile_dir) {
+                       profile_dir = get_cwd();
+               }
+               gcda_name = format("%s/%s.gcda", profile_dir, base_name);
+               cc_log("Adding profile data %s to our hash", gcda_name);
+               /* Add the gcda to our hash */
+               hash_delimiter(hash, "-fprofile-use");
+               hash_file(hash, gcda_name);
+               free(base_name);
+               free(gcda_name);
+       }
        if (direct_mode) {
 -              if (!(sloppiness & SLOPPY_FILE_MACRO)) {
 +              if (!(conf->sloppiness & SLOPPY_FILE_MACRO)) {
                        /*
                         * The source code file or an include file may contain
                         * __FILE__, so make sure that the hash is unique for
@@@ -1883,10 -1933,12 +2008,12 @@@ initialize(void
  void
  cc_reset(void)
  {
 +      conf_free(conf); conf = NULL;
 +      free(primary_config_path); primary_config_path = NULL;
 +      free(secondary_config_path); secondary_config_path = NULL;
        free(current_working_dir); current_working_dir = NULL;
 -      free(cache_dir); cache_dir = NULL;
 -      cache_logfile = NULL;
 -      base_dir = NULL;
+       free(profile_dir); profile_dir = NULL;
+       args_free(orig_args); orig_args = NULL;
        free(input_file); input_file = NULL;
        free(output_obj); output_obj = NULL;
        free(output_dep); output_dep = NULL;
diff --cc test.sh
Simple merge
diff --cc util.c
index 9f266348dc67eb581d5caae778359c46dfcfe8f1,e2f6e2169be5ebd0cd1e9cac368a08836ff62389..2ea31b40b50a1ba8a5882b28c6d0c71d17355d2c
--- 1/util.c
--- 2/util.c
+++ b/util.c
@@@ -100,30 -95,10 +100,31 @@@ path_max(const char *path
        }
  #endif
  }
+ #endif /* !_WIN32 */
  
 +static void
 +vlog(const char *format, va_list ap, bool log_updated_time)
 +{
 +      if (!init_log()) {
 +              return;
 +      }
 +
 +      log_prefix(log_updated_time);
 +      vfprintf(logfile, format, ap);
 +      fprintf(logfile, "\n");
 +}
 +
  /*
 - * Write a message to the CCACHE_LOGFILE location (adding a newline).
 + * Write a message to the log file (adding a newline) and flush.
 + */
 +void
 +cc_vlog(const char *format, va_list ap)
 +{
 +      vlog(format, ap, true);
 +}
 +
 +/*
 + * Write a message to the log file (adding a newline) and flush.
   */
  void
  cc_log(const char *format, ...)
@@@ -867,70 -829,34 +868,71 @@@ format_human_readable_size(uint64_t v
        return s;
  }
  
 -/* return a value in multiples of 1024 give a string that can end
 -   in K, M or G
 -*/
 -size_t
 -value_units(const char *s)
 +/* Format a size as a parsable string. Caller frees. */
 +char *
 +format_parsable_size_with_suffix(uint64_t size)
  {
 -      char m;
 -      double v = atof(s);
 -      m = s[strlen(s)-1];
 -      switch (m) {
 -      case 'G':
 -      case 'g':
 -      default:
 -              v *= 1024*1024;
 -              break;
 -      case 'M':
 -      case 'm':
 -              v *= 1024;
 -              break;
 -      case 'K':
 -      case 'k':
 -              v *= 1;
 -              break;
 -      }
 -      return (size_t)v;
 +      char *s;
 +      if (size >= 1000*1000*1000) {
 +              s = format("%.1fG", size / ((double)(1000*1000*1000)));
 +      } else if (size >= 1000*1000) {
 +              s = format("%.1fM", size / ((double)(1000*1000)));
 +      } else if (size >= 1000) {
 +              s = format("%.1fk", size / ((double)(1000)));
 +      } else {
 +              s = format("%u", (unsigned)size);
 +      }
 +      return s;
 +}
 +
 +/*
 + * Parse a "size value", i.e. a string that can end in k, M, G, T (10-based
 + * suffixes) or Ki, Mi, Gi, Ti (2-based suffixes). For backward compatibility,
 + * K is also recognized as a synonym of k.
 + */
 +bool
 +parse_size_with_suffix(const char *str, uint64_t *size)
 +{
 +      char *p;
 +      double x;
 +
 +      errno = 0;
 +      x = strtod(str, &p);
 +      if (errno != 0 || x < 0 || p == str || *str == '\0') {
 +              return false;
 +      }
 +
 +      while (isspace(*p)) {
 +              ++p;
 +      }
 +
 +      if (*p != '\0') {
 +              unsigned multiplier;
 +              if (*(p+1) == 'i') {
 +                      multiplier = 1024;
 +              } else {
 +                      multiplier = 1000;
 +              }
 +              switch (*p) {
 +              case 'T':
 +                      x *= multiplier;
 +              case 'G':
 +                      x *= multiplier;
 +              case 'M':
 +                      x *= multiplier;
 +              case 'K':
 +              case 'k':
 +                      x *= multiplier;
 +                      break;
 +              default:
 +                      return false;
 +              }
 +      }
 +      *size = x;
 +      return true;
  }
  
+ #ifndef _WIN32
  /*
    a sane realpath() function, trying to cope with stupid path limits and
    a broken API