1) ld mylib.a aux.o main.o
        Works, main's version of 'mylibfunc' is picked up

2) ld aux.o mylib.a main.o
        Fails: ld complains that 'mylibfunc' is multiply defined

Because mylibfunc is undefined when the archive is scanned, i.e. the linker
picks up the archive function and the finds another definition in the object file.
All functions from object files will end up in the executable.

3) ld aux.o main.o mylib.a
        Works, main's version of 'mylibfunc' is picked up
Because mylibfunc has already been resolved by main.o when the archive is scanned.

4) ld main.o aux.o mylib.a
        Works, main's version of 'mylibfunc' is picked up
Because a definition is already present.

The algorithm is fairly simple.

Symbol[string] symtab;
foreach(arg; args) // left-to-right
{
    if (isObjectFile(arg))
    {
        foreach(sym; readObj(arg))
        {
            if (auto p = sym.name in symtab)
                enforce(p.isUndefined || p.isWeak && p.size == sym.size,
p.isWeak ? "size of weak symbol changed" : "multiply defined symbol "~sym.name);
            symtab[sym.name] = sym;
        }
    }
    else if (isArchive(arg))
    {
        Symbol[string] archive = readArchive(arg);
        foreach(name, ref sym; symtab)
        {
            if (sym.isUndefined)
                sym = archive.get(name, sym);
        }
    }
}

Reply via email to