Commit c0358bed authored by jan.koester's avatar jan.koester
Browse files

arg support added

parent 1c655bc1
Loading
Loading
Loading
Loading
+66 −3
Changes for main.cpp: 66 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -240,9 +240,50 @@ int main(int argc, char* argv[]) {
    // Setup default variables
    setup_defaults(mf, argv[0]);

    // Apply command-line variables (highest priority)
    // GNU make propagates command-line variable overrides to every sub-make via
    // MAKEFLAGS: the portion after "--" holds NAME=value assignments (spaces in
    // a value are backslash-escaped). A child make re-reads them and gives them
    // command-line (highest) priority. Replicate that so a recipe like
    //   $(MAKE) $(build)=objtool CFLAGS="$(OBJTOOL_CFLAGS)"
    // reaches the nested $(MAKE) descend that actually performs the compile
    // (the kernel tools/ build relies on this for its include flags).
    if (const char* mflags = getenv("MAKEFLAGS")) {
        std::string env_flags(mflags);
        size_t sep = env_flags.find("--");
        if (sep != std::string::npos) {
            std::string overrides = env_flags.substr(sep + 2);
            std::vector<std::pair<std::string, std::string>> inherited;
            std::string word;
            auto flush = [&]() {
                if (word.empty()) return;
                size_t e = word.find('=');
                if (e != std::string::npos && e > 0)
                    inherited.emplace_back(word.substr(0, e), word.substr(e + 1));
                word.clear();
            };
            for (size_t i = 0; i < overrides.size(); ++i) {
                char c = overrides[i];
                if (c == '\\' && i + 1 < overrides.size()) {
                    word.push_back(overrides[++i]);   // unescape "\<c>" -> "<c>"
                } else if (c == ' ' || c == '\t') {
                    flush();
                } else {
                    word.push_back(c);
                }
            }
            flush();
            // Inherited overrides come first so an override stated explicitly on
            // this invocation's command line still wins (applied last below).
            cmdline_vars.insert(cmdline_vars.begin(), inherited.begin(), inherited.end());
        }
    }

    // Apply command-line variables (highest priority). Also export them into the
    // environment, like GNU make, so plain $$VAR references in recipes and any
    // child process observe the value.
    for (const auto& [name, value] : cmdline_vars) {
        mf.variables[name] = {value, makeplus::VarFlavor::Simple, true};
        setenv(name.c_str(), value.c_str(), 1);
    }

    // MAKECMDGOALS and MAKEFLAGS must exist BEFORE parsing: build systems like
@@ -268,8 +309,30 @@ int main(int argc, char* argv[]) {
        std::string combined = flags;
        if (!words.empty()) combined += words;
        if (jobs > 1) combined += " -j" + std::to_string(jobs);
        mf.variables["MAKEFLAGS"] = {makeplus::Parser::trim(combined),
                                     makeplus::VarFlavor::Simple, false};
        // Append command-line variable overrides after "--" so they propagate to
        // sub-makes (GNU make format; spaces/backslashes in a value are escaped).
        if (!cmdline_vars.empty()) {
            std::map<std::string, std::string> ov;
            std::vector<std::string> order;
            for (const auto& kv : cmdline_vars) {
                if (!ov.count(kv.first)) order.push_back(kv.first);
                ov[kv.first] = kv.second;   // later (command-line) value wins
            }
            combined += " --";
            for (const auto& name : order) {
                std::string esc;
                for (char c : ov[name]) {
                    if (c == ' ' || c == '\t' || c == '\\') esc.push_back('\\');
                    esc.push_back(c);
                }
                combined += " " + name + "=" + esc;
            }
        }
        std::string mkflags = makeplus::Parser::trim(combined);
        mf.variables["MAKEFLAGS"] = {mkflags, makeplus::VarFlavor::Simple, false};
        // MAKEFLAGS must be in the environment so a recursive $(MAKE) (a fresh
        // makeplus process) inherits the flags and the variable overrides above.
        setenv("MAKEFLAGS", mkflags.c_str(), 1);
    }

    // Parse makefile