2016-12-06 14 views
1

Есть ли готовое решение для получения списка членов архива, которые были использованы (или будут использоваться) при связывании в архиве (то есть в статической библиотеке) ?Получение списка членов архива, используемых при связывании статической библиотеки

Скажите, есть ли у меня объектный файл, который предоставляет main и зависит от a и b. Если связать это против статического Lib lib.a, обеспечивая a, b, c, d в членах архива a.o, b.o, c.o и d.o соответственно, то я хотел бы получить список с a.o и b.o, либо в качестве побочного продукта связывание библиотеки или запуск command_to_get_members main.o lib.a

Есть ли решения для этого или мне нужно разобрать nm выходы и разрешить символы против членов архива вручную?

+0

Возможно, вы ищете это [man ldd] (http://man7.org/linux/man-pages/man1/ldd.1.html) или [man strings] (https://linux.die.net)./man/1/strings) – Stargateur

+0

@Stargateur Я думаю, что самое близкое к тому, что я ищу, передает '-M' в компоновщик с' -Wl, -M'. Он печатает карту, которая включает в себя список того, как символы разрешают архивировать элементы. Не идеально, поскольку мне все еще нужно сделать некоторую обработку текста, но я думаю, что я пойду с этим, если не появится лучшее решение. – PSkocik

+0

О, я лучше посмотрю, что вы хотите, действительно, nm может сделать это с помощью --defined-only и -extern-only. Может быть, это может помочь вам http://stackoverflow.com/questions/6687630/how-to-remove-unused-c-c-symbols-with-gcc-and-ld. Я не знаю другого решения. – Stargateur

ответ

1

Вот предложение, скрипт, который использует nm--defined-only и --undefined-only) для сопоставления которых архивные объекты содержат символы, необходимые одному из объектных файлов, указанных:

#!/bin/bash 
export LANG=C LC_ALL=C 

objs=() 
libs=() 
for file in "[email protected]" ; do 
    [ -r "$file" ] || continue 
    if [ "$file" = "${file%.*}.o" ]; then 
     objs+=("$file") 
    elif [ "$file" = "${file%.*}.a" ]; then 
     libs+=("$file") 
    else 
     printf '%s: Unknown file type. Skipping.\n' "$file" >&2 
    fi 
done 

nm --defined-only "${libs[@]}" 2>/dev/null | awk -v needsyms="$(nm -u "${objs[@]}" 2>/dev/null | sed -ne 's|^[\t ]*U[\t ]*||p')" \ 
    'BEGIN { 
     split("", objlist) 
     n = split(needsyms, symlist) 
     for (i = 1; i <= n; i++) need[symlist[i]] = "" 
    } 
    /\.o:$/ { 
     name = $0 
     sub(/:$/, "", name) 
     next 
    } 

    (NF >= 3) && ($3 in need) { 
     need[$3] = name 
     objlist[name] = objlist[name] " " $3 
    } 

    END { 
     # Print symbols found and their source objects: 
     # for (name in need) printf "%s: %s\n", need[name], name 

     # Print source objects from the archive, with symbols used from it: 
     for (name in objlist) printf "%s:%s\n", name, objlist[name] 
    }' 

Файлы, которые имеют суффикс .a являются рассматриваемые объекты архива, предоставляющие символы, а файлы с суффиксом .o - это объектные файлы с неопределенными символами.