30 "usage: ninja -t msvc [options] -- cl.exe /showIncludes /otherArgs\n"
32 " -e ENVFILE load environment block from ENVFILE as environment\n"
33 " -o FILE write output dependency information to FILE.d\n"
37 void PushPathIntoEnvironment(
const string& env_block) {
38 const char* as_str = env_block.c_str();
40 if (_strnicmp(as_str,
"path=", 5) == 0) {
44 as_str = &as_str[strlen(as_str) + 1];
49 void WriteDepFileOrDie(
const char* object_path,
const CLParser& parse) {
50 string depfile_path = string(object_path) +
".d";
51 FILE* depfile = fopen(depfile_path.c_str(),
"w");
54 Fatal(
"opening %s: %s", depfile_path.c_str(),
55 GetLastErrorString().c_str());
57 if (fprintf(depfile,
"%s: ", object_path) < 0) {
60 unlink(depfile_path.c_str());
61 Fatal(
"writing %s", depfile_path.c_str());
63 const set<string>& headers = parse.
includes_;
64 for (set<string>::const_iterator i = headers.begin();
65 i != headers.end(); ++i) {
69 unlink(depfile_path.c_str());
70 Fatal(
"writing %s", depfile_path.c_str());
79 const char* output_filename = NULL;
80 const char* envfile = NULL;
82 const option kLongOptions[] = {
87 while ((opt =
getopt_long(argc, argv,
"e:o:h", kLongOptions, NULL)) != -1) {
105 if (
ReadFile(envfile, &env, &err) != 0)
106 Fatal(
"couldn't open %s: %s", envfile, err.c_str());
107 PushPathIntoEnvironment(env);
110 char* command = GetCommandLine();
111 command = strstr(command,
" -- ");
113 Fatal(
"expected command line to end with \" -- command args\"");
121 int exit_code = cl.
Run(command, &output);
123 if (output_filename) {
125 output = parser.
Parse(output);
126 WriteDepFileOrDie(output_filename, parser);
131 _setmode(_fileno(stdout), _O_BINARY);
132 printf(
"%s", output.c_str());
int MSVCHelperMain(int argc, char **argv)
string Parse(const string &output)
Parse the full output of cl, returning the output (if any) that should printed.
int getopt_long(int argc, char **argv, const char *shortopts, const GETOPT_LONG_OPTION_T *longopts, int *longind)
int ReadFile(const string &path, string *contents, string *err)
Read a file to a string (in text mode: with CRLF conversion on Windows).
int Run(const string &command, string *output)
Start a process and gather its raw output.
void Fatal(const char *msg,...)
Log a fatal message and exit.
Visual Studio's cl.exe requires some massaging to work with Ninja; for example, it emits include info...
Wraps a synchronous execution of a CL subprocess.
string EscapeForDepfile(const string &path)
void SetEnvBlock(void *env_block)
Set the environment block (as suitable for CreateProcess) to be used by Run().