]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Get -fprofile-generate, -fprofile-arcs working
authorChris AtLee <catlee@mozilla.com>
Wed, 20 Jul 2011 05:55:01 +0000 (01:55 -0400)
committerChris AtLee <catlee@mozilla.com>
Wed, 20 Jul 2011 05:55:01 +0000 (01:55 -0400)
ccache.c
compopt.c
compopt.h

index ce6982f2e80291b5bb4165af53a8d8778dbcf72a..24820ac75cf0dcde2954104ce689df00be60cc64 100644 (file)
--- a/ccache.c
+++ b/ccache.c
@@ -180,6 +180,9 @@ static bool compile_preprocessed_source_code;
 /* Whether the output is a precompiled header */
 static bool output_is_precompiled_header = false;
 
+/* Whether we should output to the real object first before saving into cache */
+static bool output_to_real_object_first = false;
+
 /*
  * Whether we are using a precompiled header (either via -include or #include).
  */
@@ -558,7 +561,13 @@ to_cache(struct args *args)
        }
        tmp_stdout = format("%s.tmp.stdout.%s", cached_obj, tmp_string());
        tmp_stderr = format("%s.tmp.stderr.%s", cached_obj, tmp_string());
-       tmp_obj = format("%s.tmp.%s", cached_obj, tmp_string());
+
+       if (output_to_real_object_first) {
+               cc_log("Outputting to final destination");
+               tmp_obj = output_obj;
+       } else {
+               tmp_obj = format("%s.tmp.%s", cached_obj, tmp_string());
+       }
 
        args_add(args, "-o");
        args_add(args, tmp_obj);
@@ -639,7 +648,8 @@ to_cache(struct args *args)
                fd = open(tmp_stderr, O_RDONLY | O_BINARY);
                if (fd != -1) {
                        if (str_eq(output_obj, "/dev/null")
-                           || (access(tmp_obj, R_OK) == 0
+                           || (! output_to_real_object_first
+                                && access(tmp_obj, R_OK) == 0
                                && move_file(tmp_obj, output_obj, 0) == 0)
                            || errno == ENOENT) {
                                /* we can use a quick method of getting the failed output */
@@ -688,16 +698,22 @@ to_cache(struct args *args)
        } else {
                tmp_unlink(tmp_stderr);
        }
-       if (move_uncompressed_file(tmp_obj, cached_obj, enable_compression) != 0) {
+
+       if (output_to_real_object_first) {
+               if (copy_file(tmp_obj, cached_obj, enable_compression) != 0) {
+                       cc_log("Failed to move %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) {
                cc_log("Failed to move %s to %s: %s", tmp_obj, cached_obj, strerror(errno));
                stats_update(STATS_ERROR);
                failed();
-       } else {
-               cc_log("Stored in cache: %s", cached_obj);
-               stat(cached_obj, &st);
-               added_bytes += file_size(&st);
-               added_files += 1;
        }
+       cc_log("Stored in cache: %s", cached_obj);
+       stat(cached_obj, &st);
+       added_bytes += file_size(&st);
+       added_files += 1;
 
        /*
         * Do an extra stat on the potentially compressed object file for the
@@ -1327,6 +1343,16 @@ cc_process_args(struct args *orig_args, struct args **preprocessor_args,
                        goto out;
                }
 
+               /* We need to output to the real object first here, otherwise
+                * runtime artifacts will be produced in the wrong place. */
+               if (compopt_needs_realdir(argv[i])) {
+                       output_to_real_object_first = true;
+                       if (base_dir) {
+                               cc_log("Disabling base dir due to %s", argv[i]);
+                               base_dir = NULL;
+                       }
+               }
+
                /* These are too hard in direct mode. */
                if (enable_direct) {
                        if (compopt_too_hard_for_direct_mode(argv[i])) {
index b2d0655fe4216831ea3286052a6b724580587ac3..3e63fba980c504c8135f1a6fa574b45aad464f7e 100644 (file)
--- a/compopt.c
+++ b/compopt.c
@@ -25,6 +25,7 @@
 #define TAKES_CONCAT_ARG (1 << 3)
 #define TAKES_PATH       (1 << 4)
 #define AFFECTS_CPP      (1 << 5)
+#define NEEDS_REALDIR    (1 << 6)
 
 struct compopt {
        const char *name;
@@ -32,7 +33,7 @@ struct compopt {
 };
 
 static const struct compopt compopts[] = {
-       {"--coverage",      TOO_HARD},
+       {"--coverage",      TOO_HARD}, /* implies -ftest-coverage */
        {"--param",         TAKES_ARG},
        {"-A",              TAKES_ARG},
        {"-D",              AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG},
@@ -54,11 +55,11 @@ static const struct compopt compopts[] = {
        {"-aux-info",       TAKES_ARG},
        {"-b",              TAKES_ARG},
        {"-fbranch-probabilities", TOO_HARD},
-       {"-fprofile-arcs",  TOO_HARD},
-       {"-fprofile-generate", TOO_HARD},
+       {"-fprofile-arcs",  NEEDS_REALDIR},
+       {"-fprofile-generate", NEEDS_REALDIR},
        {"-fprofile-use",   TOO_HARD},
        {"-frepo",          TOO_HARD},
-       {"-ftest-coverage", TOO_HARD},
+       {"-ftest-coverage", TOO_HARD}, /* generates a .gcno file at the same time */
        {"-idirafter",      AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
        {"-iframework",     AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH},
        {"-imacros",        AFFECTS_CPP | TAKES_ARG | TAKES_PATH},
@@ -156,3 +157,10 @@ compopt_takes_arg(const char *option)
        const struct compopt *co = find(option);
        return co && (co->type & TAKES_ARG);
 }
+
+bool
+compopt_needs_realdir(const char *option)
+{
+       const struct compopt *co = find(option);
+       return co && (co->type & NEEDS_REALDIR);
+}
index 8985ac3d7853781e36d1ab8ebfde56ce3c24286e..5e64d7e5cbec69c15ed86b17ad1f9f348aeb5d5d 100644 (file)
--- a/compopt.h
+++ b/compopt.h
@@ -9,5 +9,6 @@ bool compopt_too_hard(const char *option);
 bool compopt_too_hard_for_direct_mode(const char *option);
 bool compopt_takes_path(const char *option);
 bool compopt_takes_arg(const char *option);
+bool compopt_needs_realdir(const char *option);
 
 #endif /* CCACHE_COMPOPT_H */