Hot to compile a Swift script to a universal binary - swift

We can easily compile a Swift script with:
$ swiftc /path/to/script.swift -o /path/to/binary
However, that only compiles for the current architecture.
$ lipo -archs /path/to/binary
arm64
I found some commands to build for multiple architectures, but they seem to require setting up a new project. I don’t want or need to do that yet, for now I just want to compile a single script file easily, hence swiftc. Is there a way to do this?
As a bonus, does Rosetta 2 need to be installed to generate universal binaries, or is it possible to make them without it?

You would need to build the binary two times, for example, for a project that's targeting macOS, you would compile once with -target x86_64-apple-macos10.15 and the other one with -target arm64-apple-macos10.15.
After that, you would use lipo -create to stitch those together into a single file like this lipo -create <path/to/arm64-slice> <path/to/x86_64-slice> -output <path/to/universal/binary>.
This is how I did it:
➜ UniversalBinaryTest swiftc source.swift -target x86_64-apple-macos10.15 -o binary_x86-64
➜ UniversalBinaryTest lipo -archs binary_x86-64
x86_64
➜ UniversalBinaryTest swiftc source.swift -target arm64-apple-macos10.15 -o binary_arm64
➜ UniversalBinaryTest lipo -archs binary_arm64
arm64
➜ UniversalBinaryTest lipo -create binary_x86-64 binary_arm64 -output binary_universal
➜ UniversalBinaryTest lipo -archs binary_universal
x86_64 arm64
After all of that, you would probably want to re-sign the new binary.
Edit: Actually, it looks like lipo handles signing for you if both slices are signed:
➜ UniversalBinaryTest codesign -s - binary_x86-64
➜ UniversalBinaryTest codesign -vvv binary_x86-64
binary_x86-64: valid on disk
binary_x86-64: satisfies its Designated Requirement
➜ UniversalBinaryTest codesign -vvvvv binary_x86-64
binary_x86-64: valid on disk
binary_x86-64: satisfies its Designated Requirement
➜ UniversalBinaryTest codesign -s - binary_arm64
➜ UniversalBinaryTest lipo -create binary_x86-64 binary_arm64 -output binary_universal
➜ UniversalBinaryTest codesign -vvv binary_universal
binary_universal: valid on disk
binary_universal: satisfies its Designated Requirement

Related

Calling Go Function from java using JNI: Library Not loaded [duplicate]

I want to set under Mac OSX the runtime path of an executable (for the linker) at compile time, such that shared libraries at non-standard locations are found by the dynamic linker at program start.
Under Linux this is possible with -Xlinker -rpath -Xlinker /path/to (or using -Wl,-rpath,/path/to) and under Solaris you can add -R/path/to to the compiler command line.
I found some information that Mac OS X gcc has -rpath support since 10.5, i.e. since ~ 2008.
I tried to get it working with a minimal example - without success:
$ cat blah.c
int blah(int b)
{
return b+1;
}
And:
$ cat main.c
#include <stdio.h>
int blah(int);
int main ()
{
printf("%d\n", blah(22));
return 0;
}
Compiled it like this:
$ gcc -c blah.c
$ gcc -dynamiclib blah.o -o libblah.dylib
$ gcc main.c -lblah -L`pwd` -Xlinker -rpath -Xlinker `pwd`/t
Now the test:
$ mkdir t
$ mv libblah.dylib t
$ ./a.out
dyld: Library not loaded: libblah.dylib
Referenced from: /Users/max/test/./a.out
Reason: image not found
Trace/BPT trap
Thus the question: How to I set the runtime path for the linker under Mac OSX?
Btw, setting DYLD_LIBRARY_PATH works - but I don't want to use this hack.
Edit: Regarding otool -L:
$ otool -L a.out
a.out:
libblah.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.1)
It seems that otool -L only prints the library names (and probable the locations at link time) the executable was linked against and no runtime path information.
Found by experimentation, and inspecting the command lines generated by Xcode for a reference rpath demo project by Dave Driblin:
otool -L shows you the install name of the linked libraries. To get #rpath to work, you need to change the install name of the library:
$ gcc -dynamiclib blah.o -install_name #rpath/t/libblah.dylib -o libblah.dylib
$ mkdir t ; mv libblah.dylib t/
$ gcc main.c -lblah -L`pwd`/t -Xlinker -rpath -Xlinker `pwd`

Compiling Freetype 2.6.5 Xcode for IOS

Alright guys, I posted a similar question and took it down because it wasn't specific enough so here I go. From the zip file of Freetype 2.6.5 I have not been able to create an Xcode project that will compile the library for iOS use, only for i386_64.
I tried the commands here but I don't get past the first commands the and I am getting this
FreeType build system -- automatic system detection
The following settings are used:
platform unix compiler cc
configuration directory ./builds/unix configuration rules
./builds/unix/unix.mk
If this does not correspond to your system or settings please remove
the file `config.mk' from this directory then read the INSTALL file
for help.
Otherwise, simply type
/Applications/Xcode.app/Contents/Developer/usr/bin/make' again to
build the library, or
/Applications/Xcode.app/Contents/Developer/usr/bin/make refdoc' to
build the API reference (this needs python >= 2.6).
cd builds/unix; \
./configure 'CFLAGS=-arch i386' /bin/sh: ./configure: No such file or directory make: *** [setup] Error 127
I also followed the instructions inside the cmakelists.txt that it comes inside the project but still nothing, I still get an xcode project for osx and not for IOS which is giving me a plethora of linking errors. Here is the instructions for your reference.
For an iOS static library, use
#
cmake -D IOS_PLATFORM=OS -G Xcode
#
or
#
cmake -D IOS_PLATFORM=SIMULATOR -G Xcode
I am not sure what else to do. Any help?
Here's an outline of the basic build process to compile the FreeType libaries for iOS:
Download the latest FreeType source code
Extract the archive and cd into the unarchived directory
Setup toolchain and export variables for the architectures desired (arm64, arm7, i386, x86_64)
Compile the source code and build the libraries
For example, the build commands for arm64 might look something like this:
$ export CC="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang"
$ iphoneos="7.0" # target version of iOS
$ ARCH="arm64" # architecture (arm64, arm7, i386, x86_64)
$ export CFLAGS="-arch ${ARCH} -pipe -mdynamic-no-pic -Wno-trigraphs -fpascal-strings \
-O2 -Wreturn-type -Wunused-variable -fmessage-length=0 -fvisibility=hidden \
-miphoneos-version-min=$iphoneos -I/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/libxml2 \
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk"
$ export AR="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar"
$ export LDFLAGS="-arch ${ARCH} -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk \
-miphoneos-version-min=7.0"
$ ./configure --host="aarch64-apple-darwin" --enable-static=yes --enable-shared=no
$ make
$ clean
It's a bit of work to construct the commands for each arch, but
fortunately there's a build
script
— which automatically downloads, extracts, and builds the latest FreeType (2.6.5 currently).
To run the script just use the following command in Terminal:
./build_freetype.sh
The resulting iOS libraries can be found in ~/Desktop/FreeType_iOS_Release when it completes.

how to build mp4v2 for iphone

I'm new to ios development, and I want to use the mp4v2 library. I have successfully compiled for iphone simulator, i386, but am having trouble compiling for the iphone architecture. Configuring/Make-ing for i386 was easy:
./configure --disable-gch --enable-ub=i386
However, using armv6/7 as a tag didn't work
./configure --disable-gch --enable-ub=armv6,armv7
While configuring worked, the make command led to the error below:
/bin/sh ./libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -arch i386 -arch armv6 -arch armv7 -I./include -I./include -I. -I. -Wall -Wformat -g -O2 -fvisibility=hidden -c -o src/3gp.lo src/3gp.cpp
libtool: compile: g++ -DHAVE_CONFIG_H -arch i386 -arch armv6 -arch armv7 -I./include -I./include -I. -I. -Wall -Wformat -g -O2 -fvisibility=hidden -c src/3gp.cpp -fno-common -DPIC -o src/.libs/3gp.o
llvm-g++-4.2: error trying to exec '/usr/bin/../llvm-gcc-4.2/bin/arm-apple-darwin11-llvm-g++-4.2': execvp: No such file or directory
llvm-g++-4.2: error trying to exec '/usr/bin/../llvm-gcc-4.2/bin/arm-apple-darwin11-llvm-g++-4.2': execvp: No such file or directory
lipo: can't figure out the architecture type of: /var/folders/b6/vmqqncd55k79nb1nc4x30nwr0000gn/T//cctU2lnr.out
make: *** [src/3gp.lo] Error 1
How do I compile for iphone?
I guess that this error is caused by trying to find cross compiler from system root path /usr/bin/../llvm-gcc-4.2/bin/arm-apple-darwin11-llvm-g++-4.2 instead of from Developer document.
A little stupid solution is create a symbolic link llvm-gcc-4.2 in system root path /usr, pointing to the real path.
I beleive you may need to verify your xcode-select(1) value so your path includes the new xcode release tree. The tools should have been found under /Applications/xcode with the latest release.

FFMPEG integration on iphone/ ipad project

Can any One Tell me how do i integrate FFMPEG in my iphone/ ipad project.i m using Xcode 4.
i searched a lot but did not find any useful Link .please tell me step by step procedure to integrate FFMpeg in my project.
thanks,
Prerequisites
MacPorts to install:open terminal and type
sudo port install pkgconfig
Launch Terminal and download FFmpeg source
The location of the directory is up to your personal preference and I chose to save it in a ffmpeg folder under my Home folder for easy access later on.
git clone git://source.ffmpeg.org/ffmpeg.git ~/ffmpeg
Before we go further, we need to think ahead and realize that we are likely to do some simulation on Mac itself along with actual testing on iPhone. What we need to do is that we need to build libraries for 3 architectures: armv7 (iPhone 3Gs or later), armv7s (iPhone 5) and i386 (iPhone Simulator).
Let’s create some folders inside ffmpeg folder to hold 3 different builds so that we can lipo those together into one universal build.
cd ffmpeg
mkdir armv7
mkdir armv7s
mkdir i386
mkdir -p universal/lib
To Install gas-preprocessor
Click on the ZIP icon to download gas-preprocessor.
Copy gas-preprocessor.pl to /usr/bin directory.
Change permission of gas-preprocessor.pl by setting the privilege to Read & Write for all.
Configure FFmpeg for armv7 build
Before configuring,
You may refer to the detailed options by going in to the ffmpeg folder and type:
./configure --help
list of options for your reference: FFmpeg Configure Options. The “Components options” will be up to you depending on what you want to do with FFmpeg.
Now run the following configure options:
./configure \
--prefix=armv7 \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--enable-avresample \
--enable-cross-compile \
--sysroot="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk"
\
--target-os=darwin \
--cc="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc"
\
--extra-cflags="-arch armv7 -mfpu=neon -miphoneos-version-min=6.0" \
--extra-ldflags="-arch armv7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk
-miphoneos-version-min=6.0" \
--arch=arm \
--cpu=cortex-a9 \
--enable-pic \
You may get a warning such as:
WARNING: Compiler does not indicate floating-point ABI, guessing soft.
No worries. You should be fine to continue to next steps.
Build FFmpeg for armv7
Run the build commands:
make clean && make && make install
Now you should be able to see files are populated inside the ffmpeg/armv7 folder. We now move onto building for armv7s for iPhone 5.
Configure and Install FFmpeg for armv7s architecture (iPhone 5)
.
/configure \
--prefix=armv7s \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--enable-avresample \
--enable-cross-compile \
--sysroot="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk"
\
--target-os=darwin \
--cc="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc"
\
--extra-cflags="-arch armv7s -mfpu=neon -miphoneos-version-min=6.0" \
--extra-ldflags="-arch armv7s -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk
-miphoneos-version-min=6.0" \
--arch=arm \
--cpu=cortex-a9 \
--enable-pic \
Then build with:
make clean && make && make install
Configure FFmpeg for i386 build
./configure \
--prefix=i386 \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--enable-avresample \
--enable-cross-compile \
--sysroot="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.0.sdk"
\
--target-os=darwin \
--cc="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/gcc"
\
--extra-cflags="-arch i386" \
--extra-ldflags="-arch i386 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.0.sdk"
\
--arch=i386 \
--cpu=i386 \
--enable-pic \
--disable-asm \
Please note the last --disable-asm tag. If you forget to include this tag, you will likely to receive this error:
cc1: error in backend: Ran out of registers during register
allocation! make: *** [libavcodec/h264_cabac.o] Error 1
Build FFmpeg for i386
make clean && make && make install
Create universal library
The lipo commands (assuming you are still under the ffmpeg folder):
(Please note that Mountain Lion-supplied lipo knows nothing about armv7s as of yet. So we need to use xcrun to find the lipo supplied with the SDK.)
cd armv7/lib for file in *.a do cd ../.. xcrun -sdk iphoneos lipo
-output universal/lib/$file -create \
-arch armv7 armv7/lib/$file \
-arch armv7s armv7s/lib/$file \
-arch i386 i386/lib/$file echo "Universal $file created." cd - done cd ../..
Look under universal/lib, you will find all FAT libs freshly baked there. We now turn our attention to linking these static libraries to the Xcode project.
if you are getting error like this Error: No developer directory found at /Developer”? then type
sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer
Linking static libraries in Xcode
Firstly, we pull in the .a files.
Create a new Empty Application using Xcode. Assign a Product Name and Company Identifier. Then click Next and save the project.
Locate the universal libs that we created (the .a files) under ffmpeg/universal/lib.
Drag the .a files into the Frameworks folder in the Project Navigator pane.
Tick “Copy items into destination group’s folder (if needed)”. And click Finish.
Now we take care of the include files.
Locate the include files under ffmpeg/armv7/include.
Drag and drop the content of that folder onto the Project Name folder in the Project Navigator pane.
Again, tick “Copy items into destination group’s folder (if needed)”. Then click Finish.
Finally, we need to set the Header Search Paths for the project.
Click on the Project in the Project Navigator pane.
In the Standard Editor in the middle of the screen, click on Build Settings.
Search for “Header Search Paths”.
Add your project path and set it to Recursive. i.e. $(SRCROOT)
Click on Build Phases.
Under Link Binary With Libraries, add libbz2.dylib and libz.dylib.
Test and verify the working of library
We are not going to be in-depth here. Just to verify that the library is functioning.
Go to your AppDelegate.m, and add:
> #include "avformat.h"
And in the didFinishLaunchingWithOptions function, add:
av_register_all();
if suppose you are getting this errors means
Undefined symbols for architecture i386:
"_iconv", referenced from:
_mail_iconv in libmailcore.a(charconv.o)
"_iconv_open", referenced from:
_charconv in libmailcore.a(charconv.o)
_charconv_buffer in libmailcore.a(charconv.o)
"_iconv_close", referenced from:
_charconv in libmailcore.a(charconv.o)
_charconv_buffer in libmailcore.a(charconv.o)
ld: symbol(s) not found for architecture i386
collect2: ld returned 1 exit status
then add libiconv.dylib framework
you are now ready to dive in to develop using FFmpeg on iOS.
./configure script:
./configure --extra-ldflags=-L/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/usr/lib/system --disable-bzlib --disable-doc --disable-ffmpeg --disable-ffplay --disable-ffserver --enable-cross-compile --arch=arm --target-os=darwin --cc=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc --as='gas-preprocessor/gas-preprocessor.pl /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc' --sysroot=/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk --cpu=cortex-a8 --extra-cflags='-arch armv7' --extra-ldflags='-arch armv7' --enable-pic
this works fine. since the default FFMPEG configuration script has the default Library path set to /usr/lib/system so it can not find library libcache.dylib, so here I have set it to the latest sdk path.

Compiling Freetype for iPhone SDK (XCode)

I was wondering if anyone knew how to configure FreeType in XCode for the iPhone SDK. I have been trying with no success.
Ideally you'll want to build using the latest tools, and as of the release of iOS 6.0 SDK, with a minimum SDK version of 4.3 and with builds for armv7 and armv7s.
Here is the methid I used to build freetype 2.4.10 for iOS. From the root of the freetype 2.4.10 source, do:
mkdir build-armv7
./configure --prefix=./build-armv7 --host=arm-apple-darwin --enable-static=yes --enable-shared=no \
CPPFLAGS="-arch armv7 -fpascal-strings -Os -fmessage-length=0 -fvisibility=hidden -miphoneos-version-min=4.3 -I/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/include/libxml2 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk" \
CC=`xcrun -sdk iphoneos -find clang` \
CFLAGS="-arch armv7 -fpascal-strings -Os -fmessage-length=0 -fvisibility=hidden -miphoneos-version-min=4.3 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk" \
LD=`xcrun -sdk iphoneos -find ld` \
LDFLAGS="-arch armv7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk -miphoneos-version-min=4.3" \
AR=`xcrun -sdk iphoneos -find ar`
make
make install
Next, clean the build directory, and build again for armv7s:
make clean
mkdir build-armv7s
./configure --prefix=./build-armv7s --host=arm-apple-darwin --enable-static=yes --enable-shared=no \
CPPFLAGS="-arch armv7s -fpascal-strings -Os -fmessage-length=0 -fvisibility=hidden -miphoneos-version-min=4.3 -I/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/include/libxml2 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk" \
CC=`xcrun -sdk iphoneos -find clang` \
CFLAGS="-arch armv7s -fpascal-strings -Os -fmessage-length=0 -fvisibility=hidden -miphoneos-version-min=4.3 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk" \
LD=`xcrun -sdk iphoneos -find ld` \
LDFLAGS="-arch armv7s -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk -miphoneos-version-min=4.3" \
AR=`xcrun -sdk iphoneos -find ar`
make
make install
Finally, combine the architectures into a single binary, and remove the unnecessary extra headers etc. for the second architecture (which are identical to the first architecture).
xcrun -sdk iphoneos lipo -create -arch armv7 build-armv7/lib/libfreetype.a -arch armv7s build-armv7s/lib/libfreetype.a -output libfreetype_universal.a
rm -rf build-armv7s
mv -f libfreetype_universal.a build-armv7/lib/libfreetype.a
mv build-armv7 build
I have; this blog post helped immensely:
http://robertcarlsen.net/2009/03/25/openframeworks-iphone-libs-593
(Plus, there are lots of examples lying around google that do similar things.
Use the configure script supplied with Freetype.
mkdir install_dir
If you are compiling for the simulator:
export CFLAGS = "-arch i386 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk"
./configure --prefix=install_dir
if you are compiling for a device:
export CFLAGS = "-arch armv7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk"
./configure --prefix=install_dir --host=arm-apple-darwin
and then
make
make install
You will now find the headers and lib in 'install_dir'.
the 'make install' step is important, as configure will setup the headers correctly. You can't just copy or use them directly from the source tree.
You can build for each platform (simulator and device) and then combine the libs into one multi-architechture lib using the 'lipo' tool.