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>
411 #if defined(WINDOWS) || defined(MACOSX)
412 enum { MSG_NOSIGNAL = 0 };
441 if (
ptr == p.
ptr)
return *
this;
515 typedef std::map<std::string, ref_ptr<rule_t> >
rule_map;
659 static time_t
now = time(NULL);
688 if (
open) std::cerr << std::endl;
690 std::cerr << std::string(
depth * 2,
' ');
696 if (o &&
open) std::cerr << std::endl;
699 if (o || !
open) std::cerr << std::string(
depth * 2,
' ');
720 #define DEBUG if (debug.active) debug()
721 #define DEBUG_open log_auto_close auto_close; if (debug.active) debug(true)
722 #define DEBUG_close if ((auto_close.still_open = false), debug.active) debug(false)
741 std::string
const &s = se.
input;
742 char const *quoted_char =
",: '";
743 char const *escaped_char =
"\"\\$!";
744 bool need_quotes =
false;
746 size_t len = s.length(), last = 0, j = 0;
747 for (
size_t i = 0; i < len; ++i)
749 if (strchr(escaped_char, s[i]))
752 if (!buf) buf =
new char[len * 2];
753 memcpy(&buf[j], &s[last], i - last);
759 if (!need_quotes && strchr(quoted_char, s[i]))
762 if (!need_quotes)
return out << s;
764 if (!buf)
return out << s <<
'"';
766 out.write(&s[last], len - last);
783 char *res = getcwd(buf,
sizeof(buf));
786 perror(
"Failed to get working directory");
800 size_t ll = s.length();
801 if (ll == l)
return ".";
804 size_t pos = s.rfind(
'/', l);
805 assert(pos != std::string::npos);
806 return s.substr(pos + 1);
808 if (ll == l + 1)
return ".";
809 return s.substr(l + 1);
818 char const *delim =
"/\\";
822 size_t prev = 0, len = s.length();
823 size_t pos = s.find_first_of(delim);
824 if (pos == std::string::npos)
return s;
825 bool absolute = pos == 0;
831 std::string n = s.substr(prev, pos - prev);
834 if (!l.empty()) l.pop_back();
842 if (pos >= len)
break;
844 pos = s.find_first_of(delim, prev);
845 if (pos == std::string::npos) pos = len;
847 string_list::const_iterator i = l.begin(), i_end = l.end();
848 if (i == i_end)
return absolute ?
"/" :
".";
850 if (absolute) n.push_back(
'/');
852 for (++i; i != i_end; ++i)
866 for (string_list::iterator i = l.begin(),
867 i_end = l.end(); i != i_end; ++i)
887 while (strchr(
" \t", (c = in.get()))) {}
888 if (in.good()) in.putback(c);
897 while (strchr(
"\r\n", (c = in.get()))) {}
898 if (in.good()) in.putback(c);
905 static bool skip_eol(std::istream &in,
bool multi =
false)
908 if (c ==
'\r') c = in.get();
909 if (c !=
'\n' && in.good()) in.putback(c);
910 if (c !=
'\n' && !in.eof())
return false;
945 case ':': tok =
Colon;
break;
946 case ',': tok =
Comma;
break;
947 case '=': tok =
Equal;
break;
982 if (!in.good())
return res;
983 char const *separators =
" \t\r\n:$(),=+\"";
984 bool quoted = c ==
'"';
987 if (strchr(separators, c))
997 if (!in.good())
return res;
1009 if (strchr(separators, c))
1062 if (local_variables)
1065 cur2 = local_variables->begin();
1066 end2 = local_variables->end();
1067 for (assign_list::const_iterator i =
cur2; i !=
end2; ++i)
1069 if (i->name ==
name && !i->append)
1079 cur2 = dummy.begin();
1083 cur1 = dummy.begin();
1089 cur1 = i->second.begin();
1090 end1 = i->second.end();
1178 res.push_back(std::string());
1207 : gen(top.in, top.local_variables)
1263 : gen(top.in, top.local_variables)
1309 if (!g || ok)
return g;
1330 std::cerr <<
"Failed to load database" << std::endl;
1338 if (in.eof())
return;
1339 if (targets.empty())
goto error;
1340 DEBUG <<
"reading dependencies of target " << targets.front() << std::endl;
1341 if (in.get() !=
':')
goto error;
1346 dep->
deps.insert(deps.begin(), deps.end());
1347 for (string_list::const_iterator i = targets.begin(),
1348 i_end = targets.end(); i != i_end; ++i)
1362 std::ifstream in(
".remake");
1378 std::ofstream db(
".remake");
1382 for (string_list::const_iterator i = dep->
targets.begin(),
1383 i_end = dep->
targets.end(); i != i_end; ++i)
1389 for (string_set::const_iterator i = dep->
deps.begin(),
1390 i_end = dep->
deps.end(); i != i_end; ++i)
1416 assert(rule.
script.empty());
1417 for (string_list::const_iterator i = targets.begin(),
1418 i_end = targets.end(); i != i_end; ++i)
1420 std::pair<rule_map::iterator, bool> j =
1431 std::cerr <<
"Failed to load rules: " << *i
1432 <<
" cannot be the target of several rules" << std::endl;
1440 for (string_list::const_iterator i = targets.begin(),
1441 i_end = targets.end(); i != i_end; ++i)
1461 for (string_list::const_iterator i = rule.
targets.begin(),
1462 i_end = rule.
targets.end(); i != i_end; ++i)
1464 std::pair<rule_map::iterator, bool> j =
1466 if (j.second)
continue;
1467 std::cerr <<
"Failed to load rules: " << *i
1468 <<
" cannot be the target of several rules" << std::endl;
1475 for (string_list::const_iterator i = rule.
targets.begin(),
1476 i_end = rule.
targets.end(); i != i_end; ++i)
1488 static void load_rule(std::istream &in, std::string
const &first)
1490 DEBUG_open <<
"Reading rule for target " << first <<
"... ";
1495 std::cerr <<
"Failed to load rules: syntax error" << std::endl;
1503 if (!first.empty()) targets.push_front(first);
1504 else if (targets.empty())
goto error;
1505 else DEBUG <<
"actual target: " << targets.front() << std::endl;
1506 bool generic =
false;
1508 for (string_list::const_iterator i = targets.begin(),
1509 i_end = targets.end(); i != i_end; ++i)
1511 if (i->empty())
goto error;
1512 if ((i->find(
'%') != std::string::npos) !=
generic)
1514 if (i == targets.begin())
generic =
true;
1518 std::swap(rule.
targets, targets);
1520 if (in.get() !=
':')
goto error;
1522 bool assignment =
false;
1556 if (!
skip_eol(in,
true))
goto error;
1559 std::ostringstream buf;
1563 if (!in.good())
break;
1564 if (c ==
'\t' || c ==
' ')
1566 in.get(*buf.rdbuf());
1567 if (in.fail() && !in.eof()) in.clear();
1569 else if (c ==
'\r' || c ==
'\n')
1582 if (assignment)
goto error;
1587 if (!rule.
script.empty())
1589 if (assignment)
goto error;
1596 std::swap(rule.
targets, targets);
1598 std::swap(rule.
targets, targets);
1617 std::cerr <<
"Failed to load rules: syntax error" << std::endl;
1620 std::ifstream in(remakefile.c_str());
1623 std::cerr <<
"Failed to load rules: no Remakefile found" << std::endl;
1634 while (in.get() !=
'\n') {}
1638 if (c ==
' ' || c ==
'\t')
goto error;
1642 if (name.empty())
goto error;
1645 DEBUG <<
"Assignment to variable " << name << std::endl;
1649 if (tok ==
Equal) dest.swap(value);
1650 else dest.splice(dest.end(), value);
1651 if (!
skip_eol(in,
true))
goto error;
1672 for (string_list::const_iterator i = src.begin(),
1673 i_end = src.end(); i != i_end; ++i)
1675 size_t pos = i->find(
'%');
1676 if (pos == std::string::npos)dst.push_back(*i);
1677 else dst.push_back(i->substr(0, pos) + pat + i->substr(pos + 1));
1688 size_t tlen = target.length(), plen = tlen + 1;
1693 for (string_list::const_iterator j = i->targets.begin(),
1694 j_end = i->targets.end(); j != j_end; ++j)
1696 size_t len = j->length();
1697 if (tlen < len)
continue;
1698 if (plen <= tlen - (len - 1))
continue;
1699 size_t pos = j->find(
'%');
1700 if (pos == std::string::npos)
continue;
1701 size_t len2 = len - (pos + 1);
1702 if (j->compare(0, pos, target, 0, pos) ||
1703 j->compare(pos + 1, len2, target, tlen - len2, len2))
1705 plen = tlen - (len - 1);
1707 rule.stem = target.substr(pos, plen);
1708 rule.script = i->script;
1727 if (i != i_end && !i->second->script.empty())
return *i->second;
1730 if (grule.targets.empty())
1732 if (i != i_end)
return *i->second;
1736 if (grule.targets.size() == 1)
1738 if (i == i_end)
return grule;
1739 grule.
deps.insert(grule.deps.end(),
1740 i->second->deps.begin(), i->second->deps.end());
1741 grule.vars.insert(grule.vars.end(),
1742 i->second->vars.begin(), i->second->vars.end());
1747 for (string_list::const_iterator j = grule.targets.begin(),
1748 j_end = grule.targets.end(); j != j_end; ++j)
1751 if (i == i_end)
continue;
1752 if (!i->second->script.empty())
return rule_t();
1753 grule.
deps.insert(grule.deps.end(),
1754 i->second->deps.begin(), i->second->deps.end());
1755 grule.vars.insert(grule.vars.end(),
1756 i->second->vars.begin(), i->second->vars.end());
1781 std::pair<status_map::iterator,bool> i =
1784 if (!i.second)
return ts;
1785 DEBUG_open <<
"Checking status of " << target <<
"... ";
1786 dependency_map::const_iterator j =
dependencies.find(target);
1790 if (stat(target.c_str(), &s) != 0)
1799 ts.
last = s.st_mtime;
1805 for (string_list::const_iterator k = dep.
targets.begin(),
1806 k_end = dep.
targets.end(); k != k_end; ++k)
1809 if (stat(k->c_str(), &s) != 0)
1815 status[*k].last = s.st_mtime;
1816 if (s.st_mtime > latest) latest = s.st_mtime;
1818 if (st ==
Todo)
goto update;
1819 for (string_set::const_iterator k = dep.
deps.begin(),
1820 k_end = dep.
deps.end(); k != k_end; ++k)
1823 if (latest < ts_.
last)
1831 DEBUG <<
"obsolete dependency " << *k << std::endl;
1836 for (string_list::const_iterator k = dep.
targets.begin(),
1837 k_end = dep.
targets.end(); k != k_end; ++k)
1850 DEBUG_open <<
"Rechecking status of " << target <<
"... ";
1851 status_map::iterator i =
status.find(target);
1852 assert(i !=
status.end());
1861 if (stat(target.c_str(), &s) != 0)
1866 else if (s.st_mtime != ts.last)
1869 ts.last = s.st_mtime;
1883 DEBUG_open <<
"Rechecking obsoleteness of " << target <<
"... ";
1884 status_map::const_iterator i =
status.find(target);
1885 assert(i !=
status.end());
1886 if (i->second.status !=
Recheck)
return true;
1887 dependency_map::const_iterator j =
dependencies.find(target);
1890 for (string_set::const_iterator k = dep.deps.begin(),
1891 k_end = dep.deps.end(); k != k_end; ++k)
1895 for (string_list::const_iterator k = dep.targets.begin(),
1896 k_end = dep.targets.end(); k != k_end; ++k)
1917 DEBUG_open <<
"Completing job " << job_id <<
"... ";
1918 job_targets_map::iterator i =
job_targets.find(job_id);
1923 for (string_list::const_iterator j = targets.begin(),
1924 j_end = targets.end(); j != j_end; ++j)
1932 std::cerr <<
"Failed to build";
1933 for (string_list::const_iterator j = targets.begin(),
1934 j_end = targets.end(); j != j_end; ++j)
1937 std::cerr <<
' ' << *j;
1940 std::cerr << std::endl;
1950 std::string
const &s = rule.
script;
1951 std::istringstream in(s);
1952 std::ostringstream out;
1953 size_t len = s.size();
1957 size_t pos = in.tellg(), p = s.find(
'$', pos);
1958 if (p == std::string::npos || p == len - 1) p = len;
1959 out.write(&s[pos], p - pos);
1960 if (p == len)
break;
1969 if (!rule.
deps.empty())
1970 out << rule.
deps.front();
1976 for (string_list::const_iterator i = rule.
deps.begin(),
1977 i_end = rule.
deps.end(); i != i_end; ++i)
1979 if (first) first =
false;
1987 assert(!rule.
targets.empty());
2009 if (s ==
Eof)
break;
2010 if (first) first =
false;
2035 std::cout <<
"Building";
2036 for (string_list::const_iterator i = rule.
targets.begin(),
2037 i_end = rule.
targets.end(); i != i_end; ++i)
2039 std::cout <<
' ' << *i;
2041 std::cout << std::endl;
2047 for (string_list::const_iterator i = rule.
targets.begin(),
2048 i_end = rule.
targets.end(); i != i_end; ++i)
2055 std::ostringstream job_id_buf;
2056 job_id_buf << job_id;
2057 std::string job_id_ = job_id_buf.str();
2059 DEBUG_open <<
"Starting script for job " << job_id <<
"... ";
2073 CloseHandle(pfd[0]);
2074 CloseHandle(pfd[1]);
2077 if (!CreatePipe(&pfd[0], &pfd[1], NULL, 0))
2079 if (!SetHandleInformation(pfd[0], HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
2082 ZeroMemory(&si,
sizeof(STARTUPINFO));
2083 si.cb =
sizeof(STARTUPINFO);
2084 si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
2085 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
2086 si.hStdInput = pfd[0];
2087 si.dwFlags |= STARTF_USESTDHANDLES;
2088 PROCESS_INFORMATION pi;
2089 ZeroMemory(&pi,
sizeof(PROCESS_INFORMATION));
2090 if (!SetEnvironmentVariable(
"REMAKE_JOB_ID", job_id_.c_str()))
2092 char const *argv =
echo_scripts ?
"SH.EXE -e -s -v" :
"SH.EXE -e -s";
2093 if (!CreateProcess(NULL, (
char *)argv, NULL, NULL,
2094 true, 0, NULL, NULL, &si, &pi))
2098 CloseHandle(pi.hThread);
2099 DWORD len = script.length(), wlen;
2100 if (!WriteFile(pfd[1], script.c_str(), len, &wlen, NULL) || wlen < len)
2101 std::cerr <<
"Unexpected failure while sending script to shell" << std::endl;
2102 CloseHandle(pfd[0]);
2103 CloseHandle(pfd[1]);
2116 if (pipe(pfd) == -1)
2118 if (setenv(
"REMAKE_JOB_ID", job_id_.c_str(), 1))
2120 if (pid_t pid = vfork())
2122 if (pid == -1)
goto error2;
2123 ssize_t len = script.length();
2124 if (write(pfd[1], script.c_str(), len) < len)
2125 std::cerr <<
"Unexpected failure while sending script to shell" << std::endl;
2133 char const *argv[5] = {
"sh",
"-e",
"-s", NULL, NULL };
2141 execve(
"/bin/sh", (
char **)argv,
environ);
2142 _exit(EXIT_FAILURE);
2152 static bool start(std::string
const &target, client_list::iterator ¤t)
2160 std::cerr <<
"No rule for building " << target << std::endl;
2163 for (string_list::const_iterator i = rule.
targets.begin(),
2164 i_end = rule.
targets.end(); i != i_end; ++i)
2170 if (!rule.
deps.empty())
2173 current->job_id = job_id;
2174 current->pending = rule.
deps;
2175 current->delayed =
new rule_t(rule);
2187 DEBUG_open <<
"Completing request from client of job " << client.
job_id <<
"... ";
2202 char res = success ? 1 : 0;
2203 send(client.
socket, &res, 1, MSG_NOSIGNAL);
2205 closesocket(client.
socket);
2237 DEBUG_open <<
"Handling client requests... ";
2240 for (client_list::iterator i =
clients.begin(), i_next = i,
2244 DEBUG_open <<
"Handling client from job " << i->job_id <<
"... ";
2255 for (string_set::iterator j = i->running.begin(), j_next = j,
2256 j_end = i->running.end(); j != j_end; j = j_next)
2259 status_map::const_iterator k =
status.find(*j);
2260 assert(k !=
status.end());
2261 switch (k->second.status)
2271 i->running.erase(j);
2280 while (!i->pending.empty())
2282 std::string target = i->pending.front();
2283 i->pending.pop_front();
2287 i->running.insert(target);
2299 client_list::iterator j = i;
2300 if (!
start(target, i))
goto pending_failed;
2301 j->running.insert(target);
2312 if (i->running.empty())
2314 if (i->failed)
goto failed;
2327 std::cerr <<
"Circular dependency detected" << std::endl;
2328 client_list::iterator i =
clients.begin();
2344 perror(
"Failed to create server");
2354 struct sockaddr_in socket_addr;
2355 socket_addr.sin_family = AF_INET;
2356 socket_addr.sin_addr.s_addr = inet_addr(
"127.0.0.1");
2357 socket_addr.sin_port = 0;
2360 socket_fd = socket(AF_INET, SOCK_STREAM, 0);
2362 if (!SetHandleInformation((HANDLE)
socket_fd, HANDLE_FLAG_INHERIT, 0))
2364 if (bind(socket_fd, (
struct sockaddr *)&socket_addr,
sizeof(sockaddr_in)))
2366 int len =
sizeof(sockaddr_in);
2367 if (getsockname(socket_fd, (
struct sockaddr *)&socket_addr, &len))
2369 std::ostringstream buf;
2370 buf << socket_addr.sin_port;
2371 if (!SetEnvironmentVariable(
"REMAKE_SOCKET", buf.str().c_str()))
2373 if (listen(socket_fd, 1000))
goto error;
2378 sigemptyset(&sigmask);
2379 sigaddset(&sigmask, SIGCHLD);
2380 if (sigprocmask(SIG_BLOCK, &sigmask, NULL) == -1)
goto error;
2381 struct sigaction sa;
2383 sigemptyset(&sa.sa_mask);
2385 if (sigaction(SIGCHLD, &sa, NULL) == -1)
goto error;
2387 if (sigaction(SIGINT, &sa, NULL) == -1)
goto error;
2392 struct sockaddr_un socket_addr;
2394 if (len >=
sizeof(socket_addr.sun_path) - 1)
goto error2;
2395 socket_addr.sun_family = AF_UNIX;
2397 len +=
sizeof(socket_addr.sun_family);
2398 if (setenv(
"REMAKE_SOCKET",
socket_name, 1))
goto error;
2402 socket_fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
2405 socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
2407 if (fcntl(socket_fd, F_SETFD, FD_CLOEXEC) < 0)
goto error;
2409 if (bind(socket_fd, (
struct sockaddr *)&socket_addr, len))
2411 if (listen(socket_fd, 1000))
goto error;
2427 if (!SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0))
2430 std::cerr <<
"Unexpected failure while setting connection with client" << std::endl;
2436 if (ioctlsocket(fd, FIONBIO, &nbio))
goto error2;
2437 #elif defined(LINUX)
2438 int fd = accept4(
socket_fd, NULL, NULL, SOCK_CLOEXEC);
2443 if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
return;
2446 client_list::iterator proc =
clients.begin();
2452 std::cerr <<
"Received an ill-formed client message" << std::endl;
2463 std::vector<char> buf;
2465 while (len <
sizeof(
int) + 2 || buf[len - 1] || buf[len - 2])
2467 buf.resize(len + 1024);
2468 ssize_t l = recv(fd, &buf[0] + len, 1024, 0);
2469 if (l <= 0)
goto error;
2475 memcpy(&job_id, &buf[0],
sizeof(
int));
2477 proc->job_id = job_id;
2478 job_targets_map::const_iterator i =
job_targets.find(job_id);
2480 DEBUG <<
"receiving request from job " << job_id << std::endl;
2484 char const *p = &buf[0] +
sizeof(int);
2493 std::string target(p, p + len);
2494 DEBUG <<
"adding dependency " << target <<
" to job\n";
2495 proc->pending.push_back(target);
2496 dep.
deps.insert(target);
2506 pid_job_map::iterator i =
job_pids.find(pid);
2508 int job_id = i->second;
2528 for (pid_job_map::const_iterator i =
job_pids.begin(),
2529 i_end =
job_pids.end(); i != i_end; ++i, ++num)
2533 WSAEVENT aev = WSACreateEvent();
2535 WSAEventSelect(
socket_fd, aev, FD_ACCEPT);
2536 DWORD w = WaitForMultipleObjects(len, h,
false, INFINITE);
2548 bool res = GetExitCodeProcess(pid, &s) && s == 0;
2553 sigemptyset(&emptymask);
2557 int ret = pselect(
socket_fd + 1, &fdset, NULL, NULL, NULL, &emptymask);
2563 while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
2565 bool res = WIFEXITED(status) && WEXITSTATUS(status) == 0;
2588 clients.back().pending.push_back(remakefile);
2598 if (!targets.empty())
clients.back().pending = targets;
2629 perror(
"Failed to send targets to server");
2632 if (targets.empty()) exit(EXIT_SUCCESS);
2637 struct sockaddr_in socket_addr;
2638 socket_fd = socket(AF_INET, SOCK_STREAM, 0);
2640 socket_addr.sin_family = AF_INET;
2641 socket_addr.sin_addr.s_addr = inet_addr(
"127.0.0.1");
2642 socket_addr.sin_port = atoi(socket_name);
2643 if (connect(
socket_fd, (
struct sockaddr *)&socket_addr,
sizeof(sockaddr_in)))
2646 struct sockaddr_un socket_addr;
2647 size_t len = strlen(socket_name);
2648 if (len >=
sizeof(socket_addr.sun_path) - 1) exit(EXIT_FAILURE);
2649 socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
2651 socket_addr.sun_family = AF_UNIX;
2652 strcpy(socket_addr.sun_path, socket_name);
2653 if (connect(
socket_fd, (
struct sockaddr *)&socket_addr,
sizeof(socket_addr.sun_family) + len))
2657 if (setsockopt(
socket_fd, SOL_SOCKET, SO_NOSIGPIPE, &set_option,
sizeof(set_option)))
2663 char *
id = getenv(
"REMAKE_JOB_ID");
2664 int job_id =
id ? atoi(
id) : -1;
2665 if (send(
socket_fd, (
char *)&job_id,
sizeof(job_id), MSG_NOSIGNAL) !=
sizeof(job_id))
2669 for (string_list::const_iterator i = targets.begin(),
2670 i_end = targets.end(); i != i_end; ++i)
2673 ssize_t len = i->length() + 1;
2674 if (send(
socket_fd, i->c_str(), len, MSG_NOSIGNAL) != len)
2680 if (send(
socket_fd, &result, 1, MSG_NOSIGNAL) != 1)
goto error;
2681 if (recv(
socket_fd, &result, 1, 0) != 1) exit(EXIT_FAILURE);
2682 exit(result ? EXIT_SUCCESS : EXIT_FAILURE);
2698 std::cerr <<
"Usage: remake [options] [target] ...\n"
2700 " -d Echo script commands.\n"
2701 " -d -d Print lots of debugging information.\n"
2702 " -f FILE Read FILE as Remakefile.\n"
2703 " -h, --help Print this message and exit.\n"
2704 " -j[N], --jobs=[N] Allow N jobs at once; infinite jobs with no arg.\n"
2705 " -k Keep going when some targets cannot be made.\n"
2706 " -r Look up targets from the dependencies on stdin.\n"
2707 " -s, --silent, --quiet Do not echo targets.\n";
2726 std::string remakefile =
"Remakefile";
2728 bool indirect_targets =
false;
2731 for (
int i = 1; i < argc; ++i)
2733 std::string arg = argv[i];
2734 if (arg.empty())
usage(EXIT_FAILURE);
2735 if (arg ==
"-h" || arg ==
"--help")
usage(EXIT_SUCCESS);
2739 else if (arg ==
"-k" || arg ==
"--keep-going")
2741 else if (arg ==
"-s" || arg ==
"--silent" || arg ==
"--quiet")
2743 else if (arg ==
"-r")
2744 indirect_targets =
true;
2745 else if (arg ==
"-f")
2747 if (++i == argc)
usage(EXIT_FAILURE);
2748 remakefile = argv[i];
2750 else if (arg.compare(0, 2,
"-j") == 0)
2752 else if (arg.compare(0, 7,
"--jobs=") == 0)
2756 if (arg[0] ==
'-')
usage(EXIT_FAILURE);
2758 DEBUG <<
"New target: " << arg <<
'\n';
2762 if (indirect_targets)
2769 l.push_back(
dependencies.begin()->second->targets.front());
2771 for (string_list::const_iterator i = l.begin(),
2772 i_end = l.end(); i != i_end; ++i)
2774 dependency_map::const_iterator j =
dependencies.find(*i);
2777 for (string_set::const_iterator k = dep.
deps.begin(),
2778 k_end = dep.
deps.end(); k != k_end; ++k)
2788 if (WSAStartup(MAKEWORD(2,2), &wsaData))
2790 std::cerr <<
"Unexpected failure while initializing Windows Socket" << std::endl;
2796 if (
char *sn = getenv(
"REMAKE_SOCKET"))
client_mode(sn, targets);