Дублирующие идентификаторы просто игнорируются архиватором, а также компоновщиком. Они обнаруживаются, только если исходные или объектные файлы передаются непосредственно в 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