Loading main.cpp +27 −0 Changes for main.cpp: 27 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -444,6 +444,33 @@ int main(int argc, char* argv[]) { // overrides, then the make-special variables that must exist before parsing. auto load_makefile = [&](makeplus::Makefile& m) -> bool { setup_defaults(m, argv[0]); // GNU make's own documented behavior (never implemented here before): // every variable in the process's environment becomes a make // variable, as if the makefile had a plain "NAME = value" assignment // for each one -- so it's visible as $(NAME), AND (critically) a // real assignment for that same name written INSIDE the makefile // still overrides it normally, exactly like any other variable // redefinition. Real-world case this fixes: kernel.spec's own // "export WERROR=0" (meant to disable tools/lib/subcmd's own // -Werror, which THAT makefile gates behind "ifneq ($(WERROR),0)") // silently did nothing -- $(WERROR) was always empty, since nothing // here ever consulted the environment for a plain variable lookup at // all (only MAKEFLAGS, elsewhere, for its own separate reasons) -- // so the ifneq was always true and -Werror always got added, no // matter what the invoking shell exported. from_cmdline=false here // is exactly what already lets an ordinary "VAR = value" line // inside the makefile overwrite it further down in parse_file() // (which already gates a same-name redefinition on that flag to // protect a REAL command-line override, e.g. "make VAR=x", from // being silently clobbered by the makefile's own text) -- an // environment-sourced default is supposed to lose to either, unlike // a command-line one. for (char** e = environ; *e; ++e) { const char* eq = std::strchr(*e, '='); if (!eq || eq == *e) continue; std::string name(*e, eq - *e); m.variables[name] = {std::string(eq + 1), makeplus::VarFlavor::Recursive, false}; } // Command-line variables have the highest priority. for (const auto& [name, value] : cmdline_vars) m.variables[name] = {value, makeplus::VarFlavor::Simple, true}; Loading Loading
main.cpp +27 −0 Changes for main.cpp: 27 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -444,6 +444,33 @@ int main(int argc, char* argv[]) { // overrides, then the make-special variables that must exist before parsing. auto load_makefile = [&](makeplus::Makefile& m) -> bool { setup_defaults(m, argv[0]); // GNU make's own documented behavior (never implemented here before): // every variable in the process's environment becomes a make // variable, as if the makefile had a plain "NAME = value" assignment // for each one -- so it's visible as $(NAME), AND (critically) a // real assignment for that same name written INSIDE the makefile // still overrides it normally, exactly like any other variable // redefinition. Real-world case this fixes: kernel.spec's own // "export WERROR=0" (meant to disable tools/lib/subcmd's own // -Werror, which THAT makefile gates behind "ifneq ($(WERROR),0)") // silently did nothing -- $(WERROR) was always empty, since nothing // here ever consulted the environment for a plain variable lookup at // all (only MAKEFLAGS, elsewhere, for its own separate reasons) -- // so the ifneq was always true and -Werror always got added, no // matter what the invoking shell exported. from_cmdline=false here // is exactly what already lets an ordinary "VAR = value" line // inside the makefile overwrite it further down in parse_file() // (which already gates a same-name redefinition on that flag to // protect a REAL command-line override, e.g. "make VAR=x", from // being silently clobbered by the makefile's own text) -- an // environment-sourced default is supposed to lose to either, unlike // a command-line one. for (char** e = environ; *e; ++e) { const char* eq = std::strchr(*e, '='); if (!eq || eq == *e) continue; std::string name(*e, eq - *e); m.variables[name] = {std::string(eq + 1), makeplus::VarFlavor::Recursive, false}; } // Command-line variables have the highest priority. for (const auto& [name, value] : cmdline_vars) m.variables[name] = {value, makeplus::VarFlavor::Simple, true}; Loading