The actual entry point to an executable is controlled by the
LC_MAIN
load command:
$ otool -l build/Debug/MainTest | grep -A 3 LC_MAIN
cmd LC_MAIN
cmdsize 24
entryoff 3872
stacksize 0
but that doesn’t point to
main
directly. Rather, it points to
start
, which then calls
main
.
start
comes from the ‘C runtime’ (aka
crt), which is code that the build system links into your executable automatically. You can find this within the platform SDK:
$ nm /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib/crt1.o
…
U _main
…
0000000000000000 T start
The reason why
-e
isn’t doing what you expect is pretty clear based on its description in
ld
:
Specifies the entry point of a main executable. By default the entry name is
start
which is found in
crt1.o
which contains the glue code need to set up and call
main
.
You could certainly play linker games to resolve this issue but I don’t think that’s the best option. You’re basically transferring the ugliness from the source code to the build system, and it seems likely that that will make things harder to understand.
Does the Obj-C
main
need to ‘wrap’ the C++ ‘main’? That is, both run before and after it? Or does it just need to run first? If it just needs to run first, the simplest solution would be something like this:
int main(…) {
PlatformMainStart();
… do whatever your C++ `main` does …
}
and then define
PlatformMainStart
to do stuff on Apple platforms and be a no-op on other platforms.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"