Integrating libraries written in C/C++ and Go to an iOS project

Ömer ASLAN
Hipo
Published in
3 min readMay 4, 2020

--

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:

  1. 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).
  2. 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

--

--