gcc: дубликаты идентификаторов в объектных файлах или библиотеках - PullRequest
0 голосов
/ 06 сентября 2011

Дублирующие идентификаторы просто игнорируются архиватором, а также компоновщиком. Они обнаруживаются, только если исходные или объектные файлы передаются непосредственно в gcc, который считает несколько определений ошибкой. Как и положено. Архиватор / компоновщик просто игнорирует их, и в итоге мы получаем только один из идентификаторов в исполняемом файле. Какой это будет, зависит от порядка передачи объектного файла или библиотеки. Ниже приведен скрипт для демонстрации этого.

Есть ли способ заставить архиватор / компоновщик считать это ошибкой? Или есть другие инструменты для борьбы с этим?

#!/bin/sh

dir=$(mktemp -d)
echo "Using temporary directory: $dir"
echo
cd "$dir"

create_lib()
{
    lib=$1
    shift
    rm -f $lib
    ar r $lib "$@" 2>/dev/null
}

make_file()
{
    base=file$1
    cat >$base.c <<-EOF
    int f()
    {
        return $1;
    }
    EOF

    gcc $base.c -o $base.o -c

    create_lib lib$base.a $base.o
}

make_file 1
make_file 2

cat >main.c <<EOF
int main()
{
    extern int f();
    return f();
}
EOF

gcc main.c -omain.o -c

cat <<EOF
1. Passing duplicate functions to archiver in different order
   produces no error, but different result:
EOF

create_lib libfile.a file1.o file2.o
gcc main.o libfile.a -omain
(echo -n "ar file1.o file2.o: "; ./main; echo $?)

create_lib libfile.a file2.o file1.o
gcc main.o libfile.a -omain
(echo -n "ar file2.o file1.o: "; ./main; echo $?)

echo

cat <<EOF
2. Passing duplicate libraries to linker in different order
   produces no error, but different result:
EOF

gcc main.o libfile2.a libfile1.a -omain
(echo -n "gcc libfile2.a libfile1.a: "; ./main; echo $?)

gcc main.o libfile1.a libfile2.a -omain
(echo -n "gcc libfile1.a libfile2.a: "; ./main; echo $?)

Пример вывода:

Using temporary directory: /tmp/tmp.AaXzxGcSdd

1. Passing duplicate functions to archiver in different order
   produces no error, but different result:
ar file1.o file2.o: 1
ar file2.o file1.o: 2

2. Passing duplicate libraries to linker in different order
   produces no error, but different result:
gcc libfile2.a libfile1.a: 2
gcc libfile1.a libfile2.a: 1

1 Ответ

0 голосов
/ 06 сентября 2011

Я думаю, вы можете получить желаемое поведение с помощью опции --whole-archive, передаваемой компоновщику. Из документации GNU:

--whole-archive

Для каждого архива, упомянутого в командной строке после --whole-archive, включить каждый объектный файл в архив в ссылка, а не поиск в архиве нужного объекта файлы. Это обычно используется, чтобы превратить архивный файл в общий библиотека, заставляя каждый объект быть включенным в результирующий общий библиотека. Эта опция может использоваться более одного раза.

Два примечания при использовании этой опции от gcc: во-первых, gcc не знает об этой опции, поэтому вы должны использовать -Wl,-whole-archive. Во-вторых, не забудьте использовать -Wl,-no-whole-archive после вашего списка архивов, потому что GCC добавит свой собственный список архивов к вашей ссылке, и вы можете не хочу, чтобы этот флаг также влиял на них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...