Remake
Loading...
Searching...
No Matches
Classes | Macros | Typedefs | Enumerations | Functions | Variables
remake.cpp File Reference
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/wait.h>

Go to the source code of this file.

Classes

struct  ref_ptr< T >
 
struct  ref_ptr< T >::content
 
struct  dependency_t
 
struct  status_t
 
struct  assign_t
 
struct  rule_t
 
struct  job_t
 
struct  client_t
 
struct  log
 
struct  log_auto_close
 
struct  escape_string
 
struct  generator
 
struct  variable_generator
 
struct  input_generator
 
struct  addprefix_generator
 
struct  addsuffix_generator
 

Macros

#define DEBUG   if (debug.active) debug()
 
#define DEBUG_open   log_auto_close auto_close; if (debug.active) debug(true)
 
#define DEBUG_close   if ((auto_close.still_open = false), debug.active) debug(false)
 

Typedefs

typedef int socket_t
 
typedef std::list< std::string > string_list
 
typedef std::set< std::string > string_set
 
typedef std::map< std::string, ref_ptr< dependency_t > > dependency_map
 
typedef std::map< std::string, string_listvariable_map
 
typedef std::map< std::string, status_tstatus_map
 
typedef std::map< std::string, assign_tassign_map
 
typedef std::list< rule_trule_list
 
typedef std::map< std::string, ref_ptr< rule_t > > rule_map
 
typedef std::map< int, job_tjob_map
 
typedef std::map< pid_t, intpid_job_map
 
typedef std::list< client_tclient_list
 

Enumerations

enum  { INVALID_SOCKET = -1 }
 
enum  status_e {
  Uptodate , Todo , Recheck , Running ,
  RunningRecheck , Remade , Failed
}
 
enum  {
  Unexpected = 0 , Word = 1 << 1 , Colon = 1 << 2 , Equal = 1 << 3 ,
  Dollarpar = 1 << 4 , Rightpar = 1 << 5 , Comma = 1 << 6 , Plusequal = 1 << 7 ,
  Pipe = 1 << 8
}
 
enum  input_status { Success , SyntaxError , Eof }
 

Functions

static void sigchld_handler (int)
 
static void sigint_handler (int)
 
static std::ostream & operator<< (std::ostream &out, escape_string const &se)
 
static void init_working_dir ()
 
static void init_prefix_dir ()
 
static std::string normalize_abs (std::string const &s, std::string const &p)
 
static std::string normalize (std::string const &s, std::string const &w, std::string const &p)
 
static void normalize_list (string_list &l, std::string const &w, std::string const &p)
 
static void skip_spaces (std::istream &in)
 
static void skip_empty (std::istream &in)
 
static bool skip_eol (std::istream &in, bool multi=false)
 
static int expect_token (std::istream &in, int mask)
 
static std::string read_word (std::istream &in, bool detect_equal=true)
 
static generatorget_function (input_generator const &, std::string const &)
 
static bool read_words (input_generator &in, string_list &res)
 
static bool read_words (std::istream &in, string_list &res)
 
static void load_dependencies (std::istream &in)
 
static void load_dependencies ()
 
static void save_dependencies ()
 
static void merge_rule (rule_t &dest, rule_t const &src)
 
static void instantiate_rule (std::string const &target, rule_t const &src, rule_t &dst)
 
static void register_transparent_rule (rule_t const &rule, string_list const &targets)
 
static void register_scripted_rule (rule_t const &rule)
 
static void register_rule (rule_t const &rule)
 
static void load_rule (std::istream &in, std::string const &first)
 
static void load_rules (std::string const &remakefile)
 
static void substitute_pattern (std::string const &pat, string_list const &src, string_list &dst)
 
static void find_generic_rule (job_t &job, std::string const &target)
 
static void find_rule (job_t &job, std::string const &target)
 
static status_t constget_status (std::string const &target)
 
static void update_status (std::string const &target)
 
static bool still_need_rebuild (std::string const &target)
 
static void complete_job (int job_id, bool success, bool started=true)
 
static std::string prepare_script (job_t const &job)
 
static status_e run_script (int job_id, job_t const &job)
 
static status_e start (std::string const &target, client_list::iterator &current)
 
static void complete_request (client_t &client, bool success)
 
static bool has_free_slots ()
 
static bool handle_clients ()
 
static void create_server ()
 
static void accept_client ()
 
static void finalize_job (pid_t pid, bool res)
 
static void server_loop ()
 
static void server_mode (std::string const &remakefile, string_list const &targets)
 
static void client_mode (char *socket_name, string_list const &targets)
 
static void usage (int exit_status)
 
int main (int argc, char *argv[])
 

Variables

char ** environ
 
static variable_map variables
 
static dependency_map dependencies
 
static status_map status
 
static rule_list generic_rules
 
static rule_map specific_rules
 
static job_map jobs
 
static pid_job_map job_pids
 
static client_list clients
 
static int max_active_jobs = 1
 
static bool keep_going = false
 
static int running_jobs = 0
 
static int waiting_jobs = 0
 
static int job_counter = 0
 
static socket_t socket_fd
 
static bool build_failure
 
static charsocket_name
 
static std::string first_target
 
static bool show_targets = true
 
static bool echo_scripts = false
 
static time_t now = time(NULL)
 
static std::string working_dir
 
static std::string prefix_dir
 
static bool changed_prefix_dir
 
static bool propagate_vars = false
 
static bool obsolete_targets = false
 
static sigset_t old_sigmask
 
static volatile sig_atomic_t got_SIGCHLD = 0
 
static log debug
 

Macro Definition Documentation

◆ DEBUG

#define DEBUG   if (debug.active) debug()

◆ DEBUG_close

#define DEBUG_close   if ((auto_close.still_open = false), debug.active) debug(false)

◆ DEBUG_open

#define DEBUG_open   log_auto_close auto_close; if (debug.active) debug(true)

Typedef Documentation

◆ assign_map

typedef std::map<std::string, assign_t> assign_map

Definition at line 555 of file remake.cpp.

◆ client_list

Definition at line 613 of file remake.cpp.

◆ dependency_map

typedef std::map<std::string, ref_ptr<dependency_t> > dependency_map

Definition at line 517 of file remake.cpp.

◆ job_map

typedef std::map<int, job_t> job_map

Definition at line 584 of file remake.cpp.

◆ pid_job_map

Definition at line 586 of file remake.cpp.

◆ rule_list

typedef std::list<rule_t> rule_list

Definition at line 570 of file remake.cpp.

◆ rule_map

typedef std::map<std::string, ref_ptr<rule_t> > rule_map

Definition at line 572 of file remake.cpp.

◆ socket_t

Definition at line 462 of file remake.cpp.

◆ status_map

typedef std::map<std::string, status_t> status_map

Definition at line 544 of file remake.cpp.

◆ string_list

typedef std::list<std::string> string_list

Definition at line 471 of file remake.cpp.

◆ string_set

typedef std::set<std::string> string_set

Definition at line 473 of file remake.cpp.

◆ variable_map

typedef std::map<std::string, string_list> variable_map

Definition at line 519 of file remake.cpp.

Enumeration Type Documentation

◆ anonymous enum

Enumerator
INVALID_SOCKET 

Definition at line 463 of file remake.cpp.

463{ INVALID_SOCKET = -1 };
@ INVALID_SOCKET
Definition remake.cpp:463

◆ status_e

Build status of a target.

Enumerator
Uptodate 

Target is up-to-date.

Todo 

Target is missing or obsolete.

Recheck 

Target has an obsolete dependency.

Running 

Target is being rebuilt.

RunningRecheck 

Static prerequisites are being rebuilt.

Remade 

Target was successfully rebuilt.

Failed 

Build failed for target.

Definition at line 524 of file remake.cpp.

525{
526 Uptodate, ///< Target is up-to-date.
527 Todo, ///< Target is missing or obsolete.
528 Recheck, ///< Target has an obsolete dependency.
529 Running, ///< Target is being rebuilt.
530 RunningRecheck, ///< Static prerequisites are being rebuilt.
531 Remade, ///< Target was successfully rebuilt.
532 Failed ///< Build failed for target.
533};
@ Failed
Build failed for target.
Definition remake.cpp:532
@ Todo
Target is missing or obsolete.
Definition remake.cpp:527
@ Running
Target is being rebuilt.
Definition remake.cpp:529
@ Recheck
Target has an obsolete dependency.
Definition remake.cpp:528
@ Remade
Target was successfully rebuilt.
Definition remake.cpp:531
@ Uptodate
Target is up-to-date.
Definition remake.cpp:526
@ RunningRecheck
Static prerequisites are being rebuilt.
Definition remake.cpp:530

Function Documentation

◆ operator<<()

static std::ostream & operator<< ( std::ostream & out,
escape_string const & se )
static

Write the string in se to out if it does not contain any special characters, a quoted and escaped string otherwise.

Definition at line 836 of file remake.cpp.

837{
838 std::string const &s = se.input;
839 char const *quoted_char = ",: '";
840 char const *escaped_char = "\"\\$!";
841 bool need_quotes = false;
842 char *buf = NULL;
843 size_t len = s.length(), last = 0, j = 0;
844 for (size_t i = 0; i < len; ++i)
845 {
846 if (strchr(escaped_char, s[i]))
847 {
848 need_quotes = true;
849 if (!buf) buf = new char[len * 2];
850 memcpy(&buf[j], &s[last], i - last);
851 j += i - last;
852 buf[j++] = '\\';
853 buf[j++] = s[i];
854 last = i + 1;
855 }
856 if (!need_quotes && strchr(quoted_char, s[i]))
857 need_quotes = true;
858 }
859 if (!need_quotes) return out << s;
860 out << '"';
861 if (!buf) return out << s << '"';
862 out.write(buf, j);
863 out.write(&s[last], len - last);
864 delete[] buf;
865 return out << '"';
866}

◆ sigchld_handler()

static void sigchld_handler ( int )
static

Definition at line 763 of file remake.cpp.

764{
765 got_SIGCHLD = 1;
766}
static volatile sig_atomic_t got_SIGCHLD
Definition remake.cpp:761

Referenced by create_server().

◆ sigint_handler()

static void sigint_handler ( int )
static

Definition at line 768 of file remake.cpp.

769{
770 // Child processes will receive the signal too, so just prevent
771 // new jobs from starting and wait for the running jobs to fail.
772 keep_going = false;
773}
static bool keep_going
Definition remake.cpp:667

Referenced by create_server().

Variable Documentation

◆ build_failure

bool build_failure
static

Whether the request of an original client failed.

Definition at line 704 of file remake.cpp.

Referenced by complete_request(), and server_mode().

◆ changed_prefix_dir

bool changed_prefix_dir
static

Whether the prefix directory is different from working_dir.

Definition at line 746 of file remake.cpp.

Referenced by init_prefix_dir(), and server_mode().

◆ clients

client_list clients
static

List of clients waiting for a request to complete. New clients are put to front, so that the build process is depth-first.

Definition at line 655 of file remake.cpp.

Referenced by accept_client(), handle_clients(), server_loop(), server_mode(), and start().

◆ debug

log debug
static

Definition at line 803 of file remake.cpp.

Referenced by main(), and log_auto_close::~log_auto_close().

◆ dependencies

dependency_map dependencies
static

Map from targets to their known dependencies.

Definition at line 624 of file remake.cpp.

Referenced by accept_client(), get_status(), load_dependencies(), main(), register_scripted_rule(), register_transparent_rule(), run_script(), save_dependencies(), and still_need_rebuild().

◆ echo_scripts

bool echo_scripts = false
static

Whether script commands are echoed.

Definition at line 726 of file remake.cpp.

Referenced by main(), and run_script().

◆ environ

char** environ
extern

Referenced by run_script().

◆ first_target

std::string first_target
static

Name of the first target of the first specific rule, used for default run.

Definition at line 716 of file remake.cpp.

Referenced by register_rule(), and server_mode().

◆ generic_rules

rule_list generic_rules
static

Set of generic rules loaded from Remakefile.

Definition at line 634 of file remake.cpp.

Referenced by find_generic_rule(), load_rule(), and server_mode().

◆ got_SIGCHLD

volatile sig_atomic_t got_SIGCHLD = 0
static

Definition at line 761 of file remake.cpp.

Referenced by server_loop(), and sigchld_handler().

◆ job_counter

int job_counter = 0
static

Global counter used to produce increasing job numbers.

See also
jobs

Definition at line 694 of file remake.cpp.

Referenced by start().

◆ job_pids

pid_job_map job_pids
static

Map from jobs to shell pids.

Definition at line 649 of file remake.cpp.

Referenced by finalize_job(), run_script(), and server_loop().

◆ jobs

job_map jobs
static

Map of jobs being built.

Definition at line 644 of file remake.cpp.

Referenced by accept_client(), complete_job(), complete_request(), and start().

◆ keep_going

bool keep_going = false
static

Whether to keep building targets in case of failure. Can be modified by the -k option.

Definition at line 667 of file remake.cpp.

Referenced by handle_clients(), main(), and sigint_handler().

◆ max_active_jobs

int max_active_jobs = 1
static

Maximum number of parallel jobs (non-positive if unbounded). Can be modified by the -j option.

Definition at line 661 of file remake.cpp.

Referenced by has_free_slots(), and main().

◆ now

time_t now = time(NULL)
static

Time at the start of the program.

Definition at line 731 of file remake.cpp.

Referenced by update_status().

◆ obsolete_targets

bool obsolete_targets = false
static

Whether targets are unconditionally obsolete.

Definition at line 756 of file remake.cpp.

Referenced by get_status(), and main().

◆ old_sigmask

sigset_t old_sigmask
static

Definition at line 759 of file remake.cpp.

Referenced by create_server(), and run_script().

◆ prefix_dir

std::string prefix_dir
static

Directory with respect to which targets are relative.

Definition at line 741 of file remake.cpp.

Referenced by init_prefix_dir(), init_working_dir(), main(), and server_mode().

◆ propagate_vars

bool propagate_vars = false
static

Whether target-specific variables are propagated to prerequisites.

Definition at line 751 of file remake.cpp.

Referenced by accept_client(), load_rules(), and start().

◆ running_jobs

int running_jobs = 0
static

Number of jobs currently running:

  • it increases when a process is created in run_script,
  • it decreases when a completion message is received in finalize_job.
Note
There might be some jobs running while clients is empty. Indeed, if a client requested two targets to be rebuilt, if they are running concurrently, if one of them fails, the client will get a failure notice and might terminate before the other target finishes.

Definition at line 680 of file remake.cpp.

Referenced by finalize_job(), handle_clients(), has_free_slots(), and run_script().

◆ show_targets

bool show_targets = true
static

Whether a short message should be displayed for each target.

Definition at line 721 of file remake.cpp.

Referenced by complete_job(), init_prefix_dir(), main(), run_script(), and server_mode().

◆ socket_fd

socket_t socket_fd
static

Socket on which the server listens for client request.

Definition at line 699 of file remake.cpp.

Referenced by accept_client(), client_mode(), create_server(), server_loop(), and server_mode().

◆ socket_name

char* socket_name
static

Name of the server socket in the file system.

Definition at line 710 of file remake.cpp.

Referenced by client_mode(), create_server(), and server_mode().

◆ specific_rules

rule_map specific_rules
static

Map from targets to specific rules loaded from Remakefile.

Definition at line 639 of file remake.cpp.

Referenced by find_rule(), register_scripted_rule(), register_transparent_rule(), and server_mode().

◆ status

status_map status
static

Map from targets to their build status.

Definition at line 629 of file remake.cpp.

Referenced by complete_job(), get_status(), handle_clients(), load_rule(), server_loop(), server_mode(), start(), still_need_rebuild(), and update_status().

◆ variables

variable_map variables
static

Map from variable names to their content. Initialized with the values passed on the command line.

Definition at line 619 of file remake.cpp.

Referenced by client_mode(), load_rules(), main(), server_mode(), start(), and variable_generator::variable_generator().

◆ waiting_jobs

int waiting_jobs = 0
static

Number of jobs currently waiting for a build request to finish:

  • it increases when a build request is received in accept_client (since the client is presumably waiting for the reply),
  • it decreases when a reply is sent in complete_request.

Definition at line 688 of file remake.cpp.

Referenced by accept_client(), complete_request(), handle_clients(), and has_free_slots().

◆ working_dir

std::string working_dir
static

Directory with respect to which command-line names are relative.

Definition at line 736 of file remake.cpp.

Referenced by init_working_dir(), and main().