blob: 2627bfd42e21f406bea9aa3509b717229f156118 [file] [log] [blame]
Shinichiro Hamaji1d545aa2015-06-23 15:29:13 +09001// Copyright 2015 Google Inc. All rights reserved
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +090015// +build ignore
16
Shinichiro Hamaji0e74c542015-06-22 16:17:08 +090017#include <limits.h>
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090018#include <stdio.h>
19#include <string.h>
Shinichiro Hamaji087cecd2015-07-06 19:51:58 +090020#include <stdlib.h>
Shinichiro Hamajia4bb7742015-07-31 11:27:30 +090021#include <time.h>
Shinichiro Hamaji0e74c542015-06-22 16:17:08 +090022#include <unistd.h>
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090023
Shinichiro Hamaji1a444a82016-02-16 13:49:49 +090024#include "affinity.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090025#include "dep.h"
26#include "eval.h"
27#include "exec.h"
28#include "file.h"
29#include "file_cache.h"
30#include "fileutil.h"
Shinichiro Hamaji5f57a992015-06-30 19:39:39 +090031#include "find.h"
Shinichiro Hamaji08808d32015-06-26 08:02:45 +090032#include "flags.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090033#include "func.h"
34#include "log.h"
Shinichiro Hamaji5f86e1a2015-06-29 14:25:39 +090035#include "ninja.h"
Shinichiro Hamaji42b625f2015-06-16 23:07:21 +090036#include "parser.h"
Shinichiro Hamaji8ef0ce52016-01-19 18:07:43 +090037#include "regen.h"
Shinichiro Hamaji0d8e79b2015-06-30 03:29:35 +090038#include "stats.h"
Shinichiro Hamaji645cca72015-09-24 17:04:21 +090039#include "stmt.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090040#include "string_piece.h"
Shinichiro Hamaji0e74c542015-06-22 16:17:08 +090041#include "stringprintf.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090042#include "strutil.h"
Shinichiro Hamajie7992752015-06-29 18:38:35 +090043#include "symtab.h"
Shinichiro Hamajicbd34cd2015-07-05 02:53:04 +090044#include "timeutil.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090045#include "var.h"
46
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090047static void Init() {
48 InitSymtab();
49 InitFuncTable();
50 InitDepNodePool();
Shinichiro Hamaji42b625f2015-06-16 23:07:21 +090051 InitParser();
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090052}
53
54static void Quit() {
Shinichiro Hamaji0d8e79b2015-06-30 03:29:35 +090055 ReportAllStats();
56
Shinichiro Hamaji42b625f2015-06-16 23:07:21 +090057 QuitParser();
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090058 QuitDepNodePool();
59 QuitFuncTable();
60 QuitSymtab();
61}
62
Shinichiro Hamajie7992752015-06-29 18:38:35 +090063static void ReadBootstrapMakefile(const vector<Symbol>& targets,
Shinichiro Hamaji645cca72015-09-24 17:04:21 +090064 vector<Stmt*>* stmts) {
Shinichiro Hamaji0e74c542015-06-22 16:17:08 +090065 string bootstrap = (
Shinichiro Hamaji91d12492015-09-04 09:54:48 +090066 "CC?=cc\n"
Shinichiro Hamajid749b932015-07-13 20:51:15 -070067#if defined(__APPLE__)
Shinichiro Hamaji91d12492015-09-04 09:54:48 +090068 "CXX?=c++\n"
Shinichiro Hamajid749b932015-07-13 20:51:15 -070069#else
Shinichiro Hamaji91d12492015-09-04 09:54:48 +090070 "CXX?=g++\n"
Shinichiro Hamajid749b932015-07-13 20:51:15 -070071#endif
Shinichiro Hamaji91d12492015-09-04 09:54:48 +090072 "AR?=ar\n"
Shinichiro Hamaji0e74c542015-06-22 16:17:08 +090073 // Pretend to be GNU make 3.81, for compatibility.
Shinichiro Hamaji91d12492015-09-04 09:54:48 +090074 "MAKE_VERSION?=3.81\n"
Shinichiro Hamajicdcd4192015-09-04 10:06:30 +090075 "KATI?=ckati\n"
Shinichiro Hamaji91d12492015-09-04 09:54:48 +090076 // Overwrite $SHELL environment variable.
77 "SHELL=/bin/sh\n"
Shinichiro Hamaji0e74c542015-06-22 16:17:08 +090078 // TODO: Add more builtin vars.
79
80 // http://www.gnu.org/software/make/manual/make.html#Catalogue-of-Rules
81 // The document above is actually not correct. See default.c:
82 // http://git.savannah.gnu.org/cgit/make.git/tree/default.c?id=4.1
83 ".c.o:\n"
84 "\t$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@ $<\n"
85 ".cc.o:\n"
86 "\t$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@ $<\n"
87 // TODO: Add more builtin rules.
88 );
Shinichiro Hamaji003d06e2015-09-09 18:22:04 +090089 if (g_flags.generate_ninja) {
Shinichiro Hamajib6a04542015-09-09 17:37:41 +090090 bootstrap += StringPrintf("MAKE?=make -j%d\n",
Shinichiro Hamaji9dce4442015-12-05 11:05:00 +090091 g_flags.num_jobs <= 1 ? 1 : g_flags.num_jobs / 2);
Shinichiro Hamajib6a04542015-09-09 17:37:41 +090092 } else {
93 bootstrap += StringPrintf("MAKE?=%s\n",
Shinichiro Hamaji003d06e2015-09-09 18:22:04 +090094 JoinStrings(g_flags.subkati_args, " ").c_str());
Shinichiro Hamajib6a04542015-09-09 17:37:41 +090095 }
Shinichiro Hamajicdcd4192015-09-04 10:06:30 +090096 bootstrap += StringPrintf("MAKECMDGOALS?=%s\n",
Shinichiro Hamajie7992752015-06-29 18:38:35 +090097 JoinSymbols(targets, " ").c_str());
Shinichiro Hamaji0e74c542015-06-22 16:17:08 +090098
99 char cwd[PATH_MAX];
100 if (!getcwd(cwd, PATH_MAX)) {
101 fprintf(stderr, "getcwd failed\n");
102 CHECK(false);
103 }
104 bootstrap += StringPrintf("CURDIR:=%s\n", cwd);
Shinichiro Hamaji645cca72015-09-24 17:04:21 +0900105 Parse(Intern(bootstrap).str(), Loc("*bootstrap*", 0), stmts);
Shinichiro Hamaji0e74c542015-06-22 16:17:08 +0900106}
107
Shinichiro Hamajic9b9e5e2016-02-18 18:18:54 +0900108static void SetVar(StringPiece l, VarOrigin origin) {
Shinichiro Hamaji9db4cb82015-06-22 16:51:04 +0900109 size_t found = l.find('=');
110 CHECK(found != string::npos);
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900111 Symbol lhs = Intern(l.substr(0, found));
Shinichiro Hamaji9db4cb82015-06-22 16:51:04 +0900112 StringPiece rhs = l.substr(found + 1);
Shinichiro Hamajic9b9e5e2016-02-18 18:18:54 +0900113 lhs.SetGlobalVar(
114 new RecursiveVar(NewLiteral(rhs.data()), origin, rhs.data()));
Shinichiro Hamaji9db4cb82015-06-22 16:51:04 +0900115}
116
117extern "C" char** environ;
Shinichiro Hamaji9db4cb82015-06-22 16:51:04 +0900118
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900119static int Run(const vector<Symbol>& targets,
Shinichiro Hamaji998ccf72015-07-18 12:37:02 +0900120 const vector<StringPiece>& cl_vars,
121 const string& orig_args) {
Shinichiro Hamaji90db5412015-08-13 15:03:52 +0900122 double start_time = GetTime();
123
Shinichiro Hamaji003d06e2015-09-09 18:22:04 +0900124 if (g_flags.generate_ninja && (g_flags.regen || g_flags.dump_kati_stamp)) {
Shinichiro Hamajif9e15242015-07-31 12:50:06 +0900125 ScopedTimeReporter tr("regen check time");
Shinichiro Hamajif9869fc2015-09-28 17:18:59 +0900126 if (!NeedsRegen(start_time, orig_args)) {
Shinichiro Hamajiac50ff42016-02-09 16:23:28 +0900127 fprintf(stderr, "No need to regenerate ninja file\n");
Shinichiro Hamajif6df3342015-08-11 14:59:36 +0900128 return 0;
129 }
Shinichiro Hamaji003d06e2015-09-09 18:22:04 +0900130 if (g_flags.dump_kati_stamp) {
Shinichiro Hamajif6df3342015-08-11 14:59:36 +0900131 printf("Need to regenerate ninja file\n");
Shinichiro Hamajia4bb7742015-07-31 11:27:30 +0900132 return 0;
133 }
Shinichiro Hamajia09ed282015-07-31 12:21:54 +0900134 ClearGlobCache();
Shinichiro Hamajia4bb7742015-07-31 11:27:30 +0900135 }
136
Shinichiro Hamaji1a444a82016-02-16 13:49:49 +0900137 SetAffinityForSingleThread();
138
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900139 MakefileCacheManager* cache_mgr = NewMakefileCacheManager();
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900140
Shinichiro Hamajic9b9e5e2016-02-18 18:18:54 +0900141 Intern("MAKEFILE_LIST").SetGlobalVar(
142 new SimpleVar(StringPrintf(" %s", g_flags.makefile), VarOrigin::FILE));
Shinichiro Hamaji91d12492015-09-04 09:54:48 +0900143 for (char** p = environ; *p; p++) {
Shinichiro Hamajic9b9e5e2016-02-18 18:18:54 +0900144 SetVar(*p, VarOrigin::ENVIRONMENT);
Shinichiro Hamaji91d12492015-09-04 09:54:48 +0900145 }
Shinichiro Hamajic9b9e5e2016-02-18 18:18:54 +0900146 Evaluator* ev = new Evaluator();
Shinichiro Hamaji0e74c542015-06-22 16:17:08 +0900147
Shinichiro Hamaji645cca72015-09-24 17:04:21 +0900148 vector<Stmt*> bootstrap_asts;
Shinichiro Hamaji0e74c542015-06-22 16:17:08 +0900149 ReadBootstrapMakefile(targets, &bootstrap_asts);
150 ev->set_is_bootstrap(true);
Shinichiro Hamaji645cca72015-09-24 17:04:21 +0900151 for (Stmt* stmt : bootstrap_asts) {
152 LOG("%s", stmt->DebugString().c_str());
153 stmt->Eval(ev);
Shinichiro Hamaji0e74c542015-06-22 16:17:08 +0900154 }
155 ev->set_is_bootstrap(false);
156
Shinichiro Hamaji91d12492015-09-04 09:54:48 +0900157 for (StringPiece l : cl_vars) {
Shinichiro Hamajic9b9e5e2016-02-18 18:18:54 +0900158 SetVar(l, VarOrigin::COMMAND_LINE);
Shinichiro Hamaji91d12492015-09-04 09:54:48 +0900159 }
160
Shinichiro Hamaji54e52dd2015-06-27 17:14:06 +0900161 {
162 ScopedTimeReporter tr("eval time");
Shinichiro Hamaji003d06e2015-09-09 18:22:04 +0900163 Makefile* mk = cache_mgr->ReadMakefile(g_flags.makefile);
Shinichiro Hamaji645cca72015-09-24 17:04:21 +0900164 for (Stmt* stmt : mk->stmts()) {
165 LOG("%s", stmt->DebugString().c_str());
166 stmt->Eval(ev);
Shinichiro Hamaji54e52dd2015-06-27 17:14:06 +0900167 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900168 }
169
Shinichiro Hamaji645cca72015-09-24 17:04:21 +0900170 for (ParseErrorStmt* err : GetParseErrors()) {
Shinichiro Hamajia06bee92015-08-05 17:13:05 +0900171 WARN("%s:%d: warning for parse error in an unevaluated line: %s",
172 LOCF(err->loc()), err->msg.c_str());
173 }
174
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900175 vector<DepNode*> nodes;
Shinichiro Hamaji54e52dd2015-06-27 17:14:06 +0900176 {
177 ScopedTimeReporter tr("make dep time");
178 MakeDep(ev, ev->rules(), ev->rule_vars(), targets, &nodes);
179 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900180
Shinichiro Hamaji003d06e2015-09-09 18:22:04 +0900181 if (g_flags.is_syntax_check_only)
Shinichiro Hamajied883ef2015-07-31 13:15:04 +0900182 return 0;
183
Shinichiro Hamaji003d06e2015-09-09 18:22:04 +0900184 if (g_flags.generate_ninja) {
Shinichiro Hamajied883ef2015-07-31 13:15:04 +0900185 ScopedTimeReporter tr("generate ninja time");
Shinichiro Hamaji9c5e60c2015-09-29 13:26:45 +0900186 GenerateNinja(nodes, ev, orig_args, start_time);
Shinichiro Hamajied883ef2015-07-31 13:15:04 +0900187 return 0;
188 }
189
Shinichiro Hamaji45a0c762015-06-26 06:47:10 +0900190 for (const auto& p : ev->exports()) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900191 const Symbol name = p.first;
Shinichiro Hamaji45a0c762015-06-26 06:47:10 +0900192 if (p.second) {
193 Var* v = ev->LookupVar(name);
Shinichiro Hamajifb415ad2015-08-14 17:19:34 +0900194 const string&& value = v->Eval(ev);
195 LOG("setenv(%s, %s)", name.c_str(), value.c_str());
196 setenv(name.c_str(), value.c_str(), 1);
Shinichiro Hamaji45a0c762015-06-26 06:47:10 +0900197 } else {
198 LOG("unsetenv(%s)", name.c_str());
199 unsetenv(name.c_str());
200 }
201 }
202
Shinichiro Hamaji54e52dd2015-06-27 17:14:06 +0900203 {
204 ScopedTimeReporter tr("exec time");
205 Exec(nodes, ev);
206 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900207
Shinichiro Hamaji645cca72015-09-24 17:04:21 +0900208 for (Stmt* stmt : bootstrap_asts)
209 delete stmt;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900210 delete ev;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900211 delete cache_mgr;
212
Shinichiro Hamaji64cd8062015-06-27 16:58:36 +0900213 return 0;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900214}
215
Shinichiro Hamaji34556cc2015-10-05 15:01:46 +0900216static void FindFirstMakefie() {
217 if (g_flags.makefile != NULL)
218 return;
219 if (Exists("GNUmakefile")) {
220 g_flags.makefile = "GNUmakefile";
221#if !defined(__APPLE__)
222 } else if (Exists("makefile")) {
223 g_flags.makefile = "makefile";
224#endif
225 } else if (Exists("Makefile")) {
226 g_flags.makefile = "Makefile";
227 }
228}
229
Shinichiro Hamaji71cf60b2015-10-08 18:00:07 +0900230static void HandleRealpath(int argc, char** argv) {
231 char buf[PATH_MAX];
232 for (int i = 0; i < argc; i++) {
233 if (realpath(argv[i], buf))
234 printf("%s\n", buf);
235 }
236}
237
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900238int main(int argc, char* argv[]) {
Shinichiro Hamaji71cf60b2015-10-08 18:00:07 +0900239 if (argc >= 2 && !strcmp(argv[1], "--realpath")) {
240 HandleRealpath(argc - 2, argv + 2);
241 return 0;
242 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900243 Init();
Shinichiro Hamaji998ccf72015-07-18 12:37:02 +0900244 string orig_args;
245 for (int i = 0; i < argc; i++) {
246 if (i)
247 orig_args += ' ';
248 orig_args += argv[i];
249 }
Shinichiro Hamaji003d06e2015-09-09 18:22:04 +0900250 g_flags.Parse(argc, argv);
Shinichiro Hamaji34556cc2015-10-05 15:01:46 +0900251 FindFirstMakefie();
Shinichiro Hamaji003d06e2015-09-09 18:22:04 +0900252 if (g_flags.makefile == NULL)
Shinichiro Hamajie4ee8ea2015-08-15 01:22:23 +0900253 ERROR("*** No targets specified and no makefile found.");
Shinichiro Hamaji5f57a992015-06-30 19:39:39 +0900254 // This depends on command line flags.
Shinichiro Hamaji003d06e2015-09-09 18:22:04 +0900255 if (g_flags.use_find_emulator)
Shinichiro Hamaji4e950e62015-07-02 02:59:55 +0900256 InitFindEmulator();
Shinichiro Hamaji003d06e2015-09-09 18:22:04 +0900257 int r = Run(g_flags.targets, g_flags.cl_vars, orig_args);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900258 Quit();
259 return r;
260}