Integrating libraries written in C/C++ and Go to an iOS project
We ran across an interesting use case for a C library recently. One of our projects needed a direct printer integration that would not work over AirPrint. We got in touch with the printer company then they provide us with a C library source code. This printer library had never been integrated into a Mac or iOS application before.
Compiling C source code for iOS
There are two ways to use C source code in an iOS project:
- Directly adding the source code to the iOS project. If project is written in swift, using the code with a bridge (Objective-C may be needed).
- Creating a dynamic or static library. We started by creating a makefile that contained project headers and flags. In our case, it was compiled successfully but was not compatible with iOS.
Step 1: Create makefile to compile C source code
CC = gcc
INCLUDES = -I../inc/
CFLAGS += $(INCLUDES)
OBJS = object1.o \
object2.o \
...
all: $(OBJS)
.PHONY: clean
clean:
$(RM) $(OBJS)
Then, after a quick research, we needed to pass architectures and SDK root to compile for iOS platform.
Step 2: Update makefile for compiling source code to iOS platforms
For simulator:
CC = gcc
INCLUDES = -I../inc/
CFLAGS += -arch x86_64 -arch i386 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk
CFLAGS += $(INCLUDES)
OBJS = object1.o \
object2.o \
...
all: $(OBJS)
.PHONY: clean
clean:
$(RM) $(OBJS)
For iPhone OS:
CC = gcc
INCLUDES = -I../inc/
CFLAGS += -arch armv7 -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk
CFLAGS += $(INCLUDES)
OBJS = object1.o \
object2.o \
...
all: $(OBJS)
.PHONY: clean
clean:
$(RM) $(OBJS)
After compiling C code to static libraries, you need to combine to one static library with using lipo
command
Step 3: Combine static libraries into single one
$ lipo -create lib_simulator.a lib_ios.a -output lib.a
Then you can use this library by dragging into the iOS project. In addition to static library, you need to include header files as well.
Step 4: Drag library to project with header files
On the other hand, you may have an already compiled static library. In that case, it may contain both architectures, and you can remove specific architectures from it using:
$ lipo -remove i386 lib.a
In iOS, there are 2 different architectures: Simulators use i386 and x86_64.
Xcode compiler cannot separate the unncessary (simulator) architectures from the rest of the library. If you are linking the static library to your project, you should remove unncessary architectures from the library.
To solve this problem, we created another target for simulator and put the combined library to that target. For the App Store and Ad Hoc release target, it contains only real device architectures.
Compiling Go project using Gomobile
Gomobile is a tool for building and running mobile apps written in Go. It can convert Go language to compilable code for mobile. We used this is to add a library that is written in Go in mobile apps.
Step 1: You need to install Go. You can do this on Go website with your preferred installing style. https://golang.org/doc/install
Step 2: You need to set your Go paths if it is needed for your install type. It is important for setup of GoMobile.
Step 3: You need to install go mobile on terminal by:
$ go get golang.org/x/mobile/cmd/gomobile $ gomobile init
This will install and initialize gomobile.
After the installation, you can download your Go source code that will be converted to library and use that directory for your bindings. Then we can continue with library binding. We used bind command for this action.
You need to set target parameter as “ios” or “android”. This is the targeted system name. Android is the default. To build the library for ios, it must be run on an osx and Xcode must be installed.
Step 4: You need to bind codes into iOS Framework
Example command that we used:
$ gomobile bind -target=ios github.com/{project_name}/{source_code_1} github.com/{project_name}/{source_code_2} ..
Step 5: Drag framework to iOS Project
After these, your mobile compilable Go code is ready. You can read and discover more on docs here: https://godoc.org/golang.org/x/mobile/cmd/gomobile