📄 compile.c
字号:
/* -*- c-file-style: "java"; indent-tabs-mode: nil -*- * * distcc -- A simple distributed compiler system * * Copyright (C) 2002, 2003, 2004 by Martin Pool <mbp@samba.org> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */#include "config.h"#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <errno.h>#include <sys/time.h>#include "distcc.h"#include "trace.h"#include "exitcode.h"#include "util.h"#include "hosts.h"#include "bulk.h"#include "implicit.h"#include "exec.h"#include "where.h"#include "lock.h"#include "timeval.h"#include "compile.h"/** * Invoke a compiler locally. This is, obviously, the alternative to * dcc_compile_remote(). * * The server does basically the same thing, but it doesn't call this * routine because it wants to overlap execution of the compiler with * copying the input from the network. * * This routine used to exec() the compiler in place of distcc. That * is slightly more efficient, because it avoids the need to create, * schedule, etc another process. The problem is that in that case we * can't clean up our temporary files, and (not so important) we can't * log our resource usage. * * This is called with a lock on localhost already held. **/static int dcc_compile_local(char *argv[], char *input_name){ pid_t pid; int ret; int status; dcc_note_execution(dcc_hostdef_local, argv); dcc_note_state(DCC_PHASE_COMPILE, input_name, "localhost"); /* We don't do any redirection of file descriptors when running locally, * so if for example cpp is being used in a pipeline we should be fine. */ if ((ret = dcc_spawn_child(argv, &pid, NULL, NULL, NULL)) != 0) return ret; if ((ret = dcc_collect_child("cc", pid, &status))) return ret; return dcc_critique_status(status, "compile", input_name, dcc_hostdef_local, 1);}/** * Execute the commands in argv remotely or locally as appropriate. * * We may need to run cpp locally; we can do that in the background * while trying to open a remote connection. * * This function is slightly inefficient when it falls back to running * gcc locally, because cpp may be run twice. Perhaps we could adjust * the command line to pass in the .i file. On the other hand, if * something has gone wrong, we should probably take the most * conservative course and run the command unaltered. It should not * be a big performance problem because this should occur only rarely. * * @param argv Command to execute. Does not include 0='distcc'. * Treated as read-only, because it is a pointer to the program's real * argv. * * @param status On return, contains the waitstatus of the compiler or * preprocessor. This function can succeed (in running the compiler) even if * the compiler itself fails. If either the compiler or preprocessor fails, * @p status is guaranteed to hold a failure value. **/static intdcc_build_somewhere(char *argv[], int sg_level, int *status){ char *input_fname = NULL, *output_fname, *cpp_fname; char **argv_stripped; pid_t cpp_pid = 0; int cpu_lock_fd; int ret; struct dcc_hostdef *host = NULL; if (sg_level) goto run_local; /* TODO: Perhaps tidy up these gotos. */ if (dcc_scan_args(argv, &input_fname, &output_fname, &argv) != 0) { /* we need to scan the arguments even if we already know it's * local, so that we can pick up distcc client options. */ goto lock_local; }#if 0 /* turned off because we never spend long in this state. */ dcc_note_state(DCC_PHASE_STARTUP, input_fname, NULL);#endif if ((ret = dcc_pick_host_from_list(&host, &cpu_lock_fd)) != 0) { /* Doesn't happen at the moment: all failures are masked by returning localhost. */ goto fallback; } if (host->mode == DCC_MODE_LOCAL) /* We picked localhost and already have a lock on it so no * need to lock it now. */ goto run_local; if ((ret = dcc_cpp_maybe(argv, input_fname, &cpp_fname, &cpp_pid) != 0)) goto fallback; if ((ret = dcc_strip_local_args(argv, &argv_stripped))) goto fallback; /* FIXME: argv_stripped is leaked. */ if ((ret = dcc_compile_remote(argv_stripped, input_fname, cpp_fname, output_fname, cpp_pid, host, status)) != 0) { /* Returns zero if we successfully ran the compiler, even if * the compiler itself bombed out. */ goto fallback; } dcc_enjoyed_host(host); dcc_unlock(cpu_lock_fd); ret = dcc_critique_status(*status, "compile", input_fname, host, 1); if (ret < 128) /* either worked, or remote compile just simply failed, * e.g. with syntax error. don't bother retrying */ return ret; fallback: if (host) dcc_disliked_host(host); if (!dcc_getenv_bool("DISTCC_FALLBACK", 1)) { rs_log_warning("failed to distribute and fallbacks are disabled"); return ret; } /* "You guys are so lazy! Do I have to do all the work myself??" */ if (host) { rs_log(RS_LOG_WARNING|RS_LOG_NONAME, "failed to distribute %s to %s, running locally instead", input_fname ? input_fname : "(unknown)", host->hostdef_string); } else { rs_log_warning("failed to distribute, running locally instead"); } lock_local: dcc_lock_local(&cpu_lock_fd); run_local: return dcc_compile_local(argv, input_fname);}int dcc_build_somewhere_timed(char *argv[], int sg_level, int *status){ struct timeval before, after, delta; int ret; if (gettimeofday(&before, NULL)) rs_log_warning("gettimeofday failed"); ret = dcc_build_somewhere(argv, sg_level, status); if (gettimeofday(&after, NULL)) { rs_log_warning("gettimeofday failed"); } else { /* TODO: Show rate based on cpp size? Is that meaningful? */ timeval_subtract(&delta, &after, &before); rs_log(RS_LOG_INFO|RS_LOG_NONAME, "elapsed compilation time %ld.%06lds", delta.tv_sec, delta.tv_usec); } return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -