您可以使用-e <symbol>
ld 的选项,您可以将其调用为-Wl,-e,_<symbol>
从叮叮当当。从历史上看,程序的入口点是_start
来自 crt0.o,但是自 Mac OS X 10.8 和 iOS 6.0 以来,Darwin 上就不再有这种情况了,其中LC_MAIN
引入了加载命令(替换LC_UNIXTHREAD
)。仍然可以使用“旧”方式,但必须使用-no_new_main
链接器标志(有一个对应的-new_main
,如果您需要它)。曾经由 crt0.o 承担的职责已转移到动态链接器,/usr/lib/dyld
,它可以同时处理LC_MAIN
and LC_UNIXTHREAD
如所须。
所以给定一个 C 程序main
:
// t.c
#include <stdio.h>
int main(int argc, const char **argv)
{
printf("test %i\n", argc);
return 0;
}
您可以轻松创建一个 C++ 文件,如下所示:
// t.cpp
extern int main(int, const char**);
extern "C" int derp(int argc, const char **argv)
{
return main(0, (const char*[]){ (const char*)0 });
}
并编译它们clang++ -o t t.cpp -xc t.c -Wl,-e,_derp
.
请务必声明derp
as extern "C"
,或在命令行上指定损坏的符号。
您还可以使用以下命令检查生成的可执行文件otool
确保它使用LC_MAIN
而不是LC_UNIXTHREAD
:
bash$ otool -l ./t | fgrep -B1 -A3 LC_MAIN
Load command 11
cmd LC_MAIN
cmdsize 24
entryoff 3808
stacksize 0