Commit 24825f58 authored by jan.koester's avatar jan.koester
Browse files

sec

parent 2180fe02
Loading
Loading
Loading
Loading
+24 −1
Changes for executor.cpp: 24 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -36,7 +36,30 @@ const Rule* Executor::find_rule(const std::string& target, std::string& stem) {

    // Explicit rule has no recipe - try pattern/implicit rules for recipe
    const Rule* pattern = mf_.find_pattern_rule(target, stem);
    if (pattern) return pattern;
    if (pattern) {
        // GNU make only applies an implicit rule when its prerequisites exist
        // or can themselves be made. Without this check a self-similar pattern
        // such as "x/%: x/%_shipped" would chain forever (x/ -> x/_shipped ->
        // x/_shipped_shipped -> ...), growing the target name until the process
        // runs out of memory. A prerequisite counts as satisfiable if the file
        // exists, an explicit rule produces it, or it is phony.
        bool viable = true;
        for (const auto& p : pattern->prerequisites) {
            std::string prereq = p;
            size_t ppct = prereq.find('%');
            if (ppct != std::string::npos) {
                prereq = prereq.substr(0, ppct) + stem + prereq.substr(ppct + 1);
            }
            prereq = parser_.expand(prereq, mf_);
            if (prereq.empty()) continue;
            if (file_exists(prereq)) continue;
            if (mf_.find_explicit_rule(prereq)) continue;
            if (mf_.phony_targets.count(prereq)) continue;
            viable = false;
            break;
        }
        if (viable) return pattern;
    }

    // Built-in implicit rules
    static std::vector<Rule> builtins;