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(¤t_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