Commit 426da232 authored by jan.koester's avatar jan.koester
Browse files

added deduping

parent 8e17f15b
Loading
Loading
Loading
Loading
+25 −4
Changes for parser.cpp: 25 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#include <cstdio>
#include <cstring>
#include <cctype>
#include <set>

namespace fs = std::filesystem;
using namespace makeplus;
@@ -1030,13 +1031,33 @@ std::string Parser::expand_with_automatic(const std::string& input, const Makefi
    auto_vars["@"] = target;
    auto_vars["<"] = first_prereq;

    // GNU make: '$^' lists all prerequisites with duplicate names removed
    // (first occurrence kept). '$+' keeps duplicates. Deduplicating '$^' is
    // essential: Kbuild's built-in.a rule passes '$(real-prereqs)' (= $^) to
    // 'ar', so a duplicated prerequisite would otherwise add the same object
    // to the archive twice and cause "multiple definition" link errors.
    std::vector<std::string> uniq_prereqs;
    {
        std::set<std::string> seen;
        for (const auto& p : all_prereqs) {
            if (seen.insert(p).second) uniq_prereqs.push_back(p);
        }
    }

    std::string all_p;
    for (size_t i = 0; i < all_prereqs.size(); i++) {
    for (size_t i = 0; i < uniq_prereqs.size(); i++) {
        if (i > 0) all_p += ' ';
        all_p += all_prereqs[i];
        all_p += uniq_prereqs[i];
    }
    auto_vars["^"] = all_p;

    std::string all_p_dup;
    for (size_t i = 0; i < all_prereqs.size(); i++) {
        if (i > 0) all_p_dup += ' ';
        all_p_dup += all_prereqs[i];
    }
    auto_vars["+"] = all_p_dup;

    std::string newer_p;
    for (size_t i = 0; i < newer_prereqs.size(); i++) {
        if (i > 0) newer_p += ' ';
@@ -1076,8 +1097,8 @@ std::string Parser::expand_with_automatic(const std::string& input, const Makefi
        }
        return out;
    };
    auto_vars["^F"] = list_modifier(all_prereqs, false);
    auto_vars["^D"] = list_modifier(all_prereqs, true);
    auto_vars["^F"] = list_modifier(uniq_prereqs, false);
    auto_vars["^D"] = list_modifier(uniq_prereqs, true);
    auto_vars["?F"] = list_modifier(newer_prereqs, false);
    auto_vars["?D"] = list_modifier(newer_prereqs, true);