GCC manual says:
file.m
Objective-C source code. Note that you must link with thelibobjc
library yo make an Objective-C program work.
And:
-lobjc
You need this special case of the-loption in order to link an
Objective-C or Objective-C++ program.
However, I can succesfully compile a program with simply:
$ cc prg.m -framework Foundation
Is it a linker default, when you include a framework? If so, where is it
documented? The program gets linked anyway:
$ otool -L a.out
a.out:
/System/Library/Frameworks/Foundation.framework/.../Foundation (...)
/usr/lib/libSystem.B.dylib (...)
--> /usr/lib/libobjc.A.dylib (...)
/System/Library/Frameworks/CoreFoundation.f...k/.../CoreFoundation (...)
This is because the Foundation framework is already linked with libobjc.
So on OSX, you'll need -lobjc option only if you doesn't link with the Foundation framework (which is very rare).
Related
I'm trying to convert a java library to objective-c using j2objc and include the generated objc files into my XCode project. I managed to generate the objc files, but XCode gives me the following error: https://i.stack.imgur.com/QX3zF.png
I used lipo -info on a .o file and I get this "architecture: x86_64". Does it mean those objc files are not meant to run on arm64 architectures and if so, how can I solve this ? Are there any flags I could use to generate the files for arm64 ?
A previous error I had was "ARC forbids explicit message" and I solved this by adding a compiler flag -fno-objc-arc to all the compile sources related to this error. Is this solution safe ?
To compile for arm64, the -arch arm64 and -isysroot IPHONE_SDK_DIRECTORY flags are needed. To find the IPHONE_SDK_DIRECTORY on your system, run xcrun -sdk iphoneos --show-sdk-path.
There's nothing J2ObjC-specific about this, they are normal iOS flags you'll find in you look at the log of a successful compile of an Objective C file in Xcode and click its right button to expand and show all the flags used.
J2ObjC by default does not generate ARC code, so the -fno-objc-arc flag is okay. If you would prefer ARC, run j2objc with its -use-arc flag. Don't compile those generated files with -fno-objc-arc, however, as objects won't be released when your app is finished with them.
In the old days I could have compiled objective-c .m files with
$ gcc -fobjc-gc-only -framework Foundation sample.m
$ ./a.out
But now it doesn't work because there is a high chance the program has
#autoreleasepool { ... }
clause. How do I compile an objective-C on command-line now?
So I just tried out clang and it worked out beautifully.
$ clang -fobjc-gc-only -framework Foundation sample.m
$ ./a.out
2013-09-22 20:17:57.150 a.out[19858:903] Hello world.
Case closed! :)
xcodebuild is what the XCode IDE uses under the hood to build you app, and what you use in things like CI servers to kick off a build from the command line. It uses your .xcproj or .xcworkspace files to work out what to build, so that may still be too high level for you.
In which case, under xcodebuild is clang and llvm. Clang replaced gcc, and is somewhat backwardly compatible, so that would be where you would want to start I would think.
Is it possible to bundle a Mono executable using mkbundle that uses the sgen GC?
I assume that because the produced bundle requires the libmono-2.0.so.1 instead of the libmonosgen-2.0.so that it is using the standard boehm GC. I have tried using $MONO_OPTIONS=--gc=sgen but the resulting bundle still requires the non-sgen lib.
Am I misunderstanding the use of the libmono and libmonsgen libs?
Thank you for any assistance or guidance
This is a bit tricky, because Mono actually has two separate executables and two separate libraries, one for each garbage collector. For example, if you run mono --gc=sgen ... then mono will actually do an execvp() of mono-sgen ... to switch to a different executable.
Similarly, mkbundle will use pkg-config to select the library and link one or the other (i.e. whichever is the system default). To get the other library, there are two options:
One is to rebuild Mono with sgen being the default. Obviously, that may not be a viable solution.
The alternative is to use pkg-config to override the selection. You'd create a copy of mono-2.pc, replace -lmono-2.0 with -lmonosgen-2.0, update prefix and exec_prefix and use the PKG_CONFIG_PATH environment variable to pick that version.
Note that I've never actually tried the latter, but there is no reason why it shouldn't work, since pkg-config is where mkbundle gets the library path from.
Thanks for this question as it helps me to determine why one of my applications is running too slowly after bundling with the mkbundle. It was because of the Boehm GC engine being used.
To include SGen you just need to invoke mkbundle with --keeptemp flag and then rewrite compiler command (which is printed by mkbundle) to include monosgen-2 instead of mono-2.
Example: (for Mac, but could be easily rewritten for Linux)
export PATH=/Library/Frameworks/Mono.framework/Commands/:$PATH
export AS="as -arch i386"
export CC="cc -arch i386 -framework CoreFoundation -lobjc -liconv"
mkbundle TestApp.exe --deps --static -o TestAppBundleName --keeptemp
cc -arch i386 -framework CoreFoundation -lobjc -liconv -o TestAppBundleName -Wall `pkg-config --cflags monosgen-2` temp.c `pkg-config --libs-only-L monosgen-2` `pkg-config --variable=libdir monosgen-2`/libmonosgen-2.0.a `pkg-config --libs-only-l monosgen-2 | sed -e "s/\-lmonosgen-2.0 //"` temp.o
What options set, to statically linked the library curl ?
Library should be integrated to executable file.
tried different: added options g++ -DCURL_STATICLIB -lcurl ... added #define CURL_STATICLIB to the code ..., in the IDE NetBeans added libcurl.a, libcurldll.a ... etc.,
Compile is successful and all works great. But still require external libcurl.dll! (Size of executable file also increases!)
What's wrong ? might have something add to the IDE (also used NetBeans, Eclipse)
Please show a correct example as you would make
Executable file should be without calling an external dll library
it my first question :)
Fix.
Example compile for library curl with OpenSSL + zlib + libidn + libssh2 + librtmp:
g++ -static main.cpp -lcurl -lidn -lwldap32 -lssh2 -lz -lrtmp -lssl -lssl32 -lcrypto -lgdi32 -lws2_32 -lwinmm -o test.exe
note: here shouldn't be specified -lcurldll. This will lead to that: compile is successful, but still require external libcurl.dll
you need to specify -static in the linker options
When compiling Objective-C from the command line (gcc), what are some good flags to use? Many of the standard C flags (-Wall, -ansi, etc) don't play well with Objective-C.
I currently just use -lobjc and -frameworkwith various frameworks.
Many of the standard C flags (-Wall, -ansi, etc) don't play well with Objective-C
-Wall works perfectly fine with Objective-C.
The thing to do is build an Objective-C file with Xcode and have a look at the build transcript. I've just done that and here are some highlights:
-x objective-c I guess that means "compile as Objective-C", probably important
-arch x86_64 build for a particular CPU architecture
-std=gnu99 build for C99 + GNU extensions (actually surprised me, I thought Xcode used -std=c99).
-isysroot .... specifies the location of the SDK.
-mmacosx-version-min=10.6 I am compiling for 10.6 and up
-fobjc-gc-only this file was intended to be used with garbage collection and won't work without it, so I compile for GC only.
-Wall the obvious.
If you are compiling from the command line, it's probably a good idea to set the option to treat warnings as errors. I don't from within Xcode because the build results window remembers the uncleared warnings from previous builds.