]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Don’t create missing output directory
authorJoel Rosdahl <joel@rosdahl.net>
Mon, 1 Apr 2019 19:46:21 +0000 (21:46 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Mon, 1 Apr 2019 19:46:21 +0000 (21:46 +0200)
This mimics the compiler behavior for “-o out/obj.o” when “out” doesn’t
exist.

Fixes #353.

doc/NEWS.adoc
src/ccache.c
src/ccache.h
src/stats.c
test/suites/base.bash

index 67587c56ec3fb2ddcfdde40c61cc05188282e60b..f3f6e0f59f88a98726094117973976c7174203f9 100644 (file)
@@ -18,7 +18,7 @@ Changes
 
 * Compilations with /dev/null as the input file are now cached.
 
-* ccache now knows how to contruct the object filename if no “-o” option is
+* ccache now knows 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 depend mode is enabled and the compiler
@@ -49,6 +49,9 @@ Changes
 * 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.
+
 
 ccache 3.6
 ----------
index f6562a89bbf1ac5c071e7e382e73715089284576..6bb63a013361bbe10636133bf67ddac6460c0394 100644 (file)
@@ -3294,11 +3294,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:
        //
index bdca4a514a0e357b04b6bb8ec9798c4c6706d1e8..d9acf03105428f02c27629c68a94cd4b7b44a995 100644 (file)
@@ -54,7 +54,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,
index 28392f564a667528605e0296a47ef8e4cfc09cb8..1e8e4970a21a8770a67b70662ee1834983095544 100644 (file)
@@ -218,9 +218,9 @@ static struct {
                0
        },
        {
-               STATS_DEVICE,
-               "output_to_a_non_file",
-               "output to a non-regular file",
+               STATS_BADOUTPUTFILE,
+               "bad_output_file",
+               "could not write to output file",
                NULL,
                0
        },
index eaf3e4da15f3a12837150a0b8bdd13f8584b3038..d263ea69a039f1cf5ff03fd9f379e0682fc3ed06 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"