我试图在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
。全部以相同的错误结束。
答案 0 :(得分:2)
就像C标准一样,托管环境(我想你的情况是/如果你想使用标准库标题*)强迫你保持main
功能。从C11§5.1.2.2.1/ p1(强调我的):
程序启动时调用的函数名为
main
。该 实现声明此函数没有原型。它应该是 定义,返回类型为int且没有参数:
int main(void) { /* ... */ }
或带有两个参数(此处称为 argc和argv,虽然可以使用任何名称,因为它们是本地的 声明它们的函数:
int main(int argc, char *argv[]) { /* ... */ }
或等同物; 10)或其他一些 实现定义的方式。
在您的情况下,我可以考虑绕过main
功能要求的两个选项:
gcc -c
符号创建单独的目标文件(即main
),只是(声明和)调用(即包装)自定义入口点(可能通过argc
和argv
调用参数)。这将使链接器变得愉快,就像添加单个makefile规则一样简单。gcc -DWhatever=main
。这基本上用Whatever
替换main
预处理标记的每个实例,因此链接器认为Whatever
是“正确”的主要功能。 *某些标头也必须在独立环境中可用,例如<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;
}
编译&amp;运行:
$ gcc -c main.c
$ gcc foo.c main.o
$ ./a.out
foo
$ gcc -Dfoo=main foo.c
$ ./a.out
foo
有些事情可能需要更多调整,但我希望你能抓住这个想法。