⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compile.c

📁 distcc编译器的源代码.好像是readhat公司开发的.
💻 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 + -