301 #define WIN32_LEAN_AND_MEAN
320 #include <sys/stat.h>
321 #include <sys/types.h>
334 #include <winsock2.h>
338 #include <sys/socket.h>
340 #include <sys/wait.h>
345 #if defined(WINDOWS) || defined(MACOSX)
346 enum { MSG_NOSIGNAL = 0 };
375 if (
ptr == p.
ptr)
return *
this;
435 typedef std::map<std::string, ref_ptr<rule_t> >
rule_map;
582 static time_t
now = time(NULL);
604 if (
open) std::cerr << std::endl;
606 std::cerr << std::string(
depth * 2,
' ');
612 if (o &&
open) std::cerr << std::endl;
615 if (o || !
open) std::cerr << std::string(
depth * 2,
' ');
636 #define DEBUG if (debug.active) debug()
637 #define DEBUG_open log_auto_close auto_close; if (debug.active) debug(true)
638 #define DEBUG_close if ((auto_close.still_open = false), debug.active) debug(false)
646 char const *quoted_char =
",: '";
647 char const *escaped_char =
"\"\\$!";
648 bool need_quotes =
false;
649 size_t len = s.length(), nb = len;
650 for (
size_t i = 0; i < len; ++i)
652 if (strchr(quoted_char, s[i])) need_quotes =
true;
653 if (strchr(escaped_char, s[i])) ++nb;
655 if (nb != len) need_quotes =
true;
656 if (!need_quotes)
return s;
657 std::string t(nb + 2,
'\\');
659 for (
size_t i = 0, j = 1; i < len; ++i, ++j)
661 if (strchr(escaped_char, s[i])) ++j;
674 char *res = getcwd(buf,
sizeof(buf));
677 perror(
"Failed to get working directory");
691 size_t ll = s.length();
692 if (ll == l)
return ".";
695 size_t pos = s.rfind(
'/', l);
696 assert(pos != std::string::npos);
697 return s.substr(pos + 1);
699 if (ll == l + 1)
return ".";
700 return s.substr(l + 1);
709 char const *delim =
"/\\";
713 size_t prev = 0, len = s.length();
714 size_t pos = s.find_first_of(delim);
715 if (pos == std::string::npos)
return s;
716 bool absolute = pos == 0;
722 std::string n = s.substr(prev, pos - prev);
725 if (!l.empty()) l.pop_back();
733 if (pos >= len)
break;
735 pos = s.find_first_of(delim, prev);
736 if (pos == std::string::npos) pos = len;
738 string_list::const_iterator i = l.begin(), i_end = l.end();
739 if (i == i_end)
return absolute ?
"/" :
".";
741 if (absolute) n.push_back(
'/');
743 for (++i; i != i_end; ++i)
757 for (string_list::iterator i = l.begin(),
758 i_end = l.end(); i != i_end; ++i)
770 while (strchr(
" \t", (c = in.get()))) {}
771 if (in.good()) in.putback(c);
780 while (strchr(
"\r\n", (c = in.get()))) {}
781 if (in.good()) in.putback(c);
795 if (!in.good())
return Eof;
798 case ':':
return Colon;
799 case ',':
return Comma;
800 case '=':
return Equal;
809 if (c !=
'\r' && c !=
'\n')
829 if (!in.good())
return res;
830 char const *separators =
" \t\r\n:$(),=\"";
831 bool quoted = c ==
'"';
834 if (strchr(separators, c))
844 if (!in.good())
return res;
856 if (strchr(separators, c))
876 std::cerr <<
"Failed to load rules: syntax error" << std::endl;
886 size_t fixl = fix.size();
887 if (name ==
"addprefix")
889 for (string_list::const_iterator i = names.begin(),
890 i_end = names.end(); i != i_end; ++i)
897 string_list::const_iterator k = fix.begin();
898 for (
size_t j = 1; j != fixl; ++j)
900 dest.push_back(*k++);
902 dest.push_back(*k++ + *i);
905 else if (name ==
"addsuffix")
907 for (string_list::const_iterator i = names.begin(),
908 i_end = names.end(); i != i_end; ++i)
915 string_list::const_iterator k = fix.begin();
916 dest.push_back(*i + *k++);
917 for (
size_t j = 1; j != fixl; ++j)
919 dest.push_back(*k++);
934 std::cerr <<
"Failed to load rules: syntax error" << std::endl;
948 if (in.get() !=
'(')
goto error;
950 if (name.empty())
goto error;
955 variable_map::const_iterator i =
variables.find(name);
957 res.insert(res.end(), i->second.begin(), i->second.end());
975 if (targets.empty())
return;
976 DEBUG <<
"reading dependencies of target " << targets.front() << std::endl;
979 std::cerr <<
"Failed to load database" << std::endl;
985 dep->
deps.insert(d.begin(), d.end());
986 for (string_list::const_iterator i = targets.begin(),
987 i_end = targets.end(); i != i_end; ++i)
1001 std::ifstream in(
".remake");
1014 static void load_rule(std::istream &in, std::string
const &first)
1016 DEBUG_open <<
"Reading rule for target " << first <<
"... ";
1021 std::cerr <<
"Failed to load rules: syntax error" << std::endl;
1028 if (!first.empty()) targets.push_front(first);
1029 else if (targets.empty())
goto error;
1030 else DEBUG <<
"actual target: " << targets.front() << std::endl;
1031 bool generic =
false;
1033 for (string_list::const_iterator i = targets.begin(),
1034 i_end = targets.end(); i != i_end; ++i)
1036 if (i->empty())
goto error;
1037 if ((i->find(
'%') != std::string::npos) !=
generic)
1039 if (i == targets.begin())
generic =
true;
1043 std::swap(rule.
targets, targets);
1045 if (in.get() !=
':')
goto error;
1052 if (c !=
'\r' && c !=
'\n')
goto error;
1056 std::ostringstream buf;
1060 if (!in.good())
break;
1061 if (c ==
'\t' || c ==
' ')
1063 in.get(*buf.rdbuf());
1064 if (in.fail() && !in.eof()) in.clear();
1066 else if (c ==
'\r' || c ==
'\n')
1086 if (!rule.
script.empty())
1091 for (string_list::const_iterator i = rule.
targets.begin(),
1092 i_end = rule.
targets.end(); i != i_end; ++i)
1101 for (string_list::const_iterator i = rule.
targets.begin(),
1102 i_end = rule.
targets.end(); i != i_end; ++i)
1114 for (string_list::const_iterator i = rule.
targets.begin(),
1115 i_end = rule.
targets.end(); i != i_end; ++i)
1117 std::pair<rule_map::iterator,bool> j =
1119 if (j.second)
continue;
1120 std::cerr <<
"Failed to load rules: " << *i
1121 <<
" cannot be the target of several rules" << std::endl;
1132 std::ofstream db(
".remake");
1136 for (string_list::const_iterator i = dep->
targets.begin(),
1137 i_end = dep->
targets.end(); i != i_end; ++i)
1143 for (string_set::const_iterator i = dep->
deps.begin(),
1144 i_end = dep->
deps.end(); i != i_end; ++i)
1163 std::cerr <<
"Failed to load rules: syntax error" << std::endl;
1166 std::ifstream in(
"Remakefile");
1169 std::cerr <<
"Failed to load rules: no Remakefile found" << std::endl;
1180 while (in.get() !=
'\n') {}
1184 if (c ==
' ' || c ==
'\t')
goto error;
1189 if (name.empty())
goto error;
1193 DEBUG <<
"Assignment to variable " << name << std::endl;
1205 std::ostringstream buf;
1206 for (variable_map::const_iterator i =
variables.begin(),
1207 i_end =
variables.end(); i != i_end; ++i)
1209 std::ostringstream var;
1211 for (string_list::const_iterator j = i->second.begin(),
1212 j_end = i->second.end(); j != j_end; ++j)
1214 if (first) first =
false;
1218 buf << i->first <<
'=' <<
escape_string(var.str()) << std::endl;
1228 for (string_list::const_iterator i = src.begin(),
1229 i_end = src.end(); i != i_end; ++i)
1231 size_t pos = i->find(
'%');
1232 if (pos == std::string::npos)dst.push_back(*i);
1233 else dst.push_back(i->substr(0, pos) + pat + i->substr(pos + 1));
1244 size_t tlen = target.length(), plen = tlen + 1;
1249 for (string_list::const_iterator j = i->targets.begin(),
1250 j_end = i->targets.end(); j != j_end; ++j)
1252 size_t len = j->length();
1253 if (tlen < len)
continue;
1254 if (plen <= tlen - (len - 1))
continue;
1255 size_t pos = j->find(
'%');
1256 if (pos == std::string::npos)
continue;
1257 size_t len2 = len - (pos + 1);
1258 if (j->compare(0, pos, target, 0, pos) ||
1259 j->compare(pos + 1, len2, target, tlen - len2, len2))
1261 plen = tlen - (len - 1);
1262 std::string pat = target.substr(pos, plen);
1283 if (i != i_end && !i->second->script.empty())
return *i->second;
1286 if (grule.targets.empty())
1288 if (i != i_end)
return *i->second;
1292 if (grule.targets.size() == 1)
1295 grule.
deps.insert(grule.deps.end(),
1296 i->second->deps.begin(), i->second->deps.end());
1301 for (string_list::const_iterator j = grule.targets.begin(),
1302 j_end = grule.targets.end(); j != j_end; ++j)
1305 if (i == i_end)
continue;
1306 if (!i->second->script.empty())
return rule_t();
1307 grule.
deps.insert(grule.deps.end(),
1308 i->second->deps.begin(), i->second->deps.end());
1325 std::pair<status_map::iterator,bool> i =
1328 if (!i.second)
return ts;
1329 DEBUG_open <<
"Checking status of " << target <<
"... ";
1330 dependency_map::const_iterator j =
dependencies.find(target);
1334 if (stat(target.c_str(), &s) != 0)
1343 ts.
last = s.st_mtime;
1349 for (string_list::const_iterator k = dep.
targets.begin(),
1350 k_end = dep.
targets.end(); k != k_end; ++k)
1353 if (stat(k->c_str(), &s) != 0)
1359 status[*k].last = s.st_mtime;
1360 if (s.st_mtime > latest) latest = s.st_mtime;
1362 if (st ==
Todo)
goto update;
1363 for (string_set::const_iterator k = dep.
deps.begin(),
1364 k_end = dep.
deps.end(); k != k_end; ++k)
1367 if (latest < ts_.
last)
1375 DEBUG <<
"obsolete dependency " << *k << std::endl;
1380 for (string_list::const_iterator k = dep.
targets.begin(),
1381 k_end = dep.
targets.end(); k != k_end; ++k)
1394 DEBUG_open <<
"Rechecking status of " << target <<
"... ";
1395 status_map::iterator i =
status.find(target);
1396 assert (i !=
status.end());
1405 if (stat(target.c_str(), &s) != 0)
1410 else if (s.st_mtime != ts.last)
1413 ts.last = s.st_mtime;
1427 DEBUG_open <<
"Rechecking obsoleteness of " << target <<
"... ";
1428 status_map::const_iterator i =
status.find(target);
1429 assert (i !=
status.end());
1430 if (i->second.status !=
Recheck)
return true;
1431 dependency_map::const_iterator j =
dependencies.find(target);
1434 for (string_set::const_iterator k = dep.deps.begin(),
1435 k_end = dep.deps.end(); k != k_end; ++k)
1439 for (string_list::const_iterator k = dep.targets.begin(),
1440 k_end = dep.targets.end(); k != k_end; ++k)
1453 DEBUG_open <<
"Completing job " << job_id <<
"... ";
1454 job_targets_map::iterator i =
job_targets.find(job_id);
1459 for (string_list::const_iterator j = targets.begin(),
1460 j_end = targets.end(); j != j_end; ++j)
1468 std::cerr <<
"Failed to build";
1469 for (string_list::const_iterator j = targets.begin(),
1470 j_end = targets.end(); j != j_end; ++j)
1473 std::cerr <<
' ' << *j;
1476 std::cerr << std::endl;
1488 std::cout <<
"Building";
1489 for (string_list::const_iterator i = rule.
targets.begin(),
1490 i_end = rule.
targets.end(); i != i_end; ++i)
1492 std::cout <<
' ' << *i;
1494 std::cout << std::endl;
1500 for (string_list::const_iterator i = rule.
targets.begin(),
1501 i_end = rule.
targets.end(); i != i_end; ++i)
1506 DEBUG_open <<
"Starting script for job " << job_id <<
"... ";
1512 CloseHandle(pfd[0]);
1513 CloseHandle(pfd[1]);
1519 if (!CreatePipe(&pfd[0], &pfd[1], NULL, 0))
1521 if (!SetHandleInformation(pfd[0], HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
1524 ZeroMemory(&si,
sizeof(STARTUPINFO));
1525 si.cb =
sizeof(STARTUPINFO);
1526 si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
1527 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
1528 si.hStdInput = pfd[0];
1529 si.dwFlags |= STARTF_USESTDHANDLES;
1530 PROCESS_INFORMATION pi;
1531 ZeroMemory(&pi,
sizeof(PROCESS_INFORMATION));
1532 std::ostringstream buf;
1534 if (!SetEnvironmentVariable(
"REMAKE_JOB_ID", buf.str().c_str()))
1536 std::ostringstream argv;
1537 argv <<
"SH.EXE -e -s";
1539 for (string_list::const_iterator i = rule.
targets.begin(),
1540 i_end = rule.
targets.end(); i != i_end; ++i)
1544 if (!CreateProcess(NULL, (
char *)argv.str().c_str(), NULL, NULL,
1545 true, 0, NULL, NULL, &si, &pi))
1549 CloseHandle(pi.hThread);
1551 DWORD len = script.length(), wlen;
1552 if (!WriteFile(pfd[1], script.c_str(), len, &wlen, NULL) || wlen < len)
1553 std::cerr <<
"Unexpected failure while sending script to shell" << std::endl;
1554 CloseHandle(pfd[0]);
1555 CloseHandle(pfd[1]);
1571 if (pipe(pfd) == -1)
1573 if (pid_t pid = fork())
1575 if (pid == -1)
goto error2;
1577 ssize_t len = script.length();
1578 if (write(pfd[1], script.c_str(), len) < len)
1579 std::cerr <<
"Unexpected failure while sending script to shell" << std::endl;
1587 std::ostringstream buf;
1589 if (setenv(
"REMAKE_JOB_ID", buf.str().c_str(), 1))
1590 _exit(EXIT_FAILURE);
1592 char const **argv =
new char const *[num + rule.
targets.size() + 1];
1597 for (string_list::const_iterator i = rule.
targets.begin(),
1598 i_end = rule.
targets.end(); i != i_end; ++i, ++num)
1600 argv[num] = i->c_str();
1609 execv(
"/bin/sh", (
char **)argv);
1610 _exit(EXIT_FAILURE);
1620 static bool start(std::string
const &target, client_list::iterator ¤t)
1628 std::cerr <<
"No rule for building " << target << std::endl;
1631 for (string_list::const_iterator i = rule.
targets.begin(),
1632 i_end = rule.
targets.end(); i != i_end; ++i)
1638 if (!rule.
deps.empty())
1641 current->job_id = job_id;
1642 current->pending = rule.
deps;
1643 current->delayed =
new rule_t(rule);
1655 DEBUG_open <<
"Completing request from client of job " << client.
job_id <<
"... ";
1670 char res = success ? 1 : 0;
1671 send(client.
socket, &res, 1, 0);
1673 closesocket(client.
socket);
1702 for (client_list::iterator i =
clients.begin(), i_next = i,
1706 DEBUG_open <<
"Handling client from job " << i->job_id <<
"... ";
1717 for (string_set::iterator j = i->running.begin(), j_next = j,
1718 j_end = i->running.end(); j != j_end; j = j_next)
1721 status_map::const_iterator k =
status.find(*j);
1722 assert(k !=
status.end());
1723 switch (k->second.status)
1733 i->running.erase(j);
1742 while (!i->pending.empty())
1744 std::string target = i->pending.front();
1745 i->pending.pop_front();
1749 i->running.insert(target);
1761 client_list::iterator j = i;
1762 if (!
start(target, i))
goto pending_failed;
1763 j->running.insert(target);
1774 if (i->running.empty())
1776 if (i->failed)
goto failed;
1794 perror(
"Failed to create server");
1804 struct sockaddr_in socket_addr;
1805 socket_addr.sin_family = AF_INET;
1806 socket_addr.sin_addr.s_addr = inet_addr(
"127.0.0.1");
1807 socket_addr.sin_port = 0;
1810 socket_fd = socket(AF_INET, SOCK_STREAM, 0);
1812 if (!SetHandleInformation((HANDLE)
socket_fd, HANDLE_FLAG_INHERIT, 0))
1814 if (bind(socket_fd, (
struct sockaddr *)&socket_addr,
sizeof(sockaddr_in)))
1816 int len =
sizeof(sockaddr_in);
1817 if (getsockname(socket_fd, (
struct sockaddr *)&socket_addr, &len))
1819 std::ostringstream buf;
1820 buf << socket_addr.sin_port;
1821 if (!SetEnvironmentVariable(
"REMAKE_SOCKET", buf.str().c_str()))
1823 if (listen(socket_fd, 1000))
goto error;
1827 sigemptyset(&sigmask);
1828 sigaddset(&sigmask, SIGCHLD);
1829 if (sigprocmask(SIG_BLOCK, &sigmask, NULL) == -1)
goto error;
1830 struct sigaction sa;
1833 sigemptyset(&sa.sa_mask);
1834 if (sigaction(SIGCHLD, &sa, NULL) == -1)
goto error;
1839 struct sockaddr_un socket_addr;
1841 if (len >=
sizeof(socket_addr.sun_path) - 1)
goto error2;
1842 socket_addr.sun_family = AF_UNIX;
1844 len +=
sizeof(socket_addr.sun_family);
1845 if (setenv(
"REMAKE_SOCKET",
socket_name, 1))
goto error;
1849 socket_fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
1850 if (socket_fd < 0)
goto error;
1852 socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
1853 if (socket_fd < 0)
goto error;
1854 if (fcntl(socket_fd, F_SETFD, FD_CLOEXEC) < 0)
goto error;
1856 if (bind(socket_fd, (
struct sockaddr *)&socket_addr, len))
1858 if (listen(socket_fd, 1000))
goto error;
1874 if (!SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0))
1877 std::cerr <<
"Unexpected failure while setting connection with client" << std::endl;
1883 if (ioctlsocket(fd, FIONBIO, &nbio))
goto error2;
1884 #elif defined(LINUX)
1885 int fd = accept4(
socket_fd, NULL, NULL, SOCK_CLOEXEC);
1890 if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
return;
1893 client_list::iterator proc =
clients.begin();
1899 std::cerr <<
"Received an ill-formed client message" << std::endl;
1910 std::vector<char> buf;
1912 while (len <
sizeof(
int) + 2 || buf[len - 1] || buf[len - 2])
1914 buf.resize(len + 1024);
1915 ssize_t l = recv(fd, &buf[0] + len, 1024, 0);
1916 if (l <= 0)
goto error;
1922 memcpy(&job_id, &buf[0],
sizeof(
int));
1924 proc->job_id = job_id;
1925 job_targets_map::const_iterator i =
job_targets.find(job_id);
1927 DEBUG <<
"receiving request from job " << job_id << std::endl;
1931 char const *p = &buf[0] +
sizeof(int);
1940 std::string target(p, p + len);
1941 DEBUG <<
"adding dependency " << target <<
" to job\n";
1942 proc->pending.push_back(target);
1943 dep.
deps.insert(target);
1966 for (pid_job_map::const_iterator i =
job_pids.begin(),
1967 i_end =
job_pids.end(); i != i_end; ++i, ++num)
1971 WSAEVENT aev = WSACreateEvent();
1973 WSAEventSelect(
socket_fd, aev, FD_ACCEPT);
1974 DWORD w = WaitForMultipleObjects(len, h,
false, INFINITE);
1977 if (w < WAIT_OBJECT_0 || WAIT_OBJECT_0 + len <= w)
1979 if (w == WAIT_OBJECT_0 + len - 1)
1984 pid_t pid = h[w - WAIT_OBJECT_0];
1986 bool res = GetExitCodeProcess(pid, &s) && s == 0;
1988 pid_job_map::iterator i =
job_pids.find(pid);
1990 int job_id = i->second;
1996 sigemptyset(&emptymask);
2000 int ret = pselect(
socket_fd + 1, &fdset, NULL, NULL, NULL, &emptymask);
2006 while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
2008 bool res = WIFEXITED(status) && WEXITSTATUS(status) == 0;
2009 pid_job_map::iterator i =
job_pids.find(pid);
2011 int job_id = i->second;
2034 clients.back().pending.push_back(
"Remakefile");
2044 if (!targets.empty())
clients.back().pending = targets;
2064 perror(
"Failed to send targets to server");
2067 if (targets.empty()) exit(EXIT_SUCCESS);
2072 struct sockaddr_in socket_addr;
2073 socket_fd = socket(AF_INET, SOCK_STREAM, 0);
2075 socket_addr.sin_family = AF_INET;
2076 socket_addr.sin_addr.s_addr = inet_addr(
"127.0.0.1");
2077 socket_addr.sin_port = atoi(socket_name);
2078 if (connect(
socket_fd, (
struct sockaddr *)&socket_addr,
sizeof(sockaddr_in)))
2081 struct sockaddr_un socket_addr;
2082 size_t len = strlen(socket_name);
2083 if (len >=
sizeof(socket_addr.sun_path) - 1) exit(EXIT_FAILURE);
2084 socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
2086 socket_addr.sun_family = AF_UNIX;
2087 strcpy(socket_addr.sun_path, socket_name);
2088 if (connect(
socket_fd, (
struct sockaddr *)&socket_addr,
sizeof(socket_addr.sun_family) + len))
2092 if (setsockopt(
socket_fd, SOL_SOCKET, SO_NOSIGPIPE, &set_option,
sizeof(set_option)))
2098 char *
id = getenv(
"REMAKE_JOB_ID");
2099 int job_id =
id ? atoi(
id) : -1;
2100 if (send(
socket_fd, (
char *)&job_id,
sizeof(job_id), MSG_NOSIGNAL) !=
sizeof(job_id))
2104 for (string_list::const_iterator i = targets.begin(),
2105 i_end = targets.end(); i != i_end; ++i)
2108 ssize_t len = i->length() + 1;
2109 if (send(
socket_fd, i->c_str(), len, MSG_NOSIGNAL) != len)
2115 if (send(
socket_fd, &result, 1, MSG_NOSIGNAL) != 1)
goto error;
2116 if (recv(
socket_fd, &result, 1, 0) != 1) exit(EXIT_FAILURE);
2117 exit(result ? EXIT_SUCCESS : EXIT_FAILURE);
2125 std::cerr <<
"Usage: remake [options] [target] ...\n"
2127 " -d Echo script commands.\n"
2128 " -d -d Print lots of debugging information.\n"
2129 " -h, --help Print this message and exit.\n"
2130 " -j[N], --jobs=[N] Allow N jobs at once; infinite jobs with no arg.\n"
2131 " -k Keep going when some targets cannot be made.\n"
2132 " -r Look up targets from the dependencies on standard input.\n"
2133 " -s, --silent, --quiet Do not echo targets.\n";
2153 bool indirect_targets =
false;
2156 for (
int i = 1; i < argc; ++i)
2158 std::string arg = argv[i];
2159 if (arg.empty())
usage(EXIT_FAILURE);
2160 if (arg ==
"-h" || arg ==
"--help")
usage(EXIT_SUCCESS);
2164 else if (arg ==
"-k" || arg ==
"--keep-going")
2166 else if (arg ==
"-s" || arg ==
"--silent" || arg ==
"--quiet")
2168 else if (arg ==
"-r")
2169 indirect_targets =
true;
2170 else if (arg.compare(0, 2,
"-j") == 0)
2172 else if (arg.compare(0, 7,
"--jobs=") == 0)
2176 if (arg[0] ==
'-')
usage(1);
2178 DEBUG <<
"New target: " << arg <<
'\n';
2182 if (indirect_targets)
2189 l.push_back(
dependencies.begin()->second->targets.front());
2191 for (string_list::const_iterator i = l.begin(),
2192 i_end = l.end(); i != i_end; ++i)
2194 dependency_map::const_iterator j =
dependencies.find(*i);
2197 for (string_set::const_iterator k = dep.
deps.begin(),
2198 k_end = dep.
deps.end(); k != k_end; ++k)
2208 if (WSAStartup(MAKEWORD(2,2), &wsaData))
2210 std::cerr <<
"Unexpected failure while initializing Windows Socket" << std::endl;
2216 if (
char *sn = getenv(
"REMAKE_SOCKET"))
client_mode(sn, targets);