Xcode 9 - No option to create dylib project iOS - xcode

I remember in old Xcode there was option under Create New Project there was option to create BSD Dynamic Library - dylib. However now I see only Cocoa Framework, Static Library and Metal Library.
Any hints?

You may create a project for an iOS static lib, and create a dynamic lib from the static one with a custom build phase with the following command:
xcrun --sdk iphoneos clang -arch <ARCH> -shared -all_load \
-o lib<NAME>.dylib lib<NAME>.a
where <ARCH> is either armv7 or arm64 and <NAME>is the base name of your lib. You may check or list the architectures with file command. E.g.:
file <path>/lib<NAME>.a`
lib<NAME>.a (for architecture armv7): current ar archive random library
lib<NAME>.a (for architecture arm64): current ar archive random library
If more than one architecture is listed, Xcode has produced a universal static library. In this case you may create a universal shared library with multiple -arch flags:
xcrun --sdk iphoneos clang -arch armv7 -arch arm64 -shared -all_load \
-o lib<NAME>.dylib lib<NAME>.a
You may need to specify additional linker flags (e.g. -l for linking non-standard libs).

Related

Creating a universal binary using Intel compiler

In MacOSX, gcc command line accepts multiarchitecture options:
gcc -arch i386 -arch x86_64 etc.
... and creates a universal binary by compiling and linking for both archs and running lipo for gluing them together.
However using this command line with Intel, produces a compiler warning:
command line warning #10121: overriding '-arch i386' with '-arch x86_64'
Am I doing something wrong or is this a compiler limitation?
I couldn't find anything about it in the Intel developer zone.

Debugging linker error with Xcode - sdl static library

I am trying to follow this guide here for building SDL2 for iOS:
http://lazyfoo.net/tutorials/SDL/52_hello_mobile/ios_mac/index.php
I am able to build the libSDL2.a static library, however I am getting a linker error when I attempt to build his example hello world application which uses it.
Ld /Users/testuser/Library/Developer/Xcode/DerivedData/___PROJECTNAME___-egvszvnfjpicgqdtaazpczjuebut/Build/Products/Debug-iphonesimulator/___PROJECTNAME___.app/___PROJECTNAME___ normal x86_64
cd "/Users/testuser/Documents/iosBuild/SDL iOS Application"
export IPHONEOS_DEPLOYMENT_TARGET=10.0
export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator10.0.sdk -L/Users/testuser/Library/Developer/Xcode/DerivedData/___PROJECTNAME___-egvszvnfjpicgqdtaazpczjuebut/Build/Products/Debug-iphonesimulator -F/Users/testuser/Library/Developer/Xcode/DerivedData/___PROJECTNAME___-egvszvnfjpicgqdtaazpczjuebut/Build/Products/Debug-iphonesimulator -filelist /Users/testuser/Library/Developer/Xcode/DerivedData/___PROJECTNAME___-egvszvnfjpicgqdtaazpczjuebut/Build/Intermediates/___PROJECTNAME___.build/Debug-iphonesimulator/___PROJECTNAME___.build/Objects-normal/x86_64/___PROJECTNAME___.LinkFileList -mios-simulator-version-min=10.0 -Xlinker -object_path_lto -Xlinker /Users/testuser/Library/Developer/Xcode/DerivedData/___PROJECTNAME___-egvszvnfjpicgqdtaazpczjuebut/Build/Intermediates/___PROJECTNAME___.build/Debug-iphonesimulator/___PROJECTNAME___.build/Objects-normal/x86_64/___PROJECTNAME____lto.o -Xlinker -export_dynamic -Xlinker -no_deduplicate -Xlinker -objc_abi_version -Xlinker 2 -lSDL2 -framework GameController -framework Foundation -framework UIKit -framework OpenGLES -framework QuartzCore -framework CoreAudio -framework AudioToolbox -framework CoreGraphics -framework CoreMotion -Xlinker -dependency_info -Xlinker /Users/testuser/Library/Developer/Xcode/DerivedData/___PROJECTNAME___-egvszvnfjpicgqdtaazpczjuebut/Build/Intermediates/___PROJECTNAME___.build/Debug-iphonesimulator/___PROJECTNAME___.build/Objects-normal/x86_64/___PROJECTNAME____dependency_info.dat -o /Users/testuser/Library/Developer/Xcode/DerivedData/___PROJECTNAME___-egvszvnfjpicgqdtaazpczjuebut/Build/Products/Debug-iphonesimulator/___PROJECTNAME___.app/___PROJECTNAME___
ld: library not found for -lSDL2
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Per his instructions, I copied the project template and added the libSDL2.a lib that I built under the Build Phases -> link binary with libraries menu:
Any suggestions for how I can debug this problem?
Edit: My build target configuration in the project which uses the library:
try to build your library with this script. the final product will be placed in your home ~/SDL directory.
#!/bin/sh
PREFIX=$HOME/SDL
SYMROOT="SYMROOT=$PREFIX/release"
SDK_DEVICE="-sdk iphoneos"
SDK_SIMULATOR="-sdk iphonesimulator"
CONF_DEBUG="-configuration Debug"
CONF_RELEASE="-configuration Release"
mkdir -p $PREFIX
cd $PREFIX
wget https://www.libsdl.org/release/SDL2-2.0.4.zip
unzip SDL2-2.0.4.zip
rm -f SDL2-2.0.4.zip
# ------------------------------------------------------------------------
# SDL
# ------------------------------------------------------------------------
cd $PREFIX/SDL2-2.0.4/Xcode-iOS/SDL
SCHEME="libSDL"
PROJ="-project SDL.xcodeproj"
#xcodebuild OTHER_CFLAGS="-fembed-bitcode" OTHER_LDFLAGS="-lobjc" ONLY_ACTIVE_ARCH=NO -arch i386 -arch x86_64 $PROJ $SDK_SIMULATOR $CONF_DEBUG -scheme='$SCHEME' build $SYMROOT
xcodebuild OTHER_CFLAGS="-fembed-bitcode" ONLY_ACTIVE_ARCH=NO -arch i386 -arch x86_64 $PROJ $SDK_SIMULATOR $CONF_RELEASE -scheme='$SCHEME' build $SYMROOT
#xcodebuild OTHER_CFLAGS="-fembed-bitcode" OTHER_LDFLAGS="-lobjc" ONLY_ACTIVE_ARCH=NO -arch arm64 -arch armv7 $PROJ $SDK_DEVICE $CONF_DEBUG -scheme='$SCHEME' build $SYMROOT
xcodebuild OTHER_CFLAGS="-fembed-bitcode" ONLY_ACTIVE_ARCH=NO -arch arm64 -arch armv7 $PROJ $SDK_DEVICE $CONF_RELEASE -scheme='$SCHEME' build $SYMROOT
lipo $PREFIX/release/Release-iphonesimulator/libSDL2.a $PREFIX/release/Release-iphoneos/libSDL2.a -create -output $PREFIX/libSDL2.a
It's likely that the static library you built does not contain the architecture for which you're building your application. You'll need to build a static library that contains the architectures for the platform you want to build.
Also, keep in mind that it's not actually supported to put architectures for different platforms (such as iOS and tvOS, or even iOS and iOS Simulator—the simulators are separate platforms) in a single binary. You'll need a separate library or framework for each platform you're targeting, though each one can of course contain slices for all of that platform's supported architectures.

How to build dylib in XCode?

I have a library in source code, it builds in .a static library, but i need .dylib. So, i choose Mach-O-Type in "Build Settings" as "Dynamic Library", but get error:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static -arch_only x86_64 -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk -L/Users/abc/Library/Developer/Xcode/DerivedData/mylib-fwducbhnvcuzuzaopjfimtlylztm/Build/Products/Debug -filelist /Users/abc/Library/Developer/Xcode/DerivedData/mylib-fwducbhnvcuzuzaopjfimtlylztm/Build/Intermediates/mylib.build/Debug/mylib-osx.build/Objects-normal/x86_64/mylib-osx.LinkFileList -fobjc-link-runtime -framework Foundation -o /Users/abc/Library/Developer/Xcode/DerivedData/mylib-fwducbhnvcuzuzaopjfimtlylztm/Build/Products/Debug/libmylib-osx.a
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: unknown option character `f' in: -fobjc-link-runtime
libtool for some reason uses "-static" instead "-dynamic" flag... Compatibility version i've set. What do you think could be wrong?
object files (.o) could be extracted from archive file (.a) and then packed in .dylib with libtool or gcc

How do I suppress '-arch', 'x86_64' flags when compiling an OpenGL/SDL application with Waf on OSX?

I need to suppress "-arch x86_64 -arch i386" flags Waf is passing to GCC.
I am building an SDL/Opengl application. If I link against 32 bit SDL runtime I get error
Undefined symbols for architecture i386:
"_SDL_Quit", referenced from:
__del_video in SDL_functions.c.2.o
__init_video in SDL_functions.c.2.o
If I link against 64 bit SDL runtime, I get error "Undefined symbols for architecture x86_64"
The compiler is apparently using flags
-arch x86_64 -arch i386
I understand that this causes GCC on OSX to try to compile for both architectures. I want to either compile for 64 bit, or compile for 32 bit. How do I suppress the flags for one architecture?
I found out in my case that the double arch flags were originating here, specifically from distutils.sysconfig.get_config_var('LDFLAGS'). This returns the LDFLAGS that Python thinks you should link Python modules with. In my case, file $(which python) is a "Mach-O universal binary with 2 architectures", so Python thinks you should link with -arch x86_64 -arch i386 -Wl,F.
My problem was that I was building a Python native module that needed to link against Python and another library which was not built with both arches. When building my module with both arches, linking failed with "symbols not found", because both arches were not available in the third-party library.
Since waf unfortunately doesn't allow you to override its computed flags with your own flags, as Automake does, I could only fix this by messing directly with my ctx() object in my wscript:
for var in ['CFLAGS_PYEMBED', 'CFLAGS_PYEXT', 'CXXFLAGS_PYEMBED',
'CXXFLAGS_PYEXT', 'LINKFLAGS_PYEMBED', 'LINKFLAGS_PYEXT']:
newvar = []
for ix, arg in enumerate(ctx.env[var]):
if '-arch' not in (arg, ctx.env[var][ix - 1]):
newvar.append(arg)
ctx.env[var] = newvar
(This removes all -arch flags and their arguments from the relevant variables. Since I was also passing my own -arch flag in my CFLAGS, it now does not get overridden.)
I don't know of a way to issue a command/flag to suppress other flags. However, to compile for only 64 or 32 bits, you can use -m64 or -m32, respectively. Since you're compiling for both architectures, -m32 might be your only option because -m64 won't work for i386.

HICococaView not compiling with GCC 4.2

We have a large Carbon based (PowerPlant) application that we are looking finally to port over to Cocoa. We will be doing this incrementally and a first step is to try to get a Cocoa view into a Carbon window.
The problem seems to be that when I use any of the functions from HICocoaView.h the application will not compile unless I switch the compiler from GCC 4.2 to GCC 4.0.
Using any compiler other than GCC 4.0 I get an error in XCode that the functions are unavailable e.g. "HICocoaViewCreate is unavailable".
I can't figure out why this won't work, will we have to switch to the older compiler or is there some setting we can change to get it to compile?
Any help or pointers to useful documentation on porting Carbon to Cocoa greatly appreciated. I've read through the old Carbon Cocoa Integration guide but it doesn't mention this.
Edit: As requested here's the output from the build for the gcc command line:-
/Developer/usr/bin/gcc-4.2 -x objective-c++ -arch i386
-fmessage-length=0 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -O0 -Wmissing-prototypes -Wreturn-type -Wunused-variable -Wunused-value -D__IMPRO_DEBUG_BUILD__ -isysroot /Developer/SDKs/MacOSX10.5.sdk -mfix-and-continue
-mmacosx-version-min=10.5 -gdwarf-2 "-I/Users/matt/Code/MattsFeatureBranch/Modules/User
Notes/Mac/../../../(Intermediates)/Debug/User Notes.build/Debug/Module
Bundle.build/User Notes.hmap" -Wparentheses -Wno-conversion
-Wno-sign-compare -Wno-multichar -Wno-deprecated-declarations "-F/Users/matt/Code/MattsFeatureBranch/Modules/User
Notes/Mac/../../../Build Products/Mac/Debug/Plugins" "-F../../../Build
Products/Mac/Debug" "-F../../../Third Party/Mac/NVidia"
"-I/Users/matt/Code/MattsFeatureBranch/Modules/User
Notes/Mac/../../../Build Products/Mac/Debug/Plugins/include"
-I../X-Platform -I../../../Common/Mac -I../../../Common/X-Platform -I../../../DLLs/ArcadiaCore/Mac -I../../../DLLs/ArcadiaCore/X-Platform "-I../../../Third Party/Mac/Powerplant"
-I/Developer/SDKs/MacOSX10.5.sdk/Developer/Headers/FlatCarbon "-I../../../Third Party/X-Platform/boost_1_38_0"
-I../../../DLLs/ArcadiaImaging/Mac -I../../../DLLs/ArcadiaImaging/X-Platform -I../../../DLLs/ArcadiaDatabase/Mac -I../../../DLLs/ArcadiaDatabase/X-Platform -I../../../DLLs/ArcadiaUI/Mac -I../../../DLLs/ArcadiaUI/X-Platform "-I../../../Third Party/Mac/Powerplant Extras"
-I../../../DLLs/ArcadiaDevices/Mac -I../../../DLLs/ArcadiaDevices/X-Platform -I../../../DLLs/Arcadia3D/Mac -I../../../DLLs/Arcadia3D/X-Platform "-I/Users/matt/Code/MattsFeatureBranch/Modules/User
Notes/Mac/../../../(Intermediates)/Debug/User Notes.build/Debug/Module
Bundle.build/DerivedSources/i386"
"-I/Users/matt/Code/MattsFeatureBranch/Modules/User
Notes/Mac/../../../(Intermediates)/Debug/User Notes.build/Debug/Module
Bundle.build/DerivedSources" -fpermissive -fasm-blocks -include
"/Users/matt/Code/MattsFeatureBranch/Modules/User
Notes/Mac/../../../(Intermediates)/Debug/SharedPrecompiledHeaders/XPrefix-acshmfbgvfwrdqbyayvgnckkypgr/XPrefix.h"
-c "/Users/matt/Code/MattsFeatureBranch/Modules/User Notes/Mac/MUserNotesView.cpp" -o
"/Users/matt/Code/MattsFeatureBranch/Modules/User
Notes/Mac/../../../(Intermediates)/Debug/User Notes.build/Debug/Module
Bundle.build/Objects-normal/i386/MUserNotesView.o"
From HICocoaView.h in both the 10.5 and the 10.6 SDK:
#if !__LP64__
extern OSStatus
HICocoaViewCreate(
NSView * inNSView, /* can be NULL */
OptionBits inOptions,
HIViewRef * outHIView) AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER;
…
#endif /* !__LP64__ */
This means that HICocoaViewCreate() is not available on 64-bit (LP64) targets, i.e., if you need to use this function you have to target i386 (or PowerPC).
GCC 4.0 targets i386 by default even when run on 64-bit capable machines. On the other hand, GCC 4.2 targets x86_64 by default on 64-bit machines:
$ gcc-4.0 a.c; lipo -info a.out
Non-fat file: a.out is architecture: i386
$ gcc-4.2 a.c; lipo -info a.out
Non-fat file: a.out is architecture: x86_64
If you want to use both HICocoaViewCreate() and GCC 4.2, tell it to create (and use) 32-bit objects/binaries by passing -arch i386. For instance,
$ gcc-4.2 a.c -arch i386; lipo -info a.out
Non-fat file: a.out is architecture: i386
Even though part of Carbon is available for 64-bit targets, you’ll notice in the 64-bit Guide for Carbon Developers that much of HIToolbox simply isn’t available.
As for migrating from Carbon to Cocoa, it’s a whole new Objective-C API for the most part. I’m not aware of any simple migration guide, and Peter Hosey’s answer to a similar question on Stack Overflow is worth reading.

Resources