归档器和链接器都会忽略重复的标识符。仅当源文件或目标文件直接传递给gcc时才会检测到它们,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
答案 0 :(得分:0)
我认为您可以通过传递给链接器的--whole-archive
选项获得所需的行为。来自GNU ld docs:
--whole-archive
对于命令行后提到的每个档案
--whole-archive
选项,包括存档中的每个目标文件 链接,而不是搜索存档中所需的对象 文件。这通常用于将存档文件转换为共享文件 库,强制每个对象都包含在生成的共享中 图书馆。此选项可能会被多次使用。从gcc使用此选项时的两个注意事项:首先,gcc不知道 关于此选项,因此您必须使用
-Wl,-whole-archive
。第二, 不要忘记在档案列表后使用-Wl,-no-whole-archive
, 因为gcc会将自己的档案列表添加到您的链接中,您可以 不希望这面旗帜影响那些。