我正在尝试在 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
您情况下的功能要求:
- 用
gcc -c
创建单独的目标文件(即main
)符号,它只是(声明和)调用(即包装)您的自定义入口点(可能通过argc
和argv
调用参数)。这会让链接器满意,并且就像添加单个 makefile 规则一样简单。 - 将程序编译为
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/