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" 34 " -p STRING localized prefix of msvc's /showIncludes output\n" 38 void PushPathIntoEnvironment(
const string& env_block) {
39 const char* as_str = env_block.c_str();
41 if (_strnicmp(as_str,
"path=", 5) == 0) {
45 as_str = &as_str[strlen(as_str) + 1];
50 void WriteDepFileOrDie(
const char* object_path,
const CLParser& parse) {
51 string depfile_path = string(object_path) +
".d";
52 FILE* depfile = fopen(depfile_path.c_str(),
"w");
55 Fatal(
"opening %s: %s", depfile_path.c_str(),
56 GetLastErrorString().c_str());
58 if (fprintf(depfile,
"%s: ", object_path) < 0) {
61 unlink(depfile_path.c_str());
62 Fatal(
"writing %s", depfile_path.c_str());
64 const set<string>& headers = parse.
includes_;
65 for (set<string>::const_iterator i = headers.begin();
66 i != headers.end(); ++i) {
70 unlink(depfile_path.c_str());
71 Fatal(
"writing %s", depfile_path.c_str());
80 const char* output_filename = NULL;
81 const char* envfile = NULL;
83 const option kLongOptions[] = {
89 while ((opt =
getopt_long(argc, argv,
"e:o:p:h", kLongOptions, NULL)) != -1) {
110 if (
ReadFile(envfile, &env, &err) != 0)
111 Fatal(
"couldn't open %s: %s", envfile, err.c_str());
112 PushPathIntoEnvironment(env);
115 char* command = GetCommandLine();
116 command = strstr(command,
" -- ");
118 Fatal(
"expected command line to end with \" -- command args\"");
126 int exit_code = cl.
Run(command, &output);
128 if (output_filename) {
130 output = parser.
Parse(output, deps_prefix);
131 WriteDepFileOrDie(output_filename, parser);
139 _setmode(_fileno(stdout), _O_BINARY);
142 fwrite(&output[0], 1, output.size(), stdout);
int MSVCHelperMain(int argc, char **argv)
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...
string Parse(const string &output, const string &deps_prefix)
Parse the full output of cl, returning the output (if any) that should printed.
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().