2 @mainpage Remake, a build system that bridges the gap between make and redo.
4 As with <b>make</b>, <b>remake</b> uses a centralized rule file, which is
5 named <b>Remakefile</b>. It contains rules with a <em>make</em>-like
9 target1 target2 ... : prerequisite1 prerequisite2 ...
15 A target is known to be up-to-date if all its prerequisites are. If it
16 has no known prerequisites yet the file already exits, it is assumed to
17 be up-to-date. Obsolete targets are rebuilt thanks to the shell script
20 As with <b>redo</b>, <b>remake</b> supports dynamic dependencies in
21 addition to these static dependencies. Whenever a script executes
22 <tt>remake prerequisite4 prerequisite5 ...</tt>, these prerequisites are
23 rebuilt if they are obsolete. (So <b>remake</b> acts like
24 <b>redo-ifchange</b>.) Moreover, all the dependencies are stored in file
25 <b>.remake</b> so that they are remembered in subsequent runs. Note that
26 dynamic dependencies from previous runs are only used to decide whether a
27 target is obsolete; they are not automatically rebuilt when they are
28 obsolete yet a target depends on them. They will only be rebuilt once the
29 dynamic call to <b>remake</b> is executed.
31 In other words, the following two rules have almost the same behavior.
34 target1 target2 ... : prerequisite1 prerequisite2 ...
38 remake prerequisite1 prerequisite2 ...
42 (There is a difference if the targets already exist, have never been
43 built before, and the prerequisites are either younger or obsolete, since
44 the targets will not be rebuilt in the second case.)
46 The above usage of dynamic dependencies is hardly useful. Their strength
47 lies in the fact that they can be computed on the fly:
51 gcc -MMD -MF $@.d -o $@ -c $<
56 ocamldep $< | remake -r $@
59 after.xml: before.xml rules.xsl
60 xsltproc --load-trace -o after.xml rules.xsl before.xml 2> deps
61 remake `sed -n -e "\\,//,! s,^.*URL=\"\\([^\"]*\\).*\$,\\1,p" deps`
65 Note that the first rule fails if any of the header files included by
66 a C source file has to be automatically generated. In that case, one
67 should perform a first call to <b>remake</b> them before calling the
68 compiler. (Dependencies from several calls to <b>remake</b> are
69 cumulative, so they will all be remembered the next time.)
71 \section sec-usage Usage
73 Usage: <tt>remake <i>options</i> <i>targets</i></tt>
77 - <tt>-d</tt>: Echo script commands.
78 - <tt>-f FILE</tt>: Read <tt>FILE</tt> as <b>Remakefile</b>.
79 - <tt>-j[N]</tt>, <tt>--jobs=[N]</tt>: Allow <tt>N</tt> jobs at once;
80 infinite jobs with no argument.
81 - <tt>-k</tt>, <tt>--keep-going</tt>: Keep going when some targets cannot be made.
82 - <tt>-r</tt>: Look up targets from the dependencies on standard input.
83 - <tt>-s</tt>, <tt>--silent</tt>, <tt>--quiet</tt>: Do not echo targets.
85 \section sec-syntax Syntax
87 Lines starting with a space character or a tabulation are assumed to be rule
88 scripts. They are only allowed after a rule header.
90 Lines starting with <tt>#</tt> are considered to be comments and are ignored.
91 They do interrupt rule scripts though.
93 Any other line is either a variable definition or a rule header. If such a
94 line ends with a backslash, the following line break is ignored and the line
95 extends to the next one.
97 Variable definitions are a single name followed by equal followed by a list
98 of names, possibly empty.
100 Rule headers are a nonempty list of names, followed by a colon, followed by
101 another list of names, possibly empty. Basically, the syntax of a rule is as
105 targets : prerequisites
109 List of names are space-separated sequences of names. If a name contains a
110 space character, it should be put into double quotes. Names can not be any
111 of the following special characters <tt>:$(),="</tt>. Again, quotation
112 should be used. Quotation marks can be escaped by a backslash inside
115 \subsection sec-variables Variables
117 Variables can be used to factor lists of targets or prerequisites. They are
118 expanded as they are encountered during <b>Remakefile</b> parsing.
127 Variable assignments can appear instead of prerequisites inside non-generic
128 rules with no script. They are then expanded inside the corresponding
132 foo.o: CFLAGS += -DBAR
135 gcc $(CFLAGS) -MMD -MF $@.d -o $@ -c $<
140 Note: contrarily to <b>make</b>, variable names have to be enclosed in
141 parentheses. For instance, <tt>$y</tt> is not a shorthand for <tt>\$(y)</tt> and
144 \subsection sec-autovars Automatic variables
146 The following special symbols can appear inside scripts:
148 - <tt>$<</tt> expands to the first static prerequisite of the rule.
149 - <tt>$^</tt> expands to all the static prerequisites of the rule, including
151 - <tt>$\@</tt> expands to the first target of the rule.
152 - <tt>$*</tt> expands to the string that matched <tt>%</tt> in a generic rule.
153 - <tt>$$</tt> expands to a single dollar symbol.
155 Note: contrarily to <b>make</b>, there are no corresponding variables. For
156 instance, <tt>$^</tt> is not a shorthand for <tt>$(^)</tt>. Another
157 difference is that <tt>$\@</tt> is always the first target, not the one that
160 \subsection sec-functions Built-in functions
162 <b>remake</b> also supports a few built-in functions inspired from <b>make</b>.
164 - <tt>$(addprefix <i>prefix</i>, <i>list</i>)</tt> returns the list obtained
165 by prepending its first argument to each element of its second argument.
166 - <tt>$(addsuffix <i>suffix</i>, <i>list</i>)</tt> returns the list obtained
167 by appending its first argument to each element of its second argument.
169 \subsection sec-order Order-only prerequisites
171 If the static prerequisites of a rule contain a pipe symbol, prerequisites
172 on its right do not cause the targets to become obsolete if they are newer
173 (unless they are also dynamically registered as dependencies). They are
174 meant to be used when the targets do not directly depend on them, but the
175 computation of their dynamic dependencies does.
179 gcc -MMD -MF $@.d -o $@ -c $<
183 parser.c parser.h: parser.y
184 yacc -d -o parser.c parser.y
187 \subsection sec-special-var Special variables
189 Variable <tt>.OPTIONS</tt> is handled specially. Its content enables some
190 features of <b>remake</b> that are not enabled by default.
192 - <tt>variable-propagation</tt>: When a variable is set in the prerequisite
193 part of a rule, it is propagated to the rules of all the targets this rule
194 depends on. This option also enables variables to be set on the command
195 line. Note that, as in <b>make</b>, this features introduces non-determinism:
196 the content of some variables will depend on the build order.
198 \section sec-semantics Semantics
200 \subsection src-obsolete When are targets obsolete?
202 A target is obsolete:
204 - if there is no file corresponding to the target, or to one of its siblings
205 in a multi-target rule,
206 - if any of its dynamic prerequisites from a previous run or any of its static
207 prerequisites is obsolete,
208 - if the latest file corresponding to its siblings or itself is older than any
209 of its dynamic prerequisites or static prerequisites.
211 In all the other cases, it is assumed to be up-to-date (and so are all its
212 siblings). Note that the last rule above says "latest" and not "earliest". While
213 it might cause some obsolete targets to go unnoticed in corner cases, it allows
214 for the following kind of rules:
217 config.h stamp-config_h: config.h.in config.status
218 ./config.status config.h
222 A <tt>config.status</tt> file generally does not update header files (here
223 <tt>config.h</tt>) if they would not change. As a consequence, if not for the
224 <tt>stamp-config_h</tt> file above, a header would always be considered obsolete
225 once one of its prerequisites is modified. Note that touching <tt>config.h</tt>
226 rather than <tt>stamp-config_h</tt> would defeat the point of not updating it
227 in the first place, since the program files would need to be rebuilt.
229 Once all the static prerequisites of a target have been rebuilt, <b>remake</b>
230 checks whether the target still needs to be built. If it was obsolete only
231 because its prerequisites needed to be rebuilt and none of them changed, the
232 target is assumed to be up-to-date.
234 \subsection sec-rules How are targets (re)built?
236 There are two kinds of rules. If any of the targets or prerequisites contains
237 a <tt>%</tt> character, the rule is said to be <em>generic</em>. All the
238 targets of the rule shall then contain a single <tt>%</tt> character. All the
239 other rules are said to be <em>specific</em>.
241 A rule is said to <em>match</em> a given target:
243 - if it is specific and the target appears inside its target list,
244 - if it is generic and there is a way to replace the <tt>%</tt> character
245 from one of its targets so that it matches the given target.
247 When <b>remake</b> tries to build a given target, it looks for a specific rule
248 that matches it. If there is one and its script is nonempty, it uses it to
251 Otherwise, it looks for a generic rule that matches the target. If there are
252 several matching rules, it chooses the one with the shortest pattern (and if
253 there are several ones, the earliest one). <b>remake</b> then looks for
254 specific rules that match each target of the generic rule. All the
255 prerequisites of these specific rules are added to those of the generic rule.
256 The script of the generic rule is used to build the target.
262 commands building t%1 and t2%
265 commands building t2z
269 # t2x is built by the first rule (which also builds tx1) and its prerequisites are p1, px2
270 # t2y is built by the first rule (which also builds ty1) and its prerequisites are p1, py2, p3
271 # t2z is built by the second rule and its prerequisite is p4
274 The set of rules from <b>Remakefile</b> is ill-formed:
276 - if any specific rule matching a target of the generic rule has a nonempty script,
277 - if any target of the generic rule is matched by a generic rule with a shorter pattern.
279 \section sec-compilation Compilation
281 - On Linux, MacOSX, and BSD: <tt>g++ -o remake remake.cpp</tt>
282 - On Windows: <tt>g++ -o remake.exe remake.cpp -lws2_32</tt>
284 Installing <b>remake</b> is needed only if <b>Remakefile</b> does not
285 specify the path to the executable for its recursive calls. Thanks to its
286 single source file, <b>remake</b> can be shipped inside other packages and
287 built at configuration time.
289 \section sec-differences Differences with other build systems
291 Differences with <b>make</b>:
293 - Dynamic dependencies are supported.
294 - For rules with multiple targets, the shell script is executed only once
295 and is assumed to build all the targets. There is no need for
296 convoluted rules that are robust enough for parallel builds. For generic
297 rules, this is similar to the behavior of pattern rules from <b>gmake</b>.
298 - As with <b>redo</b>, only one shell is run when executing a script,
299 rather than one per script line. Note that the shells are run with
300 option <tt>-e</tt>, thus causing them to exit as soon as an error is
302 - The prerequisites of generic rules (known as implicit rules in make lingo)
303 are not used to decide between several of them. <b>remake</b> does not
304 select one for which it could satisfy the dependencies.
305 - Variables and built-in functions are expanded as they are encountered
306 during <b>Remakefile</b> parsing.
307 - Target-specific variables are not propagated, unless specifically enabled,
308 since this causes non-deterministic builds. This is the same for variables
309 set on the command line.
311 Differences with <b>redo</b>:
313 - As with <b>make</b>, it is possible to write the following kind of rules
316 Remakefile: Remakefile.in ./config.status
317 ./config.status Remakefile
319 - If a target is already built the first time <b>remake</b> runs, it still
320 uses the static prerequisites of rules mentioning it to check whether it
321 needs to be rebuilt. It does not assume it to be up-to-date. As with
322 <b>redo</b> though, if its obsolete status would be due to a dynamic
323 prerequisite, it will go unnoticed; it should be removed beforehand.
324 - Multiple targets are supported.
325 - <b>remake</b> has almost no features: no checksum-based dependencies, no
326 compatibility with job servers, etc.
328 \section sec-limitations Limitations
330 - If a rule script calls <b>remake</b>, the current working directory should
331 be the directory containing <b>Remakefile</b> (or the working directory
332 from the original <b>remake</b> if it was called with option <b>-f</b>).
333 - As with <b>make</b>, variables passed on the command line should keep
334 the same values, to ensure deterministic builds.
335 - Some cases of ill-formed rules are not caught by <b>remake</b> and can
336 thus lead to unpredictable behaviors.
338 \section sec-links Links
340 @see http://cr.yp.to/redo.html for the philosophy of <b>redo</b> and
341 https://github.com/apenwarr/redo for an implementation and some comprehensive documentation.
343 \section sec-licensing Licensing
345 @author Guillaume Melquiond
349 This program is free software: you can redistribute it and/or modify
350 it under the terms of the GNU General Public License as published by
351 the Free Software Foundation, either version 3 of the License, or
352 (at your option) any later version.
354 This program is distributed in the hope that it will be useful,
355 but WITHOUT ANY WARRANTY; without even the implied warranty of
356 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
357 GNU General Public License for more details.
359 \section sec-internals Internals
361 The parent <b>remake</b> process acts as a server. The other ones have a
362 REMAKE_SOCKET environment variable that tells them how to contact the
363 server. They send the content of the REMAKE_JOB_ID environment variable,
364 so that the server can associate the child targets to the jobs that
365 spawned them. They then wait for completion and exit with the status
366 returned by the server. This is handled by #client_mode.
368 The server calls #load_dependencies and #save_dependencies to serialize
369 dynamic dependencies from <b>.remake</b>. It loads <b>Remakefile</b> with
370 #load_rules. It then runs #server_mode, which calls #server_loop.
372 When building a target, the following sequence of events happens:
374 - #start calls #find_rule (and #find_generic_rule) to get the rule.
375 - It then creates a pseudo-client if the rule has static dependencies, or
376 calls #run_script otherwise. In both cases, a new job is created and its
377 targets are put into #job_targets.
378 - #run_script creates a shell process and stores it in #job_pids. It
379 increases #running_jobs.
380 - The child process possibly calls <b>remake</b> with a list of targets.
381 - #accept_client receives a build request from a child process and adds
382 it to #clients. It also records the new dependencies of the job into
383 #dependencies. It increases #waiting_jobs.
384 - #handle_clients uses #get_status to look up the obsoleteness of the
386 - Once the targets of a request have been built or one of them has failed,
387 #handle_clients calls #complete_request and removes the request from
389 - If the build targets come from a pseudo-client, #complete_request calls
390 #run_script. Otherwise it sends the reply to the corresponding child
391 process and decreases #waiting_jobs.
392 - When a child process ends, #server_loop calls #finalize_job, which
393 removes the process from #job_pids, decreases #running_jobs, and calls
395 - #complete_job removes the job from #job_targets and calls #update_status
396 to change the status of the targets. It also removes the target files in
401 #define WIN32_LEAN_AND_MEAN
421 #include <sys/stat.h>
422 #include <sys/types.h>
435 #include <winsock2.h>
437 typedef SOCKET socket_t;
439 #include <sys/socket.h>
441 #include <sys/wait.h>
442 typedef int socket_t;
443 enum { INVALID_SOCKET = -1 };
444 extern char **environ;
447 #if defined(WINDOWS) || defined(MACOSX)
448 enum { MSG_NOSIGNAL = 0 };
451 typedef std::list<std::string> string_list;
453 typedef std::set<std::string> string_set;
456 * Reference-counted shared object.
457 * @note The default constructor delays the creation of the object until it
458 * is first dereferenced.
468 content(T const &t): cnt(1), val(t) {}
470 mutable content *ptr;
471 ref_ptr(): ptr(NULL) {}
472 ref_ptr(T const &t): ptr(new content(t)) {}
473 ref_ptr(ref_ptr const &p): ptr(p.ptr) { if (ptr) ++ptr->cnt; }
474 ~ref_ptr() { if (ptr && --ptr->cnt == 0) delete ptr; }
475 ref_ptr &operator=(ref_ptr const &p)
477 if (ptr == p.ptr) return *this;
478 if (ptr && --ptr->cnt == 0) delete ptr;
485 if (!ptr) ptr = new content;
488 T *operator->() const { return &**this; }
497 typedef std::map<std::string, ref_ptr<dependency_t> > dependency_map;
499 typedef std::map<std::string, string_list> variable_map;
502 * Build status of a target.
506 Uptodate, ///< Target is up-to-date.
507 Todo, ///< Target is missing or obsolete.
508 Recheck, ///< Target has an obsolete dependency.
509 Running, ///< Target is being rebuilt.
510 Remade, ///< Target was successfully rebuilt.
511 Failed ///< Build failed for target.
515 * Build status of a target.
519 status_e status; ///< Actual status.
520 time_t last; ///< Last-modified date.
523 typedef std::map<std::string, status_t> status_map;
526 * Delayed assignment to a variable.
534 typedef std::map<std::string, assign_t> assign_map;
537 * A rule loaded from Remakefile.
541 string_list targets; ///< Files produced by this rule.
542 string_list deps; ///< Dependencies used for an implicit call to remake at the start of the script.
543 string_list wdeps; ///< Like #deps, except that they are not registered as dependencies.
544 assign_map assigns; ///< Assignment of variables.
545 std::string script; ///< Shell script for building the targets.
548 typedef std::list<rule_t> rule_list;
550 typedef std::map<std::string, ref_ptr<rule_t> > rule_map;
553 * A job created from a set of rules.
558 rule_t rule; ///< Original rule.
559 std::string stem; ///< Pattern used to instantiate the generic rule, if any.
560 variable_map vars; ///< Values of local variables.
563 typedef std::map<int, job_t> job_map;
565 typedef std::map<pid_t, int> pid_job_map;
568 * Client waiting for a request to complete.
570 * There are two kinds of clients:
571 * - real clients, which are instances of remake created by built scripts,
572 * - pseudo clients, which are created by the server to build specific targets.
574 * Among pseudo clients, there are two categories:
575 * - original clients, which are created for the targets passed on the
576 * command line by the user or for the initial regeneration of the rule file,
577 * - dependency clients, which are created to handle rules that have
578 * explicit dependencies and thus to emulate a call to remake.
582 socket_t socket; ///< Socket used to reply to the client (invalid for pseudo clients).
583 int job_id; ///< Job for which the built script called remake and spawned the client (negative for original clients).
584 bool failed; ///< Whether some targets failed in mode -k.
585 string_list pending; ///< Targets not yet started.
586 string_set running; ///< Targets being built.
587 variable_map vars; ///< Variables set on request.
588 bool delayed; ///< Whether it is a dependency client and a script has to be started on request completion.
589 client_t(): socket(INVALID_SOCKET), job_id(-1), failed(false), delayed(false) {}
592 typedef std::list<client_t> client_list;
595 * Map from variable names to their content.
596 * Initialized with the values passed on the command line.
598 static variable_map variables;
601 * Map from targets to their known dependencies.
603 static dependency_map dependencies;
606 * Map from targets to their build status.
608 static status_map status;
611 * Set of generic rules loaded from Remakefile.
613 static rule_list generic_rules;
616 * Map from targets to specific rules loaded from Remakefile.
618 static rule_map specific_rules;
621 * Map of jobs being built.
626 * Map from jobs to shell pids.
628 static pid_job_map job_pids;
631 * List of clients waiting for a request to complete.
632 * New clients are put to front, so that the build process is depth-first.
634 static client_list clients;
637 * Maximum number of parallel jobs (non-positive if unbounded).
638 * Can be modified by the -j option.
640 static int max_active_jobs = 1;
643 * Whether to keep building targets in case of failure.
644 * Can be modified by the -k option.
646 static bool keep_going = false;
649 * Number of jobs currently running:
650 * - it increases when a process is created in #run_script,
651 * - it decreases when a completion message is received in #finalize_job.
653 * @note There might be some jobs running while #clients is empty.
654 * Indeed, if a client requested two targets to be rebuilt, if they
655 * are running concurrently, if one of them fails, the client will
656 * get a failure notice and might terminate before the other target
659 static int running_jobs = 0;
662 * Number of jobs currently waiting for a build request to finish:
663 * - it increases when a build request is received in #accept_client
664 * (since the client is presumably waiting for the reply),
665 * - it decreases when a reply is sent in #complete_request.
667 static int waiting_jobs = 0;
670 * Global counter used to produce increasing job numbers.
673 static int job_counter = 0;
676 * Socket on which the server listens for client request.
678 static socket_t socket_fd;
681 * Whether the request of an original client failed.
683 static bool build_failure;
687 * Name of the server socket in the file system.
689 static char *socket_name;
693 * Name of the first target of the first specific rule, used for default run.
695 static std::string first_target;
698 * Whether a short message should be displayed for each target.
700 static bool show_targets = true;
703 * Whether script commands are echoed.
705 static bool echo_scripts = false;
708 * Time at the start of the program.
710 static time_t now = time(NULL);
713 * Directory with respect to which command-line names are relative.
715 static std::string working_dir;
718 * Directory with respect to which targets are relative.
720 static std::string prefix_dir;
723 * Whether target-specific variables are propagated to prerequisites.
725 static bool propagate_vars = false;
729 * Whether to print that we changed working directory (to be nice with emacs)
731 static bool print_change_working_dir = false;
734 static volatile sig_atomic_t got_SIGCHLD = 0;
736 static void sigchld_handler(int)
741 static void sigint_handler(int)
743 // Child processes will receive the signal too, so just prevent
744 // new jobs from starting and wait for the running jobs to fail.
753 log(): active(false), open(false), depth(0)
756 std::ostream &operator()()
758 if (open) std::cerr << std::endl;
760 std::cerr << std::string(depth * 2, ' ');
764 std::ostream &operator()(bool o)
766 if (o && open) std::cerr << std::endl;
769 if (o || !open) std::cerr << std::string(depth * 2, ' ');
778 struct log_auto_close
781 log_auto_close(): still_open(true)
786 if (debug.active && still_open) debug(false) << "done\n";
790 #define DEBUG if (debug.active) debug()
791 #define DEBUG_open log_auto_close auto_close; if (debug.active) debug(true)
792 #define DEBUG_close if ((auto_close.still_open = false), debug.active) debug(false)
795 * Strong typedef for strings that need escaping.
796 * @note The string is stored as a reference, so the constructed object is
797 * meant to be immediately consumed.
801 std::string const &input;
802 escape_string(std::string const &s): input(s) {}
806 * Write the string in @a se to @a out if it does not contain any special
807 * characters, a quoted and escaped string otherwise.
809 static std::ostream &operator<<(std::ostream &out, escape_string const &se)
811 std::string const &s = se.input;
812 char const *quoted_char = ",: '";
813 char const *escaped_char = "\"\\$!";
814 bool need_quotes = false;
816 size_t len = s.length(), last = 0, j = 0;
817 for (size_t i = 0; i < len; ++i)
819 if (strchr(escaped_char, s[i]))
822 if (!buf) buf = new char[len * 2];
823 memcpy(&buf[j], &s[last], i - last);
829 if (!need_quotes && strchr(quoted_char, s[i]))
832 if (!need_quotes) return out << s;
834 if (!buf) return out << s << '"';
836 out.write(&s[last], len - last);
842 * @defgroup paths Path helpers
848 * Initialize #working_dir.
850 static void init_working_dir()
853 char *res = getcwd(buf, sizeof(buf));
856 perror("Failed to get working directory");
861 for (size_t i = 0, l = working_dir.size(); i != l; ++i)
863 if (working_dir[i] == '\\') working_dir[i] = '/';
866 prefix_dir = working_dir;
870 * Initialize #prefix_dir and switch to it.
872 static void init_prefix_dir()
874 std::string old_prefix_dir = prefix_dir;
878 if (stat((prefix_dir + "/Remakefile").c_str(), &s) == 0)
880 if (0 == chdir(prefix_dir.c_str()))
882 if (old_prefix_dir != prefix_dir)
884 std::cout << "remake: Entering directory `"
887 print_change_working_dir = true;
893 std::cerr << "Cannot change working directory to '" << prefix_dir << "'";
897 size_t pos = prefix_dir.find_last_of('/');
898 if (pos == std::string::npos)
900 std::cerr << "Failed to locate Remakefile in the current directory or one of its parents" << std::endl;
903 prefix_dir.erase(pos);
908 * Normalize an absolute path with respect to @a p.
909 * Paths outside the subtree are left unchanged.
911 static std::string normalize_abs(std::string const &s, std::string const &p)
913 size_t l = p.length();
914 if (s.compare(0, l, p)) return s;
915 size_t ll = s.length();
916 if (ll == l) return ".";
919 size_t pos = s.rfind('/', l);
920 assert(pos != std::string::npos);
921 return s.substr(pos + 1);
923 if (ll == l + 1) return ".";
924 return s.substr(l + 1);
928 * Normalize path @a s (possibly relative to @a w) with respect to @a p.
930 * - If both @a p and @a w are empty, the function just removes ".", "..", "//".
931 * - If only @a p is empty, the function returns an absolute path.
933 static std::string normalize(std::string const &s, std::string const &w, std::string const &p)
936 char const *delim = "/\\";
940 size_t pos = s.find_first_of(delim);
941 if (pos == std::string::npos && w == p) return s;
942 bool absolute = pos == 0;
943 if (!absolute && w != p && !w.empty())
944 return normalize(w + '/' + s, w, p);
945 size_t prev = 0, len = s.length();
951 std::string n = s.substr(prev, pos - prev);
954 if (!l.empty()) l.pop_back();
955 else if (!absolute && !w.empty())
956 return normalize(w + '/' + s, w, p);
962 if (pos >= len) break;
964 pos = s.find_first_of(delim, prev);
965 if (pos == std::string::npos) pos = len;
967 string_list::const_iterator i = l.begin(), i_end = l.end();
968 if (i == i_end) return absolute ? "/" : ".";
970 if (absolute) n.push_back('/');
972 for (++i; i != i_end; ++i)
977 if (absolute && !p.empty()) return normalize_abs(n, p);
982 * Normalize the content of a list of targets.
984 static void normalize_list(string_list &l, std::string const &w, std::string const &p)
986 for (string_list::iterator i = l.begin(),
987 i_end = l.end(); i != i_end; ++i)
989 *i = normalize(*i, w, p);
996 * @defgroup lexer Lexer
1004 static void skip_spaces(std::istream &in)
1007 while (strchr(" \t", (c = in.get()))) {}
1008 if (in.good()) in.putback(c);
1014 static void skip_empty(std::istream &in)
1017 while (strchr("\r\n", (c = in.get()))) {}
1018 if (in.good()) in.putback(c);
1022 * Skip end of line. If @a multi is true, skip the following empty lines too.
1023 * @return true if there was a line to end.
1025 static bool skip_eol(std::istream &in, bool multi = false)
1028 if (c == '\r') c = in.get();
1029 if (c != '\n' && in.good()) in.putback(c);
1030 if (c != '\n' && !in.eof()) return false;
1031 if (multi) skip_empty(in);
1049 * Skip spaces and peek at the next token.
1050 * If it is one of @a mask, skip it (if it is not Word) and return it.
1051 * @note For composite tokens allowed by @a mask, input characters might
1052 * have been eaten even for an Unexpected result.
1054 static int expect_token(std::istream &in, int mask)
1060 if (!in.good()) return Unexpected;
1065 case '\n': return Unexpected;
1066 case ':': tok = Colon; break;
1067 case ',': tok = Comma; break;
1068 case '=': tok = Equal; break;
1069 case ')': tok = Rightpar; break;
1070 case '|': tok = Pipe; break;
1072 if (!(mask & Dollarpar)) return Unexpected;
1075 if (in.peek() != '(') return Unexpected;
1078 if (!(mask & Plusequal)) return Unexpected;
1081 if (in.peek() != '=') return Unexpected;
1085 if (skip_eol(in)) continue;
1087 return mask & Word ? Word : Unexpected;
1089 return mask & Word ? Word : Unexpected;
1091 if (!(tok & mask)) return Unexpected;
1098 * Read a (possibly quoted) word.
1100 static std::string read_word(std::istream &in)
1104 if (!in.good()) return res;
1105 char const *separators = " \t\r\n:$(),=+\"";
1106 bool quoted = c == '"';
1109 if (strchr(separators, c))
1119 if (!in.good()) return res;
1131 if (strchr(separators, c))
1144 * @defgroup stream Token streams
1150 * Possible results from word producers.
1160 * Interface for word producers.
1164 virtual ~generator() {}
1165 virtual input_status next(std::string &) = 0;
1169 * Generator for the words of a variable.
1171 struct variable_generator: generator
1174 string_list::const_iterator vcur, vend;
1175 variable_generator(std::string const &, variable_map const *);
1176 input_status next(std::string &);
1179 variable_generator::variable_generator(std::string const &n,
1180 variable_map const *local_variables): name(n)
1182 if (local_variables)
1184 variable_map::const_iterator i = local_variables->find(name);
1185 if (i != local_variables->end())
1187 vcur = i->second.begin();
1188 vend = i->second.end();
1192 variable_map::const_iterator i = variables.find(name);
1193 if (i == variables.end()) return;
1194 vcur = i->second.begin();
1195 vend = i->second.end();
1198 input_status variable_generator::next(std::string &res)
1210 * Generator for the words of an input stream.
1212 struct input_generator
1216 variable_map const *local_variables;
1217 bool earliest_exit, done;
1218 input_generator(std::istream &i, variable_map const *lv, bool e = false)
1219 : in(i), nested(NULL), local_variables(lv), earliest_exit(e), done(false) {}
1220 input_status next(std::string &);
1221 ~input_generator() { assert(!nested); }
1224 static generator *get_function(input_generator const &, std::string const &);
1226 input_status input_generator::next(std::string &res)
1231 input_status s = nested->next(res);
1232 if (s == Success) return Success;
1235 if (s == SyntaxError) return SyntaxError;
1237 if (done) return Eof;
1238 if (earliest_exit) done = true;
1239 switch (expect_token(in, Word | Dollarpar))
1242 res = read_word(in);
1246 std::string name = read_word(in);
1247 if (name.empty()) return SyntaxError;
1248 if (expect_token(in, Rightpar))
1249 nested = new variable_generator(name, local_variables);
1252 nested = get_function(*this, name);
1253 if (!nested) return SyntaxError;
1263 * Read a list of words from an input generator.
1264 * @return false if a syntax error was encountered.
1266 static bool read_words(input_generator &in, string_list &res)
1270 res.push_back(std::string());
1271 input_status s = in.next(res.back());
1272 if (s == Success) continue;
1278 static bool read_words(std::istream &in, string_list &res)
1280 input_generator gen(in, NULL);
1281 return read_words(gen, res);
1285 * Generator for the result of function addprefix.
1287 struct addprefix_generator: generator
1289 input_generator gen;
1291 string_list::const_iterator prei;
1294 addprefix_generator(input_generator const &, bool &);
1295 input_status next(std::string &);
1298 addprefix_generator::addprefix_generator(input_generator const &top, bool &ok)
1299 : gen(top.in, top.local_variables)
1301 if (!read_words(gen, pre)) return;
1302 if (!expect_token(gen.in, Comma)) return;
1308 input_status addprefix_generator::next(std::string &res)
1325 switch (gen.next(res))
1328 if (!prel) return Success;
1334 return expect_token(gen.in, Rightpar) ? Eof : SyntaxError;
1341 * Generator for the result of function addsuffix.
1343 struct addsuffix_generator: generator
1345 input_generator gen;
1347 string_list::const_iterator sufi;
1350 addsuffix_generator(input_generator const &, bool &);
1351 input_status next(std::string &);
1354 addsuffix_generator::addsuffix_generator(input_generator const &top, bool &ok)
1355 : gen(top.in, top.local_variables)
1357 if (!read_words(gen, suf)) return;
1358 if (!expect_token(gen.in, Comma)) return;
1364 input_status addsuffix_generator::next(std::string &res)
1376 switch (gen.next(res))
1379 if (!sufl) return Success;
1385 return expect_token(gen.in, Rightpar) ? Eof : SyntaxError;
1392 * Return a generator for function @a name.
1394 static generator *get_function(input_generator const &in, std::string const &name)
1397 generator *g = NULL;
1399 if (name == "addprefix") g = new addprefix_generator(in, ok);
1400 else if (name == "addsuffix") g = new addsuffix_generator(in, ok);
1401 if (!g || ok) return g;
1409 * @defgroup database Dependency database
1415 * Load dependencies from @a in.
1417 static void load_dependencies(std::istream &in)
1422 std::cerr << "Failed to load database" << std::endl;
1428 string_list targets;
1429 if (!read_words(in, targets)) goto error;
1430 if (in.eof()) return;
1431 if (targets.empty()) goto error;
1432 DEBUG << "reading dependencies of target " << targets.front() << std::endl;
1433 if (in.get() != ':') goto error;
1434 ref_ptr<dependency_t> dep;
1435 dep->targets = targets;
1437 if (!read_words(in, deps)) goto error;
1438 dep->deps.insert(deps.begin(), deps.end());
1439 for (string_list::const_iterator i = targets.begin(),
1440 i_end = targets.end(); i != i_end; ++i)
1442 dependencies[*i] = dep;
1449 * Load known dependencies from file <tt>.remake</tt>.
1451 static void load_dependencies()
1453 DEBUG_open << "Loading database... ";
1454 std::ifstream in(".remake");
1457 DEBUG_close << "not found\n";
1460 load_dependencies(in);
1465 * Save all the dependencies in file <tt>.remake</tt>.
1467 static void save_dependencies()
1469 DEBUG_open << "Saving database... ";
1470 std::ofstream db(".remake");
1471 while (!dependencies.empty())
1473 ref_ptr<dependency_t> dep = dependencies.begin()->second;
1474 for (string_list::const_iterator i = dep->targets.begin(),
1475 i_end = dep->targets.end(); i != i_end; ++i)
1477 db << escape_string(*i) << ' ';
1478 dependencies.erase(*i);
1481 for (string_set::const_iterator i = dep->deps.begin(),
1482 i_end = dep->deps.end(); i != i_end; ++i)
1484 db << ' ' << escape_string(*i);
1492 static void merge_rule(rule_t &dest, rule_t const &src);
1495 * @defgroup parser Rule parser
1501 * Register a specific rule with an empty script:
1503 * - Check that none of the targets already has an associated rule with a
1505 * - Create a new rule with a single target for each target, if needed.
1506 * - Add the prerequisites of @a rule to all these associated rules.
1508 static void register_transparent_rule(rule_t const &rule, string_list const &targets)
1510 assert(rule.script.empty());
1511 for (string_list::const_iterator i = targets.begin(),
1512 i_end = targets.end(); i != i_end; ++i)
1514 std::pair<rule_map::iterator, bool> j =
1515 specific_rules.insert(std::make_pair(*i, ref_ptr<rule_t>()));
1516 ref_ptr<rule_t> &r = j.first->second;
1519 r = ref_ptr<rule_t>(rule);
1520 r->targets = string_list(1, *i);
1523 if (!r->script.empty())
1525 std::cerr << "Failed to load rules: " << *i
1526 << " cannot be the target of several rules" << std::endl;
1529 assert(r->targets.size() == 1 && r->targets.front() == *i);
1530 merge_rule(*r, rule);
1533 for (string_list::const_iterator i = targets.begin(),
1534 i_end = targets.end(); i != i_end; ++i)
1536 ref_ptr<dependency_t> &dep = dependencies[*i];
1537 if (dep->targets.empty()) dep->targets.push_back(*i);
1538 dep->deps.insert(rule.deps.begin(), rule.deps.end());
1543 * Register a specific rule with a nonempty script:
1545 * - Check that none of the targets already has an associated rule.
1546 * - Create a single shared rule and associate it to all the targets.
1547 * - Merge the prerequisites of all the targets into a single set and
1548 * add the prerequisites of the rule to it. (The preexisting
1549 * prerequisites, if any, come from a previous run.)
1551 static void register_scripted_rule(rule_t const &rule)
1553 ref_ptr<rule_t> r(rule);
1554 for (string_list::const_iterator i = rule.targets.begin(),
1555 i_end = rule.targets.end(); i != i_end; ++i)
1557 std::pair<rule_map::iterator, bool> j =
1558 specific_rules.insert(std::make_pair(*i, r));
1559 if (j.second) continue;
1560 std::cerr << "Failed to load rules: " << *i
1561 << " cannot be the target of several rules" << std::endl;
1565 ref_ptr<dependency_t> dep;
1566 dep->targets = rule.targets;
1567 dep->deps.insert(rule.deps.begin(), rule.deps.end());
1568 for (string_list::const_iterator i = rule.targets.begin(),
1569 i_end = rule.targets.end(); i != i_end; ++i)
1571 ref_ptr<dependency_t> &d = dependencies[*i];
1572 dep->deps.insert(d->deps.begin(), d->deps.end());
1578 * Read a rule starting with target @a first, if nonempty.
1579 * Store into #generic_rules or #specific_rules depending on its genericity.
1581 static void load_rule(std::istream &in, std::string const &first)
1583 DEBUG_open << "Reading rule for target " << first << "... ";
1587 DEBUG_close << "failed\n";
1588 std::cerr << "Failed to load rules: syntax error" << std::endl;
1593 // Read targets and check genericity.
1594 string_list targets;
1595 if (!read_words(in, targets)) goto error;
1596 if (!first.empty()) targets.push_front(first);
1597 else if (targets.empty()) goto error;
1598 else DEBUG << "actual target: " << targets.front() << std::endl;
1599 bool generic = false;
1600 normalize_list(targets, "", "");
1601 for (string_list::const_iterator i = targets.begin(),
1602 i_end = targets.end(); i != i_end; ++i)
1604 if (i->empty()) goto error;
1605 if ((i->find('%') != std::string::npos) != generic)
1607 if (i == targets.begin()) generic = true;
1611 std::swap(rule.targets, targets);
1613 if (in.get() != ':') goto error;
1615 bool assignment = false;
1617 // Read dependencies.
1620 if (expect_token(in, Word))
1622 std::string d = read_word(in);
1623 if (int tok = expect_token(in, Equal | Plusequal))
1625 if (!read_words(in, v)) goto error;
1626 assign_t &a = rule.assigns[d];
1627 a.append = tok == Plusequal;
1635 if (!read_words(in, v)) goto error;
1636 normalize_list(v, "", "");
1639 if (expect_token(in, Pipe))
1641 if (!read_words(in, v)) goto error;
1642 normalize_list(v, "", "");
1649 if (!skip_eol(in, true)) goto error;
1652 std::ostringstream buf;
1656 if (!in.good()) break;
1657 if (c == '\t' || c == ' ')
1659 in.get(*buf.rdbuf());
1660 if (in.fail() && !in.eof()) in.clear();
1662 else if (c == '\r' || c == '\n')
1670 rule.script = buf.str();
1672 // Add generic rules to the correct set.
1675 if (assignment) goto error;
1676 generic_rules.push_back(rule);
1680 if (!rule.script.empty())
1682 if (assignment) goto error;
1683 register_scripted_rule(rule);
1687 // Swap away the targets to avoid costly copies when registering.
1688 string_list targets;
1689 std::swap(rule.targets, targets);
1690 register_transparent_rule(rule, targets);
1691 std::swap(rule.targets, targets);
1694 // If there is no default target yet, mark it as such.
1695 if (first_target.empty())
1696 first_target = rule.targets.front();
1700 * Load rules from @a remakefile.
1701 * If some rules have dependencies and non-generic targets, add these
1702 * dependencies to the targets.
1704 static void load_rules(std::string const &remakefile)
1706 DEBUG_open << "Loading rules... ";
1710 std::cerr << "Failed to load rules: syntax error" << std::endl;
1713 std::ifstream in(remakefile.c_str());
1716 std::cerr << "Failed to load rules: no Remakefile found" << std::endl;
1721 string_list options;
1729 while (in.get() != '\n') {}
1733 if (c == ' ' || c == '\t') goto error;
1734 if (expect_token(in, Word))
1736 std::string name = read_word(in);
1737 if (name.empty()) goto error;
1738 if (int tok = expect_token(in, Equal | Plusequal))
1740 DEBUG << "Assignment to variable " << name << std::endl;
1742 if (!read_words(in, value)) goto error;
1744 *(name == ".OPTIONS" ? &options : &variables[name]);
1745 if (tok == Equal) dest.swap(value);
1746 else dest.splice(dest.end(), value);
1747 if (!skip_eol(in, true)) goto error;
1749 else load_rule(in, name);
1751 else load_rule(in, std::string());
1754 // Set actual options.
1755 for (string_list::const_iterator i = options.begin(),
1756 i_end = options.end(); i != i_end; ++i)
1758 if (*i == "variable-propagation") propagate_vars = true;
1761 std::cerr << "Failed to load rules: unrecognized option" << std::endl;
1770 * @defgroup rules Rule resolution
1775 static void merge_rule(rule_t &dest, rule_t const &src)
1777 dest.deps.insert(dest.deps.end(), src.deps.begin(), src.deps.end());
1778 dest.wdeps.insert(dest.wdeps.end(), src.wdeps.begin(), src.wdeps.end());
1779 for (assign_map::const_iterator i = src.assigns.begin(),
1780 i_end = src.assigns.end(); i != i_end; ++i)
1782 if (!i->second.append)
1785 dest.assigns[i->first] = i->second;
1788 assign_map::iterator j = dest.assigns.find(i->first);
1789 if (j == dest.assigns.end()) goto new_assign;
1790 j->second.value.insert(j->second.value.end(),
1791 i->second.value.begin(), i->second.value.end());
1796 * Substitute a pattern into a list of strings.
1798 static void substitute_pattern(std::string const &pat, string_list const &src, string_list &dst)
1800 for (string_list::const_iterator i = src.begin(),
1801 i_end = src.end(); i != i_end; ++i)
1803 size_t pos = i->find('%');
1804 if (pos == std::string::npos) dst.push_back(*i);
1805 else dst.push_back(i->substr(0, pos) + pat + i->substr(pos + 1));
1810 * Find a generic rule matching @a target:
1811 * - the one leading to shorter matches has priority,
1812 * - among equivalent rules, the earliest one has priority.
1814 static void find_generic_rule(job_t &job, std::string const &target)
1816 size_t tlen = target.length(), plen = tlen + 1;
1817 for (rule_list::const_iterator i = generic_rules.begin(),
1818 i_end = generic_rules.end(); i != i_end; ++i)
1820 for (string_list::const_iterator j = i->targets.begin(),
1821 j_end = i->targets.end(); j != j_end; ++j)
1823 size_t len = j->length();
1824 if (tlen < len) continue;
1825 if (plen <= tlen - (len - 1)) continue;
1826 size_t pos = j->find('%');
1827 if (pos == std::string::npos) continue;
1828 size_t len2 = len - (pos + 1);
1829 if (j->compare(0, pos, target, 0, pos) ||
1830 j->compare(pos + 1, len2, target, tlen - len2, len2))
1832 plen = tlen - (len - 1);
1833 job.stem = target.substr(pos, plen);
1834 job.rule = rule_t();
1835 job.rule.script = i->script;
1836 substitute_pattern(job.stem, i->targets, job.rule.targets);
1837 substitute_pattern(job.stem, i->deps, job.rule.deps);
1838 substitute_pattern(job.stem, i->wdeps, job.rule.wdeps);
1845 * Find a specific rule matching @a target. Return a generic one otherwise.
1846 * If there is both a specific rule with an empty script and a generic rule, the
1847 * generic one is returned after adding the dependencies of the specific one.
1849 static void find_rule(job_t &job, std::string const &target)
1851 rule_map::const_iterator i = specific_rules.find(target),
1852 i_end = specific_rules.end();
1853 // If there is a specific rule with a script, return it.
1854 if (i != i_end && !i->second->script.empty())
1856 job.rule = *i->second;
1859 find_generic_rule(job, target);
1860 // If there is no generic rule, return the specific rule (no script), if any.
1861 if (job.rule.targets.empty())
1865 job.rule = *i->second;
1869 // Optimize the lookup when there is only one target (already looked up).
1870 if (job.rule.targets.size() == 1)
1872 if (i == i_end) return;
1873 merge_rule(job.rule, *i->second);
1876 // Add the dependencies of the specific rules of every target to the
1877 // generic rule. If any of those rules has a nonempty script, error out.
1878 for (string_list::const_iterator j = job.rule.targets.begin(),
1879 j_end = job.rule.targets.end(); j != j_end; ++j)
1881 i = specific_rules.find(*j);
1882 if (i == i_end) continue;
1883 if (!i->second->script.empty()) return;
1884 merge_rule(job.rule, *i->second);
1891 * @defgroup status Target status
1897 * Compute and memoize the status of @a target:
1898 * - if the file does not exist, the target is obsolete,
1899 * - if any dependency is obsolete or younger than the file, it is obsolete,
1900 * - otherwise it is up-to-date.
1902 * @note For rules with multiple targets, all the targets share the same
1903 * status. (If one is obsolete, they all are.) The second rule above
1904 * is modified in that case: the latest target is chosen, not the oldest!
1906 static status_t const &get_status(std::string const &target)
1908 std::pair<status_map::iterator,bool> i =
1909 status.insert(std::make_pair(target, status_t()));
1910 status_t &ts = i.first->second;
1911 if (!i.second) return ts;
1912 DEBUG_open << "Checking status of " << target << "... ";
1913 dependency_map::const_iterator j = dependencies.find(target);
1914 if (j == dependencies.end())
1917 if (stat(target.c_str(), &s) != 0)
1919 DEBUG_close << "missing\n";
1924 DEBUG_close << "up-to-date\n";
1925 ts.status = Uptodate;
1926 ts.last = s.st_mtime;
1929 dependency_t const &dep = *j->second;
1930 status_e st = Uptodate;
1932 for (string_list::const_iterator k = dep.targets.begin(),
1933 k_end = dep.targets.end(); k != k_end; ++k)
1936 if (stat(k->c_str(), &s) != 0)
1938 if (st == Uptodate) DEBUG_close << *k << " missing\n";
1942 status[*k].last = s.st_mtime;
1943 if (s.st_mtime > latest) latest = s.st_mtime;
1945 if (st != Uptodate) goto update;
1946 for (string_set::const_iterator k = dep.deps.begin(),
1947 k_end = dep.deps.end(); k != k_end; ++k)
1949 status_t const &ts_ = get_status(*k);
1950 if (latest < ts_.last)
1952 DEBUG_close << "older than " << *k << std::endl;
1956 if (ts_.status != Uptodate && st != Recheck)
1958 DEBUG << "obsolete dependency " << *k << std::endl;
1962 if (st == Uptodate) DEBUG_close << "all siblings up-to-date\n";
1964 for (string_list::const_iterator k = dep.targets.begin(),
1965 k_end = dep.targets.end(); k != k_end; ++k)
1967 status[*k].status = st;
1973 * Change the status of @a target to #Remade or #Uptodate depending on whether
1974 * its modification time changed.
1976 static void update_status(std::string const &target)
1978 DEBUG_open << "Rechecking status of " << target << "... ";
1979 status_map::iterator i = status.find(target);
1980 assert(i != status.end());
1981 status_t &ts = i->second;
1985 DEBUG_close << "possibly remade\n";
1989 if (stat(target.c_str(), &s) != 0)
1991 DEBUG_close << "missing\n";
1994 else if (s.st_mtime != ts.last)
1996 DEBUG_close << "remade\n";
1997 ts.last = s.st_mtime;
2001 DEBUG_close << "unchanged\n";
2002 ts.status = Uptodate;
2007 * Check whether all the prerequisites of @a target ended being up-to-date.
2009 static bool still_need_rebuild(std::string const &target)
2011 DEBUG_open << "Rechecking obsoleteness of " << target << "... ";
2012 status_map::const_iterator i = status.find(target);
2013 assert(i != status.end());
2014 if (i->second.status != Recheck) return true;
2015 dependency_map::const_iterator j = dependencies.find(target);
2016 assert(j != dependencies.end());
2017 dependency_t const &dep = *j->second;
2018 for (string_set::const_iterator k = dep.deps.begin(),
2019 k_end = dep.deps.end(); k != k_end; ++k)
2021 if (status[*k].status != Uptodate) return true;
2023 for (string_list::const_iterator k = dep.targets.begin(),
2024 k_end = dep.targets.end(); k != k_end; ++k)
2026 status[*k].status = Uptodate;
2028 DEBUG_close << "no longer obsolete\n";
2035 * @defgroup server Server
2041 * Handle job completion.
2043 static void complete_job(int job_id, bool success)
2045 DEBUG_open << "Completing job " << job_id << "... ";
2046 job_map::iterator i = jobs.find(job_id);
2047 assert(i != jobs.end());
2048 string_list const &targets = i->second.rule.targets;
2051 for (string_list::const_iterator j = targets.begin(),
2052 j_end = targets.end(); j != j_end; ++j)
2059 DEBUG_close << "failed\n";
2060 std::cerr << "Failed to build";
2061 for (string_list::const_iterator j = targets.begin(),
2062 j_end = targets.end(); j != j_end; ++j)
2064 status[*j].status = Failed;
2065 std::cerr << ' ' << *j;
2068 std::cerr << std::endl;
2074 * Return the script obtained by substituting variables.
2076 static std::string prepare_script(job_t const &job)
2078 std::string const &s = job.rule.script;
2079 std::istringstream in(s);
2080 std::ostringstream out;
2081 size_t len = s.size();
2085 size_t pos = in.tellg(), p = s.find('$', pos);
2086 if (p == std::string::npos || p == len - 1) p = len;
2087 out.write(&s[pos], p - pos);
2088 if (p == len) break;
2097 if (!job.rule.deps.empty())
2098 out << job.rule.deps.front();
2104 for (string_list::const_iterator i = job.rule.deps.begin(),
2105 i_end = job.rule.deps.end(); i != i_end; ++i)
2107 if (first) first = false;
2115 assert(!job.rule.targets.empty());
2116 out << job.rule.targets.front();
2127 input_generator gen(in, &job.vars, true);
2131 input_status s = gen.next(w);
2132 if (s == SyntaxError)
2137 if (s == Eof) break;
2138 if (first) first = false;
2145 // Let dollars followed by an unrecognized character
2146 // go through. This differs from Make, which would
2147 // use a one-letter variable.
2157 * Execute the script from @a rule.
2159 static status_e run_script(int job_id, job_t const &job)
2163 std::cout << "Building";
2164 for (string_list::const_iterator i = job.rule.targets.begin(),
2165 i_end = job.rule.targets.end(); i != i_end; ++i)
2167 std::cout << ' ' << *i;
2169 std::cout << std::endl;
2172 ref_ptr<dependency_t> dep;
2173 dep->targets = job.rule.targets;
2174 dep->deps.insert(job.rule.deps.begin(), job.rule.deps.end());
2175 for (string_list::const_iterator i = job.rule.targets.begin(),
2176 i_end = job.rule.targets.end(); i != i_end; ++i)
2178 dependencies[*i] = dep;
2181 std::string script = prepare_script(job);
2183 std::ostringstream job_id_buf;
2184 job_id_buf << job_id;
2185 std::string job_id_ = job_id_buf.str();
2187 DEBUG_open << "Starting script for job " << job_id << "... ";
2190 DEBUG_close << "no script\n";
2191 complete_job(job_id, true);
2198 DEBUG_close << "failed\n";
2199 complete_job(job_id, false);
2208 CloseHandle(pfd[0]);
2209 CloseHandle(pfd[1]);
2212 if (!CreatePipe(&pfd[0], &pfd[1], NULL, 0))
2214 if (!SetHandleInformation(pfd[0], HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
2217 ZeroMemory(&si, sizeof(STARTUPINFO));
2218 si.cb = sizeof(STARTUPINFO);
2219 si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
2220 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
2221 si.hStdInput = pfd[0];
2222 si.dwFlags |= STARTF_USESTDHANDLES;
2223 PROCESS_INFORMATION pi;
2224 ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
2225 if (!SetEnvironmentVariable("REMAKE_JOB_ID", job_id_.c_str()))
2227 char const *argv = echo_scripts ? "SH.EXE -e -s -v" : "SH.EXE -e -s";
2228 if (!CreateProcess(NULL, (char *)argv, NULL, NULL,
2229 true, 0, NULL, NULL, &si, &pi))
2233 CloseHandle(pi.hThread);
2234 DWORD len = script.length(), wlen;
2235 if (!WriteFile(pfd[1], script.c_str(), len, &wlen, NULL) || wlen < len)
2236 std::cerr << "Unexpected failure while sending script to shell" << std::endl;
2237 CloseHandle(pfd[0]);
2238 CloseHandle(pfd[1]);
2240 job_pids[pi.hProcess] = job_id;
2251 if (pipe(pfd) == -1)
2253 if (setenv("REMAKE_JOB_ID", job_id_.c_str(), 1))
2255 if (pid_t pid = vfork())
2257 if (pid == -1) goto error2;
2258 ssize_t len = script.length();
2259 if (write(pfd[1], script.c_str(), len) < len)
2260 std::cerr << "Unexpected failure while sending script to shell" << std::endl;
2264 job_pids[pid] = job_id;
2267 // Child process starts here. Notice the use of vfork above.
2268 char const *argv[5] = { "sh", "-e", "-s", NULL, NULL };
2269 if (echo_scripts) argv[3] = "-v";
2276 execve("/bin/sh", (char **)argv, environ);
2277 _exit(EXIT_FAILURE);
2282 * Create a job for @a target according to the loaded rules.
2283 * Mark all the targets from the rule as running and reset their dependencies.
2284 * Inherit variables from @a current, if enabled.
2285 * If the rule has dependencies, create a new client to build them just
2286 * before @a current, and change @a current so that it points to it.
2288 static status_e start(std::string const &target, client_list::iterator ¤t)
2290 int job_id = job_counter++;
2291 DEBUG_open << "Starting job " << job_id << " for " << target << "... ";
2292 job_t &job = jobs[job_id];
2293 find_rule(job, target);
2294 if (job.rule.targets.empty())
2296 status[target].status = Failed;
2297 DEBUG_close << "failed\n";
2298 std::cerr << "No rule for building " << target << std::endl;
2301 for (string_list::const_iterator i = job.rule.targets.begin(),
2302 i_end = job.rule.targets.end(); i != i_end; ++i)
2304 status[*i].status = Running;
2306 if (propagate_vars) job.vars = current->vars;
2307 for (assign_map::const_iterator i = job.rule.assigns.begin(),
2308 i_end = job.rule.assigns.end(); i != i_end; ++i)
2310 std::pair<variable_map::iterator, bool> k =
2311 job.vars.insert(std::make_pair(i->first, string_list()));
2312 string_list &v = k.first->second;
2313 if (i->second.append)
2317 variable_map::const_iterator j = variables.find(i->first);
2318 if (j != variables.end()) v = j->second;
2321 else if (!k.second) v.clear();
2322 v.insert(v.end(), i->second.value.begin(), i->second.value.end());
2324 if (!job.rule.deps.empty() || !job.rule.wdeps.empty())
2326 current = clients.insert(current, client_t());
2327 current->job_id = job_id;
2328 current->pending = job.rule.deps;
2329 current->pending.insert(current->pending.end(),
2330 job.rule.wdeps.begin(), job.rule.wdeps.end());
2331 if (propagate_vars) current->vars = job.vars;
2332 current->delayed = true;
2335 return run_script(job_id, job);
2339 * Send a reply to a client then remove it.
2340 * If the client was a dependency client, start the actual script.
2342 static void complete_request(client_t &client, bool success)
2344 DEBUG_open << "Completing request from client of job " << client.job_id << "... ";
2347 assert(client.socket == INVALID_SOCKET);
2350 job_map::const_iterator i = jobs.find(client.job_id);
2351 assert(i != jobs.end());
2352 if (still_need_rebuild(i->second.rule.targets.front()))
2353 run_script(client.job_id, i->second);
2354 else complete_job(client.job_id, true);
2356 else complete_job(client.job_id, false);
2358 else if (client.socket != INVALID_SOCKET)
2360 char res = success ? 1 : 0;
2361 send(client.socket, &res, 1, MSG_NOSIGNAL);
2363 closesocket(client.socket);
2365 close(client.socket);
2370 if (client.job_id < 0 && !success) build_failure = true;
2374 * Return whether there are slots for starting new jobs.
2376 static bool has_free_slots()
2378 if (max_active_jobs <= 0) return true;
2379 return running_jobs - waiting_jobs < max_active_jobs;
2383 * Handle client requests:
2384 * - check for running targets that have finished,
2385 * - start as many pending targets as allowed,
2386 * - complete the request if there are neither running nor pending targets
2387 * left or if any of them failed.
2389 * @return true if some child processes are still running.
2391 * @post If there are pending requests, at least one child process is running.
2393 * @invariant New free slots cannot appear during a run, since the only way to
2394 * decrease #running_jobs is #finalize_job and the only way to
2395 * increase #waiting_jobs is #accept_client. None of these functions
2396 * are called during a run. So breaking out as soon as there no free
2397 * slots left is fine.
2399 static bool handle_clients()
2401 DEBUG_open << "Handling client requests... ";
2403 bool need_restart = false;
2405 for (client_list::iterator i = clients.begin(), i_next = i,
2406 i_end = clients.end(); i != i_end && has_free_slots(); i = i_next)
2409 DEBUG_open << "Handling client from job " << i->job_id << "... ";
2411 // Remove running targets that have finished.
2412 for (string_set::iterator j = i->running.begin(), j_next = j,
2413 j_end = i->running.end(); j != j_end; j = j_next)
2416 status_map::const_iterator k = status.find(*j);
2417 assert(k != status.end());
2418 switch (k->second.status)
2424 if (!keep_going) goto complete;
2428 i->running.erase(j);
2436 // Start pending targets.
2437 while (!i->pending.empty())
2439 std::string target = i->pending.front();
2440 i->pending.pop_front();
2441 switch (get_status(target).status)
2444 i->running.insert(target);
2449 if (!keep_going) goto complete;
2456 client_list::iterator j = i;
2457 switch (start(target, i))
2460 goto pending_failed;
2462 // A shell was started, check for free slots.
2463 j->running.insert(target);
2464 if (!has_free_slots()) return true;
2467 // Switch to the dependency client that was inserted.
2468 j->running.insert(target);
2473 need_restart = true;
2481 // Try to complete the request.
2482 // (This might start a new job if it was a dependency client.)
2483 if (i->running.empty() || i->failed)
2486 complete_request(*i, !i->failed);
2487 DEBUG_close << (i->failed ? "failed\n" : "finished\n");
2489 need_restart = true;
2493 if (running_jobs != waiting_jobs) return true;
2494 if (running_jobs == 0 && clients.empty()) return false;
2495 if (need_restart) goto restart;
2497 // There is a circular dependency.
2498 // Try to break it by completing one of the requests.
2499 assert(!clients.empty());
2500 std::cerr << "Circular dependency detected" << std::endl;
2501 client_list::iterator i = clients.begin();
2502 complete_request(*i, false);
2508 * Create a named unix socket that listens for build requests. Also set
2509 * the REMAKE_SOCKET environment variable that will be inherited by all
2512 static void create_server()
2517 perror("Failed to create server");
2523 DEBUG_open << "Creating server... ";
2526 // Prepare a windows socket.
2527 struct sockaddr_in socket_addr;
2528 socket_addr.sin_family = AF_INET;
2529 socket_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
2530 socket_addr.sin_port = 0;
2532 // Create and listen to the socket.
2533 socket_fd = socket(AF_INET, SOCK_STREAM, 0);
2534 if (socket_fd == INVALID_SOCKET) goto error;
2535 if (!SetHandleInformation((HANDLE)socket_fd, HANDLE_FLAG_INHERIT, 0))
2537 if (bind(socket_fd, (struct sockaddr *)&socket_addr, sizeof(sockaddr_in)))
2539 int len = sizeof(sockaddr_in);
2540 if (getsockname(socket_fd, (struct sockaddr *)&socket_addr, &len))
2542 std::ostringstream buf;
2543 buf << socket_addr.sin_port;
2544 if (!SetEnvironmentVariable("REMAKE_SOCKET", buf.str().c_str()))
2546 if (listen(socket_fd, 1000)) goto error;
2548 // Set signal handlers for SIGCHLD and SIGINT.
2549 // Block SIGCHLD (unblocked during select).
2551 sigemptyset(&sigmask);
2552 sigaddset(&sigmask, SIGCHLD);
2553 if (sigprocmask(SIG_BLOCK, &sigmask, NULL) == -1) goto error;
2554 struct sigaction sa;
2556 sigemptyset(&sa.sa_mask);
2557 sa.sa_handler = &sigchld_handler;
2558 if (sigaction(SIGCHLD, &sa, NULL) == -1) goto error;
2559 sa.sa_handler = &sigint_handler;
2560 if (sigaction(SIGINT, &sa, NULL) == -1) goto error;
2562 // Prepare a named unix socket in temporary directory.
2563 struct stat tmpstat;
2565 if ((0 == stat(tmpdir = getenv("TMPDIR"), &tmpstat)
2566 && (S_ISDIR(tmpstat.st_mode)))
2567 || ((0 == stat(tmpdir = (char*)P_tmpdir, &tmpstat))
2568 && (S_ISDIR(tmpstat.st_mode)))
2569 || ((0 == stat(tmpdir = (char*)"/tmp", &tmpstat))
2570 && (S_ISDIR(tmpstat.st_mode))));
2572 std::stringstream tmpname;
2573 long int rnd = now ^ getpid();
2578 tmpname << tmpdir << "/rmk-";
2583 while (access (tmpname.str().c_str(), F_OK) == 0);
2584 socket_name = strdup(tmpname.str().c_str());
2585 if (!socket_name) goto error2;
2586 struct sockaddr_un socket_addr;
2587 size_t len = strlen(socket_name);
2588 if (len >= sizeof(socket_addr.sun_path) - 1) goto error2;
2589 socket_addr.sun_family = AF_UNIX;
2590 strcpy(socket_addr.sun_path, socket_name);
2591 len += sizeof(socket_addr.sun_family);
2592 if (setenv("REMAKE_SOCKET", socket_name, 1)) goto error;
2594 // Create and listen to the socket.
2596 socket_fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
2597 if (socket_fd == INVALID_SOCKET) goto error;
2599 socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
2600 if (socket_fd == INVALID_SOCKET) goto error;
2601 if (fcntl(socket_fd, F_SETFD, FD_CLOEXEC) < 0) goto error;
2603 if (bind(socket_fd, (struct sockaddr *)&socket_addr, len))
2605 if (listen(socket_fd, 1000)) goto error;
2610 * Accept a connection from a client, get the job it spawned from,
2611 * get the targets, and mark them as dependencies of the job targets.
2613 static void accept_client()
2615 DEBUG_open << "Handling client request... ";
2617 // Accept connection.
2619 socket_t fd = accept(socket_fd, NULL, NULL);
2620 if (fd == INVALID_SOCKET) return;
2621 if (!SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0))
2624 std::cerr << "Unexpected failure while setting connection with client" << std::endl;
2628 // WSAEventSelect puts sockets into nonblocking mode, so disable it here.
2630 if (ioctlsocket(fd, FIONBIO, &nbio)) goto error2;
2631 #elif defined(LINUX)
2632 int fd = accept4(socket_fd, NULL, NULL, SOCK_CLOEXEC);
2635 int fd = accept(socket_fd, NULL, NULL);
2637 if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) return;
2639 clients.push_front(client_t());
2640 client_list::iterator proc = clients.begin();
2645 DEBUG_close << "failed\n";
2646 std::cerr << "Received an ill-formed client message" << std::endl;
2652 clients.erase(proc);
2656 // Receive message. Stop when encountering two nuls in a row.
2657 std::vector<char> buf;
2659 while (len < sizeof(int) + 2 || buf[len - 1] || buf[len - 2])
2661 buf.resize(len + 1024);
2662 ssize_t l = recv(fd, &buf[0] + len, 1024, 0);
2663 if (l <= 0) goto error;
2667 // Parse job that spawned the client.
2669 memcpy(&job_id, &buf[0], sizeof(int));
2671 proc->job_id = job_id;
2672 job_map::const_iterator i = jobs.find(job_id);
2673 if (i == jobs.end()) goto error;
2674 DEBUG << "receiving request from job " << job_id << std::endl;
2675 if (propagate_vars) proc->vars = i->second.vars;
2677 // Parse the targets and the variable assignments.
2678 // Mark the targets as dependencies of the job targets.
2679 dependency_t &dep = *dependencies[i->second.rule.targets.front()];
2680 string_list *last_var = NULL;
2681 char const *p = &buf[0] + sizeof(int);
2694 if (len == 1) goto error;
2695 std::string target(p + 1, p + len);
2696 DEBUG << "adding dependency " << target << " to job\n";
2697 proc->pending.push_back(target);
2698 dep.deps.insert(target);
2703 if (len == 1) goto error;
2704 std::string var(p + 1, p + len);
2705 DEBUG << "adding variable " << var << " to job\n";
2706 last_var = &proc->vars[var];
2712 if (!last_var) goto error;
2713 last_var->push_back(std::string(p + 1, p + len));
2722 if (!propagate_vars && !proc->vars.empty())
2724 std::cerr << "Assignments are ignored unless 'variable-propagation' is enabled" << std::endl;
2730 * Handle child process exit status.
2732 static void finalize_job(pid_t pid, bool res)
2734 pid_job_map::iterator i = job_pids.find(pid);
2735 assert(i != job_pids.end());
2736 int job_id = i->second;
2739 complete_job(job_id, res);
2743 * Loop until all the jobs have finished.
2745 * @post There are no client requests left, not even virtual ones.
2747 static void server_loop()
2749 while (handle_clients())
2751 DEBUG_open << "Handling events... ";
2753 size_t len = job_pids.size() + 1;
2756 for (pid_job_map::const_iterator i = job_pids.begin(),
2757 i_end = job_pids.end(); i != i_end; ++i, ++num)
2761 WSAEVENT aev = WSACreateEvent();
2763 WSAEventSelect(socket_fd, aev, FD_ACCEPT);
2764 DWORD w = WaitForMultipleObjects(len, h, false, INFINITE);
2765 WSAEventSelect(socket_fd, aev, 0);
2776 bool res = GetExitCodeProcess(pid, &s) && s == 0;
2778 finalize_job(pid, res);
2781 sigemptyset(&emptymask);
2784 FD_SET(socket_fd, &fdset);
2785 int ret = pselect(socket_fd + 1, &fdset, NULL, NULL, NULL, &emptymask);
2786 if (ret > 0 /* && FD_ISSET(socket_fd, &fdset)*/) accept_client();
2787 if (!got_SIGCHLD) continue;
2791 while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
2793 bool res = WIFEXITED(status) && WEXITSTATUS(status) == 0;
2794 finalize_job(pid, res);
2799 assert(clients.empty());
2803 * Load dependencies and rules, listen to client requests, and loop until
2804 * all the requests have completed.
2805 * If Remakefile is obsolete, perform a first run with it only, then reload
2806 * the rules, and perform a second with the original clients.
2808 static void server_mode(std::string const &remakefile, string_list const &targets)
2810 load_dependencies();
2811 load_rules(remakefile);
2813 if (get_status(remakefile).status != Uptodate)
2815 clients.push_back(client_t());
2816 clients.back().pending.push_back(remakefile);
2818 if (build_failure) goto early_exit;
2820 specific_rules.clear();
2821 generic_rules.clear();
2822 first_target.clear();
2823 load_rules(remakefile);
2825 clients.push_back(client_t());
2826 if (!targets.empty()) clients.back().pending = targets;
2827 else if (!first_target.empty())
2828 clients.back().pending.push_back(first_target);
2833 remove(socket_name);
2836 save_dependencies();
2837 if (print_change_working_dir)
2838 std::cout << "remake: Leaving directory `" << prefix_dir
2840 exit(build_failure ? EXIT_FAILURE : EXIT_SUCCESS);
2846 * @defgroup client Client
2852 * Connect to the server @a socket_name, send a request for building @a targets
2853 * with some @a variables, and exit with the status returned by the server.
2855 static void client_mode(char *socket_name, string_list const &targets)
2860 perror("Failed to send targets to server");
2863 if (targets.empty()) exit(EXIT_SUCCESS);
2864 DEBUG_open << "Connecting to server... ";
2866 // Connect to server.
2868 struct sockaddr_in socket_addr;
2869 socket_fd = socket(AF_INET, SOCK_STREAM, 0);
2870 if (socket_fd == INVALID_SOCKET) goto error;
2871 socket_addr.sin_family = AF_INET;
2872 socket_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
2873 socket_addr.sin_port = atoi(socket_name);
2874 if (connect(socket_fd, (struct sockaddr *)&socket_addr, sizeof(sockaddr_in)))
2877 struct sockaddr_un socket_addr;
2878 size_t len = strlen(socket_name);
2879 if (len >= sizeof(socket_addr.sun_path) - 1) exit(EXIT_FAILURE);
2880 socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
2881 if (socket_fd == INVALID_SOCKET) goto error;
2882 socket_addr.sun_family = AF_UNIX;
2883 strcpy(socket_addr.sun_path, socket_name);
2884 if (connect(socket_fd, (struct sockaddr *)&socket_addr, sizeof(socket_addr.sun_family) + len))
2888 if (setsockopt(socket_fd, SOL_SOCKET, SO_NOSIGPIPE, &set_option, sizeof(set_option)))
2893 // Send current job id.
2894 char *id = getenv("REMAKE_JOB_ID");
2895 int job_id = id ? atoi(id) : -1;
2896 if (send(socket_fd, (char *)&job_id, sizeof(job_id), MSG_NOSIGNAL) != sizeof(job_id))
2900 for (string_list::const_iterator i = targets.begin(),
2901 i_end = targets.end(); i != i_end; ++i)
2903 DEBUG_open << "Sending target " << *i << "... ";
2904 std::string s = 'T' + *i;
2905 ssize_t len = s.length() + 1;
2906 if (send(socket_fd, s.c_str(), len, MSG_NOSIGNAL) != len)
2911 for (variable_map::const_iterator i = variables.begin(),
2912 i_end = variables.end(); i != i_end; ++i)
2914 DEBUG_open << "Sending variable " << i->first << "... ";
2915 std::string s = 'V' + i->first;
2916 ssize_t len = s.length() + 1;
2917 if (send(socket_fd, s.c_str(), len, MSG_NOSIGNAL) != len)
2919 for (string_list::const_iterator j = i->second.begin(),
2920 j_end = i->second.end(); j != j_end; ++j)
2922 std::string s = 'W' + *j;
2923 len = s.length() + 1;
2924 if (send(socket_fd, s.c_str(), len, MSG_NOSIGNAL) != len)
2929 // Send terminating nul and wait for reply.
2931 if (send(socket_fd, &result, 1, MSG_NOSIGNAL) != 1) goto error;
2932 if (recv(socket_fd, &result, 1, 0) != 1) exit(EXIT_FAILURE);
2933 exit(result ? EXIT_SUCCESS : EXIT_FAILURE);
2939 * @defgroup ui User interface
2945 * Display usage and exit with @a exit_status.
2947 static void usage(int exit_status)
2949 std::cerr << "Usage: remake [options] [target] ...\n"
2951 " -d Echo script commands.\n"
2952 " -d -d Print lots of debugging information.\n"
2953 " -f FILE Read FILE as Remakefile.\n"
2954 " -h, --help Print this message and exit.\n"
2955 " -j[N], --jobs=[N] Allow N jobs at once; infinite jobs with no arg.\n"
2956 " -k Keep going when some targets cannot be made.\n"
2957 " -r Look up targets from the dependencies on stdin.\n"
2958 " -s, --silent, --quiet Do not echo targets.\n";
2963 * This program behaves in two different ways.
2965 * - If the environment contains the REMAKE_SOCKET variable, the client
2966 * connects to this socket and sends to the server its build targets.
2967 * It exits once it receives the server reply.
2969 * - Otherwise, it creates a server that waits for build requests. It
2970 * also creates a pseudo-client that requests the targets passed on the
2973 int main(int argc, char *argv[])
2977 std::string remakefile;
2978 string_list targets;
2979 bool literal_targets = false;
2980 bool indirect_targets = false;
2982 // Parse command-line arguments.
2983 for (int i = 1; i < argc; ++i)
2985 std::string arg = argv[i];
2986 if (arg.empty()) usage(EXIT_FAILURE);
2987 if (literal_targets) goto new_target;
2988 if (arg == "-h" || arg == "--help") usage(EXIT_SUCCESS);
2990 if (echo_scripts) debug.active = true;
2991 else echo_scripts = true;
2992 else if (arg == "-k" || arg =="--keep-going")
2994 else if (arg == "-s" || arg == "--silent" || arg == "--quiet")
2995 show_targets = false;
2996 else if (arg == "-r")
2997 indirect_targets = true;
2998 else if (arg == "-f")
3000 if (++i == argc) usage(EXIT_FAILURE);
3001 remakefile = argv[i];
3003 else if (arg == "--")
3004 literal_targets = true;
3005 else if (arg.compare(0, 2, "-j") == 0)
3006 max_active_jobs = atoi(arg.c_str() + 2);
3007 else if (arg.compare(0, 7, "--jobs=") == 0)
3008 max_active_jobs = atoi(arg.c_str() + 7);
3011 if (arg[0] == '-') usage(EXIT_FAILURE);
3012 if (arg.find('=') != std::string::npos)
3014 std::istringstream in(arg);
3015 std::string name = read_word(in);
3016 if (name.empty() || !expect_token(in, Equal)) usage(EXIT_FAILURE);
3017 read_words(in, variables[name]);
3021 targets.push_back(normalize(arg, working_dir, working_dir));
3022 DEBUG << "New target: " << arg << '\n';
3026 if (indirect_targets)
3028 load_dependencies(std::cin);
3031 if (l.empty() && !dependencies.empty())
3033 l.push_back(dependencies.begin()->second->targets.front());
3035 for (string_list::const_iterator i = l.begin(),
3036 i_end = l.end(); i != i_end; ++i)
3038 dependency_map::const_iterator j = dependencies.find(*i);
3039 if (j == dependencies.end()) continue;
3040 dependency_t const &dep = *j->second;
3041 for (string_set::const_iterator k = dep.deps.begin(),
3042 k_end = dep.deps.end(); k != k_end; ++k)
3044 targets.push_back(normalize(*k, working_dir, working_dir));
3047 dependencies.clear();
3052 if (WSAStartup(MAKEWORD(2,2), &wsaData))
3054 std::cerr << "Unexpected failure while initializing Windows Socket" << std::endl;
3059 // Run as client if REMAKE_SOCKET is present in the environment.
3060 if (char *sn = getenv("REMAKE_SOCKET")) client_mode(sn, targets);
3062 // Otherwise run as server.
3063 if (remakefile.empty())
3065 remakefile = "Remakefile";
3068 normalize_list(targets, working_dir, prefix_dir);
3069 server_mode(remakefile, targets);