c - 如何将可执行入口点的名称从 main 更改为其他名称?

标签 c gcc linker ld elf

我正在尝试在 Ubuntu Linux (12.04 x64) 上使用 gcc 4.8 编译第三方源代码,其中包含许多实用程序和测试应用程序,其中可执行入口点未称为 main。不要问我为什么 - 我不知道答案。

链接器当然会提示:

/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status

是否可以强制链接器使用另一种方法作为入口点?我尝试将这些链接器选项与 gcc 一起使用,但它们都不起作用: -Wl,-eWhatever-Wl,--entry=Whatever-Wl,-e,Whatever。都以同样的错误结束。

最佳答案

按照 C 标准,托管环境(我猜这是你的情况,因为/如果你想使用标准库头*)强制你保持 main功能。来自 C11 §5.1.2.2.1/p1(强调我的):

The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:

int main(void) { /* ... */ }

or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):

int main(int argc, char *argv[]) { /* ... */ }

or equivalent;10) or in some other implementation-defined manner.

我可以想到两个选项来绕过 main您情况下的功能要求:

  1. gcc -c 创建单独的目标文件(即 main )符号,它只是(声明和)调用(即包装)您的自定义入口点(可能通过 argcargv 调用参数)。这会让链接器满意,并且就像添加单个 makefile 规则一样简单。
  2. 将程序编译为gcc -DWhatever=main .这基本上取代了 Whatever 的每个实例通过 main 预处理 token , 所以链接器会想到 Whatever作为“适当的”主要功能。

* 一些 header 也必须在独立环境中可用,例如 <stddef.h><float.h> ,请参阅 §4/p6 了解它们的完整列表。

这是这两个选项的一些基本说明。每个人都假设 foo.c如下:

foo.c

#include <stdio.h>

void foo(void)
{
    printf("foo\n");
}

第一种方法:

main.c

/* declare an entry point */
void foo(void);

/* define main as wrapper function */
int main(void)
{
    foo();

    return 0;
}

编译&运行:

$ gcc -c main.c
$ gcc foo.c main.o
$ ./a.out
foo

第二种方法:

$ gcc -Dfoo=main foo.c 
$ ./a.out
foo

有些事情可能需要更多的调整,但我希望你明白这一点。

关于c - 如何将可执行入口点的名称从 main 更改为其他名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28485740/

相关文章:

c - Linux gcc <time.h> 和线程在一起

c - fork() 的执行顺序?

gcc - 为什么 __get_cpuid 对于 leaf=4 返回全零?

c++ - 将 C++ 代码与 'gcc' 链接(无 g++)

c - 运行基于 FANN 的程序时出现符号查找错误

c - 从结构中释放内存给出无效指针

c - 如何通过宏向 C 库提供选项

linux - 跟踪共享库中符号的来源

c - 写入名称为日期的文件

linux - 如何获得二进制文本部分的偏移量和大小?