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.
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.
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
Install GCC, G++ and Clang/LLVM.
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
How To setup and use Cygwin and MinGW
How To Install and Get Started Cygwin (pronounced as SIG-win) = GNU + Cygnus + Windows. The mother site for Cygwin is…
Make sure you have installed the gcc, g++, cmake packages and setup environment variable
Install Android SDK, NDK and CMake toolchain
Xcode - Apple Developer
Xcode 11 includes everything you need to create amazing apps and to bring your apps to even more devices. Take…
Create the main() function
And build project with CMake
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
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
In order to make C++ visible to Java codes on Android, we have to create an interface called the Java Native Interface (JNI).
Resolving Native Method Names
Dynamic linkers resolve entries based on their names. A native method name is concatenated from the following components:
- the prefix
- 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
Luckily, I found iOS CMake toolchain here:
A tool for generating cross-language type declarations and interface bindings. - dropbox/djinni
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
src/ directory: Containing shared code base for different platforms
tool/ directory: A small python script, used to compile applications for different platforms
runner.bat build -platform windows
./runner build -platform osx
./runner build -platform linux
./runner build -platform android
./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: