Вы можете использовать опцию -e <symbol>
ld, которую вы можете вызвать как -Wl,-e,_<symbol>
из clang. Исторически, точка входа в программу была бы _start
из crt0.o, однако это не было делом в Дарвине с Mac OS X 10.8 и iOS 6.0, где была введена команда загрузки LC_MAIN
(заменившая LC_UNIXTHREAD
). «Старый» способ все еще можно использовать, но его необходимо явно включить с помощью флага компоновщика -no_new_main
(который имеет аналог -new_main
, если он вам когда-нибудь понадобится). Обязанность, некогда выполняемая crt0.o, была перенесена на динамический компоновщик /usr/lib/dyld
, который может обрабатывать как LC_MAIN
, так и 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
как 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