Cross-platform C/C++ development (Android/iOS/Windows/MacOS/Linux)

Currently, applications on the market can run on many different platforms. So you have to face to maintain multiple codebases. Cross-platform development is that you only need to maintain one code base and it works on all systems.

The goal of this story is to build a C/C++ development run on different platforms: Android/iOS/MacOS/Windows/Linux.

Advantages

Performance

Unlike some other languages (Java, Python), C/C++ is a compiled language, it translate code line directly into machine code. No virtual machine, no interpreter, no garbage collector. This is the reason why C/C++ is faster than other interpreter languages (such as Java).

Access kernel API

With C/C++, you can call low-level kernel API (syscall, mprotect, mmap …), which cannot be done easily by other language.

Security

C/C++ is a compiled language, meaning its application cannot be statically analyzed easily by Reverse Engineering.

Building the C/C++ project

Now I will demonstrate how to build a C/C++ cross-platform application using CMake

MacOS/Linux

Install GCC, G++ and Clang/LLVM.

Windows

There are many C/C++ compiler on windows: Cygwin, MinGW, Windows Linux Subsystem, Visual Studio … In this article I will choose Cygwin.

How to install Cygwin

Make sure you have installed the gcc, g++, cmake packages and setup environment variable

Android

Install Android SDK, NDK and CMake toolchain

https://developer.android.com/studio/projects/install-ndk

iOS

Install Xcode

Let’s go

MacOS/Linux/Windows:

Create the main() function

And build project with CMake

MacOS/Linux

cmake path/to/hello-cross-platform -DCMAKE_BUILD_TYPE=Debug -B/path/to/hello-cross-platform/build/unix -DCMAKE_CXX_COMPILER_WORKS=TRUE -G “CodeBlocks — Unix Makefiles”

cmake — build /path/to/hello-cross-platform/build/unix — target helloworld — -j 4

Windows

Cygwin build script:

cmake /cygdrive/C/../path/to/hello-cross-platform -DCMAKE_BUILD_TYPE=Debug -B/cygdrive/C/../path/to/hello-cross-platform/build/unix -DCMAKE_CXX_COMPILER_WORKS=TRUE -G “CodeBlocks — Unix Makefiles”

cmake — build /cygdrive/C/../path/to/hello-cross-platform/build/cygwin — target helloworld — -j 4

Android

In order to make C++ visible to Java codes on Android, we have to create an interface called the Java Native Interface (JNI).

Dynamic linkers resolve entries based on their names. A native method name is concatenated from the following components:

  • the prefix Java_
  • a mangled fully-qualified class name
  • an underscore (“_”) separator
  • a mangled method name
  • for overloaded native methods, two underscores (“__”) followed by the mangled argument signature

The disadvantage of this approach is the security problem. On this case JNI method symbols will be exported, so reverse engineering can statically analyzed your code

Another approach is JNI RegisterNatives. No exported symbols !

Here is my implementation

iOS

Luckily, I found iOS CMake toolchain here:

Setup iOS CMake framework

Generating iOS CMake project

cmake /path/to/hello-cross-platform -B/path/to/hello-cross-platform/build/ios -DPLATFORM=IOS -DBUILD_DIR=/path/to/hello-cross-platform/build/ios -DCMAKE_TOOLCHAIN_FILE=/path/to/hello-cross-platform/cmake/utils/ios.toolchain.cmake -DENABLE_BITCODE=FALSE -GXcode

Objective-C++ (named with .mm extension) is mix Objective-C classes and C++ classes

I renamed ViewController.m to ViewController.mm (Objective-C++) so I can use C++ on iOS.

If you want to use Swift, you need to create the bridging header

The code base

The CMakeLists.txt

src/ directory: Containing shared code base for different platforms

tool/ directory: A small python script, used to compile applications for different platforms

Build project:

Windows:

runner.bat build -platform windows

MacOS:

./runner build -platform osx

Linux:

./runner build -platform linux

Android:

./runner build -platform android

iOS:

./runner build -platform ios

This will produce a build folder, containing a production application

I created a demonstration project on Github, you can checkout here: