Author: vasi
Date: Wed Oct  4 18:23:27 2006
New Revision: 81

URL: 
<http://svn.finkproject.org/websvn/listing.php?sc=1&rev=81&repname=user%3a+vasi>
Log:
add multiarch

Modified:
    ccache-multiarch/trunk/ccache.c
    ccache-multiarch/trunk/execute.c

Modified: ccache-multiarch/trunk/ccache.c
URL: 
<http://svn.finkproject.org/websvn/diff.php?path=/ccache-multiarch/trunk/ccache.c&rev=81&repname=user%3a+vasi>
==============================================================================
--- ccache-multiarch/trunk/ccache.c (original)
+++ ccache-multiarch/trunk/ccache.c Wed Oct  4 18:23:27 2006
@@ -38,9 +38,6 @@
 /* the original argument list */
 static ARGS *orig_args;
 
-/* the output filename being compiled to */
-static char *output_file;
-
 /* the source file */
 static char *input_file;
 
@@ -64,6 +61,21 @@
 
 /* can we safely use the unification hashing backend? */
 static int enable_unify;
+
+
+/* A list of requested architectures */
+static ARGS *arches = NULL;
+
+/* Intermediate per-arch output files */
+static ARGS *arch_outs = NULL;
+
+/* Final output file, may be multi-arch */
+static const char *final_out = NULL;
+
+/* The output filename being used for the current arch, may be intermediate */
+static char *current_out = NULL;
+
+
 
 /* a list of supported file extensions, and the equivalent
    extension for code that has been through the pre-processor
@@ -87,12 +99,28 @@
        {"ii", "ii"},
        {NULL, NULL}};
 
+/* clean intermediate per-arch output */
+static void clean_arch_outs(void)
+{
+       if (arch_outs) {
+               int i;
+               for (i = 0; i < arch_outs->argc; ++i) {
+                       unlink(arch_outs->argv[i]);
+               }
+               /* don't worry about leaking, this function is designed to be 
called
+                  only just before we die */
+       }
+}
+
+
 /*
   something went badly wrong - just execute the real compiler
 */
 static void failed(void)
 {
        char *e;
+       
+       clean_arch_outs();
 
        /* delete intermediate pre-processor file if needed */
        if (i_tmpfile) {
@@ -128,6 +156,11 @@
        exit(1);
 }
 
+/* exit, but make sure we clean up first */
+static void safe_exit(int status) {
+       clean_arch_outs();
+       exit(status);
+}
 
 /* return a string to be used to distinguish temporary files 
    this also tries to cope with NFS by adding the local hostname 
@@ -182,7 +215,7 @@
        args_pop(args, 3);
 
        if (stat(tmp_stdout, &st1) != 0 || st1.st_size != 0) {
-               cc_log("compiler produced stdout for %s\n", output_file);
+               cc_log("compiler produced stdout for %s\n", final_out);
                stats_update(STATS_STDOUT);
                unlink(tmp_stdout);
                unlink(tmp_stderr);
@@ -193,13 +226,13 @@
 
        if (status != 0) {
                int fd;
-               cc_log("compile of %s gave status = %d\n", output_file, status);
+               cc_log("compile of %s gave status = %d\n", final_out, status);
                stats_update(STATS_STATUS);
 
                fd = open(tmp_stderr, O_RDONLY | O_BINARY);
                if (fd != -1) {
-                       if (strcmp(output_file, "/dev/null") == 0 ||
-                           rename(tmp_hashname, output_file) == 0 || errno == 
ENOENT) {
+                       if (strcmp(current_out, "/dev/null") == 0 ||
+                           rename(tmp_hashname, current_out) == 0 || errno == 
ENOENT) {
                                if (cpp_stderr) {
                                        /* we might have some stderr from cpp */
                                        int fd2 = open(cpp_stderr, O_RDONLY | 
O_BINARY);
@@ -219,7 +252,7 @@
                                if (i_tmpfile && !direct_i_file) {
                                        unlink(i_tmpfile);
                                }
-                               exit(status);
+                               safe_exit(status);
                        }
                }
                
@@ -239,7 +272,7 @@
                failed();
        }
 
-       cc_log("Placed %s into cache\n", output_file);
+       cc_log("Placed %s into cache\n", final_out);
        stats_tocache(file_size(&st1) + file_size(&st2));
 
        free(tmp_hashname);
@@ -447,10 +480,12 @@
 
 
 /* 
-   try to return the compile result from cache. If we can return from
-   cache then this function exits with the correct status code,
-   otherwise it returns */
-static void from_cache(int first)
+   try to return the compile result from cache.
+   
+   If we can use the cached value, does so and returns true.
+   Otherwise returns false.
+*/
+static int from_cache(int first)
 {
        int fd_stderr, fd_cpp_stderr;
        char *stderr_file;
@@ -462,7 +497,7 @@
        if (fd_stderr == -1) {
                /* it isn't in cache ... */
                free(stderr_file);
-               return;
+               return 0;
        }
 
        /* make sure the output is there too */
@@ -470,7 +505,7 @@
                close(fd_stderr);
                unlink(stderr_file);
                free(stderr_file);
-               return;
+               return 0;
        }
 
        /* the user might be disabling cache hits */
@@ -478,44 +513,44 @@
                close(fd_stderr);
                unlink(stderr_file);
                free(stderr_file);
-               return;
+               return 0;
        }
 
        utime(stderr_file, NULL);
 
-       if (strcmp(output_file, "/dev/null") == 0) {
+       if (strcmp(current_out, "/dev/null") == 0) {
                ret = 0;
        } else {
-               unlink(output_file);
+               unlink(current_out);
                if (getenv("CCACHE_HARDLINK")) {
-                       ret = link(hashname, output_file);
+                       ret = link(hashname, current_out);
                } else {
-                       ret = copy_file(hashname, output_file);
+                       ret = copy_file(hashname, current_out);
                }
        }
 
        /* the hash file might have been deleted by some external process */
        if (ret == -1 && errno == ENOENT) {
-               cc_log("hashfile missing for %s\n", output_file);
+               cc_log("hashfile missing for %s\n", current_out);
                stats_update(STATS_MISSING);
                close(fd_stderr);
                unlink(stderr_file);
-               return;
+               return 0;
        }
        free(stderr_file);
 
        if (ret == -1) {
-               ret = copy_file(hashname, output_file);
+               ret = copy_file(hashname, current_out);
                if (ret == -1) {
                        cc_log("failed to copy %s -> %s (%s)\n", 
-                              hashname, output_file, strerror(errno));
+                              hashname, current_out, strerror(errno));
                        stats_update(STATS_ERROR);
                        failed();
                }
        }
        if (ret == 0) {
                /* update the mtime on the file so that make doesn't get 
confused */
-               utime(output_file, NULL);
+               utime(current_out, NULL);
        }
 
        /* get rid of the intermediate preprocessor file */
@@ -541,13 +576,13 @@
        copy_fd(fd_stderr, 2);
        close(fd_stderr);
 
-       /* and exit with the right status code */
+       /* and return with true */
        if (first) {
-               cc_log("got cached result for %s\n", output_file);
+               cc_log("got cached result for %s\n", final_out);
                stats_update(STATS_CACHED);
        }
 
-       exit(0);
+       return 1;
 }
 
 /* find the real compiler. We just search the PATH to find a executable of the 
@@ -583,7 +618,7 @@
        if (!orig_args->argv[0]) {
                stats_update(STATS_COMPILER);
                perror(base);
-               exit(1);
+               safe_exit(1);
        }
 }
 
@@ -633,6 +668,16 @@
        args_add(stripped_args, argv[0]);
 
        for (i=1; i<argc; i++) {
+               /* make sure we know about all arches, then strip them */
+               if (strcmp(argv[i], "-arch") == 0) {
+                       if (!arches) {
+                               arches = args_init(0, NULL);
+                       }
+                       args_add(arches, argv[i+1]);
+                       ++i;
+                       continue;
+               }
+               
                /* some options will never work ... */
                if (strcmp(argv[i], "-E") == 0) {
                        failed();
@@ -670,14 +715,14 @@
                                stats_update(STATS_ARGS);
                                failed();
                        }
-                       output_file = argv[i+1];
+                       final_out = argv[i+1];
                        i++;
                        continue;
                }
                
                /* alternate form of -o, with no space */
                if (strncmp(argv[i], "-o", 2) == 0) {
-                       output_file = &argv[i][2];
+                       final_out = &argv[i][2];
                        continue;
                }
 
@@ -793,20 +838,20 @@
 
 
        /* don't try to second guess the compilers heuristics for stdout 
handling */
-       if (output_file && strcmp(output_file, "-") == 0) {
+       if (final_out && strcmp(final_out, "-") == 0) {
                stats_update(STATS_OUTSTDOUT);
                failed();
        }
 
-       if (!output_file) {
+       if (!final_out) {
                char *p;
-               output_file = x_strdup(input_file);
-               if ((p = strrchr(output_file, '/'))) {
-                       output_file = p+1;
-               }
-               p = strrchr(output_file, '.');
+               final_out = x_strdup(input_file);
+               if ((p = strrchr(final_out, '/'))) {
+                       final_out = p+1;
+               }
+               p = strrchr(final_out, '.');
                if (!p || !p[1]) {
-                       cc_log("badly formed output_file %s\n", output_file);
+                       cc_log("badly formed final_out %s\n", final_out);
                        stats_update(STATS_ARGS);
                        failed();
                }
@@ -815,8 +860,8 @@
        }
 
        /* cope with -o /dev/null */
-       if (strcmp(output_file,"/dev/null") != 0 && stat(output_file, &st) == 0 
&& !S_ISREG(st.st_mode)) {
-               cc_log("Not a regular file %s\n", output_file);
+       if (strcmp(final_out,"/dev/null") != 0 && stat(final_out, &st) == 0 && 
!S_ISREG(st.st_mode)) {
+               cc_log("Not a regular file %s\n", final_out);
                stats_update(STATS_DEVICE);
                failed();
        }
@@ -825,15 +870,95 @@
                char *p = find_executable(e, MYNAME);
                if (!p) {
                        perror(e);
-                       exit(1);
+                       safe_exit(1);
                }
                args_add_prefix(stripped_args, p);
        }
-}
+       
+       if (arches) {
+               /* if we have just one arch, don't do any special multi-arch 
stuff */
+               if (arches->argc == 1) {
+                       args_add(stripped_args, "-arch");
+                       args_add(stripped_args, arches->argv[0]);
+                       args_pop(arches, 1);
+                       free(arches);
+                       arches = NULL;
+               }
+       }
+}
+
+
+/* set up for a single arch */
+static void setup_arch(int i)
+{
+       if (arches) {
+               /* clean up from the last time we were called */
+               if (current_out) {
+                       free(current_out);
+                       args_pop(stripped_args, 2);
+               }
+               
+               /* set up a temporary one-arch output file */
+               x_asprintf(&current_out, "%s/tmp.archout.%s.%s", temp_dir,
+                       arches->argv[i], tmp_string());
+               if (!arch_outs) {
+                       arch_outs = args_init(0, NULL);
+               }
+               args_add(arch_outs, current_out);
+               
+               /* add the -arch argument for this step */
+               args_add(stripped_args, "-arch");
+               args_add(stripped_args, arches->argv[i]);
+       } else {
+               current_out = final_out;
+       }
+}
+
+/* merge the arches, if necessary. Exits, does not return! */
+static void merge_arches(void)
+{
+       ARGS *lipo_args;
+       const char *lipo;
+       int i;
+       
+       if (!arches) {
+               exit(0);
+       }
+       
+       /* clean up from setup_arch */
+       if (current_out) {
+               free(current_out);
+               args_pop(stripped_args, 2);
+       }
+       
+       /* find a lipo executable */
+       lipo = find_executable("lipo", "");
+       if (!lipo) {
+               cc_log("can't find lipo");
+               failed();
+       }
+       
+       /* set up args to give to lipo */
+       lipo_args = args_init(0, NULL);
+       args_add(lipo_args, lipo);
+       args_add(lipo_args, "-create");
+       args_add(lipo_args, "-output");
+       args_add(lipo_args, final_out);
+       for (i = 0; i < arch_outs->argc; ++i) {
+               args_add(lipo_args, arch_outs->argv[i]);
+       }
+       
+       /* run it, and exit */
+       unlink(final_out);
+       exit(execv(lipo, lipo_args->argv));
+}
+
 
 /* the main ccache driver function */
 static void ccache(int argc, char *argv[])
 {
+       int i;
+       
        /* find the real compiler */
        find_compiler(argc, argv);
        
@@ -850,27 +975,33 @@
        /* process argument list, returning a new set of arguments for 
pre-processing */
        process_args(orig_args->argc, orig_args->argv);
 
-       /* run with -E to find the hash */
-       find_hash(stripped_args);
-
-       /* if we can return from cache at this point then do */
-       from_cache(1);
-
-       if (getenv("CCACHE_READONLY")) {
-               cc_log("read-only set - doing real compile\n");
-               failed();
-       }
-       
-       /* run real compiler, sending output to cache */
-       to_cache(stripped_args);
-
-       /* return from cache */
-       from_cache(0);
-
-       /* oh oh! */
-       cc_log("secondary from_cache failed!\n");
-       stats_update(STATS_ERROR);
-       failed();
+       /* get intermediary files per-arch -- at least once! */
+       for (i = 0; i == 0 || (arches && i < arches->argc); ++i) {
+               setup_arch(i);
+               
+               /* run with -E to find the hash */
+               find_hash(stripped_args);
+               
+               if (from_cache(1)) continue; /* done with this step */
+               
+               if (getenv("CCACHE_READONLY")) {
+                       cc_log("read-only set - doing real compile\n");
+                       failed();
+               }
+               
+               /* run real compiler, sending output to cache */
+               to_cache(stripped_args);
+       
+               /* return from cache */
+               if (from_cache(0)) continue;
+       
+               /* oh oh! */
+               cc_log("secondary from_cache failed!\n");
+               stats_update(STATS_ERROR);
+               failed();
+       }
+       
+       merge_arches();
 }
 
 

Modified: ccache-multiarch/trunk/execute.c
URL: 
<http://svn.finkproject.org/websvn/diff.php?path=/ccache-multiarch/trunk/execute.c&rev=81&repname=user%3a+vasi>
==============================================================================
--- ccache-multiarch/trunk/execute.c (original)
+++ ccache-multiarch/trunk/execute.c Wed Oct  4 18:23:27 2006
@@ -35,22 +35,28 @@
        
        if (pid == 0) {
                int fd;
+               
+               if (path_stdout) {
+                       unlink(path_stdout);
+                       fd = open(path_stdout, 
O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY,
+                               0666);
+                       if (fd == -1) {
+                               exit(STATUS_NOCACHE);
+                       }
+                       dup2(fd, 1);
+                       close(fd);
+               }
 
-               unlink(path_stdout);
-               fd = open(path_stdout, 
O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
-               if (fd == -1) {
-                       exit(STATUS_NOCACHE);
+               if (path_stderr) {
+                       unlink(path_stderr);
+                       fd = open(path_stderr, 
O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY,
+                               0666);
+                       if (fd == -1) {
+                               exit(STATUS_NOCACHE);
+                       }
+                       dup2(fd, 2);
+                       close(fd);
                }
-               dup2(fd, 1);
-               close(fd);
-
-               unlink(path_stderr);
-               fd = open(path_stderr, 
O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
-               if (fd == -1) {
-                       exit(STATUS_NOCACHE);
-               }
-               dup2(fd, 2);
-               close(fd);
 
                exit(execv(argv[0], argv));
        }


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Fink-commits mailing list
Fink-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/fink-commits

Reply via email to