366 #define WIN32_LEAN_AND_MEAN
385 #include <sys/stat.h>
386 #include <sys/types.h>
399 #include <winsock2.h>
403 #include <sys/socket.h>
405 #include <sys/wait.h>
410 #if defined(WINDOWS) || defined(MACOSX)
411 enum { MSG_NOSIGNAL = 0 };
440 if (
ptr == p.
ptr)
return *
this;
514 typedef std::map<std::string, ref_ptr<rule_t> >
rule_map;
658 static time_t
now = time(NULL);
687 if (
open) std::cerr << std::endl;
689 std::cerr << std::string(
depth * 2,
' ');
695 if (o &&
open) std::cerr << std::endl;
698 if (o || !
open) std::cerr << std::string(
depth * 2,
' ');
719 #define DEBUG if (debug.active) debug()
720 #define DEBUG_open log_auto_close auto_close; if (debug.active) debug(true)
721 #define DEBUG_close if ((auto_close.still_open = false), debug.active) debug(false)
740 std::string
const &s = se.
input;
741 char const *quoted_char =
",: '";
742 char const *escaped_char =
"\"\\$!";
743 bool need_quotes =
false;
745 size_t len = s.length(), last = 0, j = 0;
746 for (
size_t i = 0; i < len; ++i)
748 if (strchr(escaped_char, s[i]))
751 if (!buf) buf =
new char[len * 2];
752 memcpy(&buf[j], &s[last], i - last);
758 if (!need_quotes && strchr(quoted_char, s[i]))
761 if (!need_quotes)
return out << s;
763 if (!buf)
return out << s <<
'"';
765 out.write(&s[last], len - last);
782 char *res = getcwd(buf,
sizeof(buf));
785 perror(
"Failed to get working directory");
799 size_t ll = s.length();
800 if (ll == l)
return ".";
803 size_t pos = s.rfind(
'/', l);
804 assert(pos != std::string::npos);
805 return s.substr(pos + 1);
807 if (ll == l + 1)
return ".";
808 return s.substr(l + 1);
817 char const *delim =
"/\\";
821 size_t prev = 0, len = s.length();
822 size_t pos = s.find_first_of(delim);
823 if (pos == std::string::npos)
return s;
824 bool absolute = pos == 0;
830 std::string n = s.substr(prev, pos - prev);
833 if (!l.empty()) l.pop_back();
841 if (pos >= len)
break;
843 pos = s.find_first_of(delim, prev);
844 if (pos == std::string::npos) pos = len;
846 string_list::const_iterator i = l.begin(), i_end = l.end();
847 if (i == i_end)
return absolute ?
"/" :
".";
849 if (absolute) n.push_back(
'/');
851 for (++i; i != i_end; ++i)
865 for (string_list::iterator i = l.begin(),
866 i_end = l.end(); i != i_end; ++i)
886 while (strchr(
" \t", (c = in.get()))) {}
887 if (in.good()) in.putback(c);
896 while (strchr(
"\r\n", (c = in.get()))) {}
897 if (in.good()) in.putback(c);
904 static bool skip_eol(std::istream &in,
bool multi =
false)
907 if (c ==
'\r') c = in.get();
908 if (c !=
'\n' && in.good()) in.putback(c);
909 if (c !=
'\n' && !in.eof())
return false;
944 case ':': tok =
Colon;
break;
945 case ',': tok =
Comma;
break;
946 case '=': tok =
Equal;
break;
981 if (!in.good())
return res;
982 char const *separators =
" \t\r\n:$(),=+\"";
983 bool quoted = c ==
'"';
986 if (strchr(separators, c))
996 if (!in.good())
return res;
1008 if (strchr(separators, c))
1061 if (local_variables)
1064 cur2 = local_variables->begin();
1065 end2 = local_variables->end();
1066 for (assign_list::const_iterator i =
cur2; i !=
end2; ++i)
1068 if (i->name ==
name && !i->append)
1078 cur2 = dummy.begin();
1082 cur1 = dummy.begin();
1088 cur1 = i->second.begin();
1089 end1 = i->second.end();
1177 res.push_back(std::string());
1206 : gen(top.in, top.local_variables)
1262 : gen(top.in, top.local_variables)
1308 if (!g || ok)
return g;
1329 std::cerr <<
"Failed to load database" << std::endl;
1337 if (in.eof())
return;
1338 if (targets.empty())
goto error;
1339 DEBUG <<
"reading dependencies of target " << targets.front() << std::endl;
1340 if (in.get() !=
':')
goto error;
1345 dep->
deps.insert(deps.begin(), deps.end());
1346 for (string_list::const_iterator i = targets.begin(),
1347 i_end = targets.end(); i != i_end; ++i)
1361 std::ifstream in(
".remake");
1377 std::ofstream db(
".remake");
1381 for (string_list::const_iterator i = dep->
targets.begin(),
1382 i_end = dep->
targets.end(); i != i_end; ++i)
1388 for (string_set::const_iterator i = dep->
deps.begin(),
1389 i_end = dep->
deps.end(); i != i_end; ++i)
1415 assert(rule.
script.empty());
1416 for (string_list::const_iterator i = targets.begin(),
1417 i_end = targets.end(); i != i_end; ++i)
1419 std::pair<rule_map::iterator, bool> j =
1430 std::cerr <<
"Failed to load rules: " << *i
1431 <<
" cannot be the target of several rules" << std::endl;
1439 for (string_list::const_iterator i = targets.begin(),
1440 i_end = targets.end(); i != i_end; ++i)
1460 for (string_list::const_iterator i = rule.
targets.begin(),
1461 i_end = rule.
targets.end(); i != i_end; ++i)
1463 std::pair<rule_map::iterator, bool> j =
1465 if (j.second)
continue;
1466 std::cerr <<
"Failed to load rules: " << *i
1467 <<
" cannot be the target of several rules" << std::endl;
1474 for (string_list::const_iterator i = rule.
targets.begin(),
1475 i_end = rule.
targets.end(); i != i_end; ++i)
1487 static void load_rule(std::istream &in, std::string
const &first)
1489 DEBUG_open <<
"Reading rule for target " << first <<
"... ";
1494 std::cerr <<
"Failed to load rules: syntax error" << std::endl;
1502 if (!first.empty()) targets.push_front(first);
1503 else if (targets.empty())
goto error;
1504 else DEBUG <<
"actual target: " << targets.front() << std::endl;
1505 bool generic =
false;
1507 for (string_list::const_iterator i = targets.begin(),
1508 i_end = targets.end(); i != i_end; ++i)
1510 if (i->empty())
goto error;
1511 if ((i->find(
'%') != std::string::npos) !=
generic)
1513 if (i == targets.begin())
generic =
true;
1517 std::swap(rule.
targets, targets);
1519 if (in.get() !=
':')
goto error;
1521 bool assignment =
false;
1555 if (!
skip_eol(in,
true))
goto error;
1558 std::ostringstream buf;
1562 if (!in.good())
break;
1563 if (c ==
'\t' || c ==
' ')
1565 in.get(*buf.rdbuf());
1566 if (in.fail() && !in.eof()) in.clear();
1568 else if (c ==
'\r' || c ==
'\n')
1581 if (assignment)
goto error;
1586 if (!rule.
script.empty())
1588 if (assignment)
goto error;
1595 std::swap(rule.
targets, targets);
1597 std::swap(rule.
targets, targets);
1616 std::cerr <<
"Failed to load rules: syntax error" << std::endl;
1619 std::ifstream in(remakefile.c_str());
1622 std::cerr <<
"Failed to load rules: no Remakefile found" << std::endl;
1633 while (in.get() !=
'\n') {}
1637 if (c ==
' ' || c ==
'\t')
goto error;
1641 if (name.empty())
goto error;
1644 DEBUG <<
"Assignment to variable " << name << std::endl;
1648 if (tok ==
Equal) dest.swap(value);
1649 else dest.splice(dest.end(), value);
1650 if (!
skip_eol(in,
true))
goto error;
1671 for (string_list::const_iterator i = src.begin(),
1672 i_end = src.end(); i != i_end; ++i)
1674 size_t pos = i->find(
'%');
1675 if (pos == std::string::npos)dst.push_back(*i);
1676 else dst.push_back(i->substr(0, pos) + pat + i->substr(pos + 1));
1687 size_t tlen = target.length(), plen = tlen + 1;
1692 for (string_list::const_iterator j = i->targets.begin(),
1693 j_end = i->targets.end(); j != j_end; ++j)
1695 size_t len = j->length();
1696 if (tlen < len)
continue;
1697 if (plen <= tlen - (len - 1))
continue;
1698 size_t pos = j->find(
'%');
1699 if (pos == std::string::npos)
continue;
1700 size_t len2 = len - (pos + 1);
1701 if (j->compare(0, pos, target, 0, pos) ||
1702 j->compare(pos + 1, len2, target, tlen - len2, len2))
1704 plen = tlen - (len - 1);
1706 rule.stem = target.substr(pos, plen);
1707 rule.script = i->script;
1726 if (i != i_end && !i->second->script.empty())
return *i->second;
1729 if (grule.targets.empty())
1731 if (i != i_end)
return *i->second;
1735 if (grule.targets.size() == 1)
1737 if (i == i_end)
return grule;
1738 grule.
deps.insert(grule.deps.end(),
1739 i->second->deps.begin(), i->second->deps.end());
1740 grule.vars.insert(grule.vars.end(),
1741 i->second->vars.begin(), i->second->vars.end());
1746 for (string_list::const_iterator j = grule.targets.begin(),
1747 j_end = grule.targets.end(); j != j_end; ++j)
1750 if (i == i_end)
continue;
1751 if (!i->second->script.empty())
return rule_t();
1752 grule.
deps.insert(grule.deps.end(),
1753 i->second->deps.begin(), i->second->deps.end());
1754 grule.vars.insert(grule.vars.end(),
1755 i->second->vars.begin(), i->second->vars.end());
1780 std::pair<status_map::iterator,bool> i =
1783 if (!i.second)
return ts;
1784 DEBUG_open <<
"Checking status of " << target <<
"... ";
1785 dependency_map::const_iterator j =
dependencies.find(target);
1789 if (stat(target.c_str(), &s) != 0)
1798 ts.
last = s.st_mtime;
1804 for (string_list::const_iterator k = dep.
targets.begin(),
1805 k_end = dep.
targets.end(); k != k_end; ++k)
1808 if (stat(k->c_str(), &s) != 0)
1814 status[*k].last = s.st_mtime;
1815 if (s.st_mtime > latest) latest = s.st_mtime;
1817 if (st ==
Todo)
goto update;
1818 for (string_set::const_iterator k = dep.
deps.begin(),
1819 k_end = dep.
deps.end(); k != k_end; ++k)
1822 if (latest < ts_.
last)
1830 DEBUG <<
"obsolete dependency " << *k << std::endl;
1835 for (string_list::const_iterator k = dep.
targets.begin(),
1836 k_end = dep.
targets.end(); k != k_end; ++k)
1849 DEBUG_open <<
"Rechecking status of " << target <<
"... ";
1850 status_map::iterator i =
status.find(target);
1851 assert(i !=
status.end());
1860 if (stat(target.c_str(), &s) != 0)
1865 else if (s.st_mtime != ts.last)
1868 ts.last = s.st_mtime;
1882 DEBUG_open <<
"Rechecking obsoleteness of " << target <<
"... ";
1883 status_map::const_iterator i =
status.find(target);
1884 assert(i !=
status.end());
1885 if (i->second.status !=
Recheck)
return true;
1886 dependency_map::const_iterator j =
dependencies.find(target);
1889 for (string_set::const_iterator k = dep.deps.begin(),
1890 k_end = dep.deps.end(); k != k_end; ++k)
1894 for (string_list::const_iterator k = dep.targets.begin(),
1895 k_end = dep.targets.end(); k != k_end; ++k)
1916 DEBUG_open <<
"Completing job " << job_id <<
"... ";
1917 job_targets_map::iterator i =
job_targets.find(job_id);
1922 for (string_list::const_iterator j = targets.begin(),
1923 j_end = targets.end(); j != j_end; ++j)
1931 std::cerr <<
"Failed to build";
1932 for (string_list::const_iterator j = targets.begin(),
1933 j_end = targets.end(); j != j_end; ++j)
1936 std::cerr <<
' ' << *j;
1939 std::cerr << std::endl;
1949 std::string
const &s = rule.
script;
1950 std::istringstream in(s);
1951 std::ostringstream out;
1952 size_t len = s.size();
1956 size_t pos = in.tellg(), p = s.find(
'$', pos);
1957 if (p == std::string::npos || p == len - 1) p = len;
1958 out.write(&s[pos], p - pos);
1959 if (p == len)
break;
1968 if (!rule.
deps.empty())
1969 out << rule.
deps.front();
1975 for (string_list::const_iterator i = rule.
deps.begin(),
1976 i_end = rule.
deps.end(); i != i_end; ++i)
1978 if (first) first =
false;
1986 assert(!rule.
targets.empty());
2008 if (s ==
Eof)
break;
2009 if (first) first =
false;
2034 std::cout <<
"Building";
2035 for (string_list::const_iterator i = rule.
targets.begin(),
2036 i_end = rule.
targets.end(); i != i_end; ++i)
2038 std::cout <<
' ' << *i;
2040 std::cout << std::endl;
2046 for (string_list::const_iterator i = rule.
targets.begin(),
2047 i_end = rule.
targets.end(); i != i_end; ++i)
2054 std::ostringstream job_id_buf;
2055 job_id_buf << job_id;
2056 std::string job_id_ = job_id_buf.str();
2058 DEBUG_open <<
"Starting script for job " << job_id <<
"... ";
2072 CloseHandle(pfd[0]);
2073 CloseHandle(pfd[1]);
2076 if (!CreatePipe(&pfd[0], &pfd[1], NULL, 0))
2078 if (!SetHandleInformation(pfd[0], HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
2081 ZeroMemory(&si,
sizeof(STARTUPINFO));
2082 si.cb =
sizeof(STARTUPINFO);
2083 si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
2084 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
2085 si.hStdInput = pfd[0];
2086 si.dwFlags |= STARTF_USESTDHANDLES;
2087 PROCESS_INFORMATION pi;
2088 ZeroMemory(&pi,
sizeof(PROCESS_INFORMATION));
2089 if (!SetEnvironmentVariable(
"REMAKE_JOB_ID", job_id_.c_str()))
2091 char const *argv =
echo_scripts ?
"SH.EXE -e -s -v" :
"SH.EXE -e -s";
2092 if (!CreateProcess(NULL, (
char *)argv, NULL, NULL,
2093 true, 0, NULL, NULL, &si, &pi))
2097 CloseHandle(pi.hThread);
2098 DWORD len = script.length(), wlen;
2099 if (!WriteFile(pfd[1], script.c_str(), len, &wlen, NULL) || wlen < len)
2100 std::cerr <<
"Unexpected failure while sending script to shell" << std::endl;
2101 CloseHandle(pfd[0]);
2102 CloseHandle(pfd[1]);
2115 if (pipe(pfd) == -1)
2117 if (pid_t pid = fork())
2119 if (pid == -1)
goto error2;
2120 ssize_t len = script.length();
2121 if (write(pfd[1], script.c_str(), len) < len)
2122 std::cerr <<
"Unexpected failure while sending script to shell" << std::endl;
2130 if (setenv(
"REMAKE_JOB_ID", job_id_.c_str(), 1))
2131 _exit(EXIT_FAILURE);
2132 char const *argv[5] = {
"sh",
"-e",
"-s", NULL, NULL };
2140 execv(
"/bin/sh", (
char **)argv);
2141 _exit(EXIT_FAILURE);
2151 static bool start(std::string
const &target, client_list::iterator ¤t)
2159 std::cerr <<
"No rule for building " << target << std::endl;
2162 for (string_list::const_iterator i = rule.
targets.begin(),
2163 i_end = rule.
targets.end(); i != i_end; ++i)
2169 if (!rule.
deps.empty())
2172 current->job_id = job_id;
2173 current->pending = rule.
deps;
2174 current->delayed =
new rule_t(rule);
2186 DEBUG_open <<
"Completing request from client of job " << client.
job_id <<
"... ";
2201 char res = success ? 1 : 0;
2202 send(client.
socket, &res, 1, 0);
2204 closesocket(client.
socket);
2236 DEBUG_open <<
"Handling client requests... ";
2239 for (client_list::iterator i =
clients.begin(), i_next = i,
2243 DEBUG_open <<
"Handling client from job " << i->job_id <<
"... ";
2254 for (string_set::iterator j = i->running.begin(), j_next = j,
2255 j_end = i->running.end(); j != j_end; j = j_next)
2258 status_map::const_iterator k =
status.find(*j);
2259 assert(k !=
status.end());
2260 switch (k->second.status)
2270 i->running.erase(j);
2279 while (!i->pending.empty())
2281 std::string target = i->pending.front();
2282 i->pending.pop_front();
2286 i->running.insert(target);
2298 client_list::iterator j = i;
2299 if (!
start(target, i))
goto pending_failed;
2300 j->running.insert(target);
2311 if (i->running.empty())
2313 if (i->failed)
goto failed;
2326 std::cerr <<
"Circular dependency detected" << std::endl;
2327 client_list::iterator i =
clients.begin();
2343 perror(
"Failed to create server");
2353 struct sockaddr_in socket_addr;
2354 socket_addr.sin_family = AF_INET;
2355 socket_addr.sin_addr.s_addr = inet_addr(
"127.0.0.1");
2356 socket_addr.sin_port = 0;
2359 socket_fd = socket(AF_INET, SOCK_STREAM, 0);
2361 if (!SetHandleInformation((HANDLE)
socket_fd, HANDLE_FLAG_INHERIT, 0))
2363 if (bind(socket_fd, (
struct sockaddr *)&socket_addr,
sizeof(sockaddr_in)))
2365 int len =
sizeof(sockaddr_in);
2366 if (getsockname(socket_fd, (
struct sockaddr *)&socket_addr, &len))
2368 std::ostringstream buf;
2369 buf << socket_addr.sin_port;
2370 if (!SetEnvironmentVariable(
"REMAKE_SOCKET", buf.str().c_str()))
2372 if (listen(socket_fd, 1000))
goto error;
2377 sigemptyset(&sigmask);
2378 sigaddset(&sigmask, SIGCHLD);
2379 if (sigprocmask(SIG_BLOCK, &sigmask, NULL) == -1)
goto error;
2380 struct sigaction sa;
2382 sigemptyset(&sa.sa_mask);
2384 if (sigaction(SIGCHLD, &sa, NULL) == -1)
goto error;
2386 if (sigaction(SIGINT, &sa, NULL) == -1)
goto error;
2391 struct sockaddr_un socket_addr;
2393 if (len >=
sizeof(socket_addr.sun_path) - 1)
goto error2;
2394 socket_addr.sun_family = AF_UNIX;
2396 len +=
sizeof(socket_addr.sun_family);
2397 if (setenv(
"REMAKE_SOCKET",
socket_name, 1))
goto error;
2401 socket_fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
2404 socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
2406 if (fcntl(socket_fd, F_SETFD, FD_CLOEXEC) < 0)
goto error;
2408 if (bind(socket_fd, (
struct sockaddr *)&socket_addr, len))
2410 if (listen(socket_fd, 1000))
goto error;
2426 if (!SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0))
2429 std::cerr <<
"Unexpected failure while setting connection with client" << std::endl;
2435 if (ioctlsocket(fd, FIONBIO, &nbio))
goto error2;
2436 #elif defined(LINUX)
2437 int fd = accept4(
socket_fd, NULL, NULL, SOCK_CLOEXEC);
2442 if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
return;
2445 client_list::iterator proc =
clients.begin();
2451 std::cerr <<
"Received an ill-formed client message" << std::endl;
2462 std::vector<char> buf;
2464 while (len <
sizeof(
int) + 2 || buf[len - 1] || buf[len - 2])
2466 buf.resize(len + 1024);
2467 ssize_t l = recv(fd, &buf[0] + len, 1024, 0);
2468 if (l <= 0)
goto error;
2474 memcpy(&job_id, &buf[0],
sizeof(
int));
2476 proc->job_id = job_id;
2477 job_targets_map::const_iterator i =
job_targets.find(job_id);
2479 DEBUG <<
"receiving request from job " << job_id << std::endl;
2483 char const *p = &buf[0] +
sizeof(int);
2492 std::string target(p, p + len);
2493 DEBUG <<
"adding dependency " << target <<
" to job\n";
2494 proc->pending.push_back(target);
2495 dep.
deps.insert(target);
2505 pid_job_map::iterator i =
job_pids.find(pid);
2507 int job_id = i->second;
2527 for (pid_job_map::const_iterator i =
job_pids.begin(),
2528 i_end =
job_pids.end(); i != i_end; ++i, ++num)
2532 WSAEVENT aev = WSACreateEvent();
2534 WSAEventSelect(
socket_fd, aev, FD_ACCEPT);
2535 DWORD w = WaitForMultipleObjects(len, h,
false, INFINITE);
2547 bool res = GetExitCodeProcess(pid, &s) && s == 0;
2552 sigemptyset(&emptymask);
2556 int ret = pselect(
socket_fd + 1, &fdset, NULL, NULL, NULL, &emptymask);
2562 while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
2564 bool res = WIFEXITED(status) && WEXITSTATUS(status) == 0;
2587 clients.back().pending.push_back(remakefile);
2597 if (!targets.empty())
clients.back().pending = targets;
2628 perror(
"Failed to send targets to server");
2631 if (targets.empty()) exit(EXIT_SUCCESS);
2636 struct sockaddr_in socket_addr;
2637 socket_fd = socket(AF_INET, SOCK_STREAM, 0);
2639 socket_addr.sin_family = AF_INET;
2640 socket_addr.sin_addr.s_addr = inet_addr(
"127.0.0.1");
2641 socket_addr.sin_port = atoi(socket_name);
2642 if (connect(
socket_fd, (
struct sockaddr *)&socket_addr,
sizeof(sockaddr_in)))
2645 struct sockaddr_un socket_addr;
2646 size_t len = strlen(socket_name);
2647 if (len >=
sizeof(socket_addr.sun_path) - 1) exit(EXIT_FAILURE);
2648 socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
2650 socket_addr.sun_family = AF_UNIX;
2651 strcpy(socket_addr.sun_path, socket_name);
2652 if (connect(
socket_fd, (
struct sockaddr *)&socket_addr,
sizeof(socket_addr.sun_family) + len))
2656 if (setsockopt(
socket_fd, SOL_SOCKET, SO_NOSIGPIPE, &set_option,
sizeof(set_option)))
2662 char *
id = getenv(
"REMAKE_JOB_ID");
2663 int job_id =
id ? atoi(
id) : -1;
2664 if (send(
socket_fd, (
char *)&job_id,
sizeof(job_id), MSG_NOSIGNAL) !=
sizeof(job_id))
2668 for (string_list::const_iterator i = targets.begin(),
2669 i_end = targets.end(); i != i_end; ++i)
2672 ssize_t len = i->length() + 1;
2673 if (send(
socket_fd, i->c_str(), len, MSG_NOSIGNAL) != len)
2679 if (send(
socket_fd, &result, 1, MSG_NOSIGNAL) != 1)
goto error;
2680 if (recv(
socket_fd, &result, 1, 0) != 1) exit(EXIT_FAILURE);
2681 exit(result ? EXIT_SUCCESS : EXIT_FAILURE);
2697 std::cerr <<
"Usage: remake [options] [target] ...\n"
2699 " -d Echo script commands.\n"
2700 " -d -d Print lots of debugging information.\n"
2701 " -f FILE Read FILE as Remakefile.\n"
2702 " -h, --help Print this message and exit.\n"
2703 " -j[N], --jobs=[N] Allow N jobs at once; infinite jobs with no arg.\n"
2704 " -k Keep going when some targets cannot be made.\n"
2705 " -r Look up targets from the dependencies on standard input.\n"
2706 " -s, --silent, --quiet Do not echo targets.\n";
2725 std::string remakefile =
"Remakefile";
2727 bool indirect_targets =
false;
2730 for (
int i = 1; i < argc; ++i)
2732 std::string arg = argv[i];
2733 if (arg.empty())
usage(EXIT_FAILURE);
2734 if (arg ==
"-h" || arg ==
"--help")
usage(EXIT_SUCCESS);
2738 else if (arg ==
"-k" || arg ==
"--keep-going")
2740 else if (arg ==
"-s" || arg ==
"--silent" || arg ==
"--quiet")
2742 else if (arg ==
"-r")
2743 indirect_targets =
true;
2744 else if (arg ==
"-f")
2746 if (++i == argc)
usage(EXIT_FAILURE);
2747 remakefile = argv[i];
2749 else if (arg.compare(0, 2,
"-j") == 0)
2751 else if (arg.compare(0, 7,
"--jobs=") == 0)
2755 if (arg[0] ==
'-')
usage(EXIT_FAILURE);
2757 DEBUG <<
"New target: " << arg <<
'\n';
2761 if (indirect_targets)
2768 l.push_back(
dependencies.begin()->second->targets.front());
2770 for (string_list::const_iterator i = l.begin(),
2771 i_end = l.end(); i != i_end; ++i)
2773 dependency_map::const_iterator j =
dependencies.find(*i);
2776 for (string_set::const_iterator k = dep.
deps.begin(),
2777 k_end = dep.
deps.end(); k != k_end; ++k)
2787 if (WSAStartup(MAKEWORD(2,2), &wsaData))
2789 std::cerr <<
"Unexpected failure while initializing Windows Socket" << std::endl;
2795 if (
char *sn = getenv(
"REMAKE_SOCKET"))
client_mode(sn, targets);