I have the following program:
#include <stdio.h>
int bob() {
printf("bob\n");
return 0;
}
int main() {
printf("main\n");
return 0;
}
On Linux, I can enable a custom entry point via:
gcc test.c -Wl,-e,bob
When I run the resulting program, I get:
./a.out
bob
On OS X, however, this doesn't work:
clang test.c -Wl,-e,bob
./a.out
main
I've tried everything to get this to work. I think it might be a bug. Here's the output with the -v
option:
clang test.c -Wl,-e,bob -v
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.9.0 -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name test.c -mrelocation-model pic -pic-level 2 -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 236.3 -v -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/5.1 -fdebug-compilation-dir /Users/mfichman/jogo -ferror-limit 19 -fmessage-length 125 -stack-protector 1 -mstackrealign -fblocks -fobjc-runtime=macosx-10.9.0 -fencode-extended-block-signature -fdiagnostics-show-option -fcolor-diagnostics -vectorize-slp -o /var/folders/4z/q41by0256hjc7s6v8ljmfpw8lywh5g/T/test-9b80a6.o -x c test.c
clang -cc1 version 5.1 based upon LLVM 3.4svn default target x86_64-apple-darwin13.3.0
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/5.1/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
/usr/include
/System/Library/Frameworks (framework directory)
/Library/Frameworks (framework directory)
End of search list.
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.9.0 -e bob -o a.out /var/folders/4z/q41by0256hjc7s6v8ljmfpw8lywh5g/T/test-9b80a6.o -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/5.1/lib/darwin/libclang_rt.osx.a
You can see that clang
is correctly passing -e
to ld
, so maybe this is a problem with Apple's ld
. If that's the case, I'd be interested in workaround solutions.
Clang is also provided in all major BSD or GNU/Linux distributions as part of their respective packaging systems. From Xcode 4.2, Clang is the default compiler for Mac OS X.
To compile a C++ program on the command line, run the clang++ compiler as follows: $ scl enable llvm-toolset-6.0 'clang++ -o output_file source_file ...' This creates a binary file named output_file in the current working directory. If the -o option is omitted, the clang++ compiler creates a file named a.
clang++.exe should be located in C:\Program Files\LLVM\bin , which should be in your system PATH.
The default entry point overridden by the -e
argument is not _main
but rather start
, which is responsible for setting up and calling _main
, then passing the return value of _main
to _exit
. If you specify your own entry point you'll need to perform these steps yourself. There's currently no way to have this initialization performed for you but use a different main function as use of _main
is hard-coded into the tools.
The reason your -e argument is ignored is due to a change in 10.8. Prior to this release the implementation of start
was linked into each application via crt1.o
. In 10.8 the start
processing can be performed by dyld and the LC_MAIN load command specifies the offset to the main function within the program. Changing this offset appears to be what you want, but this is not currently possible as when the LC_MAIN startup method is used ld always uses _main
and disregards the -e
argument. To specify your own entry point you need to tell ld to use the old method of program startup, which you can do for an application with a deployment target of 10.8 or later by passing -no_new_main
to the linker. This is the default behavior for applications with a deployment target earlier than 10.8.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With