gcc:链接时替代

时间:2018-06-15 07:35:53

标签: c gcc linker

我目前正在尝试了解gcc编译器和链接器的工作原理。我遇到了一种叫做“链接时替代”的技术,我觉得这很有趣。目标是在多个文件中具有多个函数定义,并在链接时确定哪些定义进入最终可执行文件。

一个简单的例子:

main.c中:

#include "header.h"

int main(void)
{
    hello("everyone");
    return 0;
}

header.h:

#ifndef _HEADER_H
#define _HEADER_H

void hello(const char * name);

#endif

file1.c中:

#include "header.h"
#include <stdio.h>

void hello(const char * name)
{
    printf("File1: Hello, %s!\n", name);
}

file2.c中:

#include "header.h"
#include <stdio.h>

void hello(const char * name)
{
    printf("File2: Hello, %s!\n", name);
}

现在我有两个问题:

  • 是否可以使用适当的链接顺序选择一个函数(如果所有三个文件都出现在链接器的参数列表中)?
  • 假设file2.c实现了main.c所需的许多功能。是否可以通过使用链接器替换file1.c中不同实现(具有相同名称)的单个函数或某些函数?链接器应首先使用file1.c中的函数定义,然后使用file2.c作为剩余的未解析函数。

我希望我的问题可以理解;)

谢谢!

1 个答案:

答案 0 :(得分:1)

  

是否可以使用适当的链接顺序选择一个函数(如果所有三个文件都出现在链接器的参数列表中)?

如果通过“所有三个文件”表示目标文件(假设没有弱符号),则不会:所有3个文件都将被链接,并且您将得到重复的符号定义错误。

但是如果你将file1.o放入lib1.a,将file2.o放入lib2.a,那么是:

gcc main.c -l1 -l2  # uses file1.o:hello
gcc main.c -l2 -l1  # uses file2.o:hello

更多详情herehere

  

假设file2.c实现了main.c所需的许多功能。是否可以通过使用链接器替换file1.c中不同实现(具有相同名称)的单个函数或某些函数?

是的,但仅限于支持弱符号的平台(例如ELF平台,请参阅__attribute__((weak)) here)。

如果file2.o中的所有符号都是弱定义的,而file1.o中的所有符号都不是,则链接file1.o和file2.o将获得所需的结果:强符号获胜。

我相信(但尚未测试)如果两者 file1.o和file2.o弱定义相同的符号,那么顺序将很重要:

gcc main.c file1.o file2.o  # file1.o definitions override file2.o
gcc main.c file2.o file1.o  # file2.o definitions override file1.o