Commit 2c6866c5 authored by jan.koester's avatar jan.koester
Browse files

env fix

parent 14b027eb
Loading
Loading
Loading
Loading
+27 −0
Changes for main.cpp: 27 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -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};