GithubHelp home page GithubHelp logo

felixzhang00 / cppbuildcacheworkinprogress Goto Github PK

View Code? Open in Web Editor NEW

This project forked from jomof/cppbuildcacheworkinprogress

0.0 1.0 0.0 106.19 MB

License: Apache License 2.0

Shell 0.17% JavaScript 0.01% C++ 3.43% Python 0.04% Perl 0.01% C 0.22% Java 56.17% Prolog 0.01% Kotlin 36.14% CSS 0.01% Makefile 0.01% PureBasic 0.01% HTML 2.18% CMake 0.03% GLSL 0.01% RenderScript 0.09% Batchfile 0.02% Dockerfile 0.01% Starlark 1.45% AIDL 0.01%

cppbuildcacheworkinprogress's Introduction

Mostly From Scratch Guide to Android C++ Build

This repo describes the Android Gradle C++ build process from the perspective of someone who knows Gradle, Android Java build, and basics of C/C++ development but without knowing the Android specific build aspects.

Major elements of this repo:

Ninja, CMake, Gradle

This section describes the build tools we use from the lowest level (Ninja) to the highest (Gradle).

Ninja, the machine language of C++ builds

Ninja is a very low-level C++ build system. Its build files, usually named 'build.ninja' are expressly intended to be generated by a higher-level tool rather than hand maintained by a human. In our case the higher-level tool is CMake. Ninja's responsibilities are:

a) To compose the clang++ flags for each expected .o file

b) To learn and remember the relationship between each .o file and corresponding .cpp and .h files needed to build it

c) To understand which .o files are out of date

d) To build, with parallelization, just the .o files that are out of date

Ninja is widely recognized as the best tool for high-performance, parallel, incremental, C/C++ build scheduling.

In order to achieve (b) Ninja invokes clang++ with the -E flag the first time a .o file is compiled from a .cpp. For subsequent builds, the -E flag is not used unless Ninja detects a change in .cpp or .h files. These dependencies are stored in a proprietary format called .ninja_deps.

The Ninja project is meant to be reused across clean calls so, in our case, it's stored outside the normal build/ folder in a folder named .cxx/.

Resources:

CMake, the meta C++ build-system

CMake is a C/C++ meta build-system. The term meta is used because CMake generates a build system and doesn't directly compile .cpp to .o itself. CMake's responsibilities are:

a) To have a maintainable, human-readable, representation of source files, flags, libraries and their relationships with each other. This information is usually in a file called CMakeLists.txt.

b) To provide reflection on those build relationships so that IDEs can present the structure to users in a helpful way. This includes project structure tree features and language service features like autocompletion.

In our case, CMake generates a Ninja project.

CMake's configuration phase is typically quite slow because it does things like test the clang compiler for features and usually ends up invoking clang++.exe many times.

Resources:

A Brief Aside on compile_commands.json

The file compile_commands.json, created by CMake during the 'configureCMakeDebug' task, contains each output .o file along with the .cpp and Clang flags needed to build it. Here's a what it looks like

{
  "directory": "/Users/jomof/AndroidStudioProjects/CppBuildCacheWorkInProgress/HelloWorld/app/.cxx/Debug/3z5c3158/x86",
  "command": "/path/to/clang/clang++ --target=i686-none-linux-android16 --gcc-toolchain=/path/to/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64 --sysroot=/path/to/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/sysroot -Dnative_lib_EXPORTS -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -mstackrealign -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security   -O0 -fno-limit-debug-info  -fPIC -o CMakeFiles/native-lib.dir/native-lib.cpp.o -c /path/to/sources/native-lib.cpp",
  "file": "/path/to/sources/native-lib.cpp"
}
...

This contains all of the information we need to create a build cache key except for the list of #include files. List of #includes are determined on first build by Ninja and stored in (.ninja_deps)[HelloWorld/app/.cxx/Debug/3z5c3158/x86/.ninja_deps] file.

Android Gradle Plugin integrates C++ build with Java\Kotlin build

Android Gradle Plugin's C++ specific responsibilities are:

  1. The "configure" (called externalNativeJsonGenerator) task invokes CMake to produce a set of Ninja projects. There is one Ninja project per target ABI, per variant.
     ./gradlew configureCMakeDebug
  2. The "build" task execs ninja.exe for each relevant project.
     ./gradlew buildCMakeDebug

The result of (2) is typically a set of .so files that can be packaged into the final APK.

Clean:

./gradlew clean

Will not remove the generated Ninja project but it will delete .o files in that project.

Build HelloWorld Sample

Build Prerequisites

Android Gradle Plugin C/C++ has two prerequisites that typical Java\Kotlin projects don't have.

  1. NDK contains clang++.exe for Android along with headers and libraries. NDK version matters and HelloWorld project in this repo uses version 21.4.7075529

  2. An external native build system. This project uses CMake but there is also a build system in the NDK specifically for Android called 'ndk-build'. The HelloWorld project uses version 3.18.1 of CMake.

Often, (1) and (2) will be downloaded and installed automatically during gradle build.

If this fails, then the fallback is to install Android Studio and, at the Welcome Screen, select 'Configure' at lower right. The SDK Manager -> Appearance & Behavior -> System Settings -> Android SDK -> SDK Tools. Click 'Show Package Details' in lower right and then find the required NDK version in the tree view under 'NDK (Side by side)'.

Repeat the process above for CMake 3.18.1.

In a CI environment, these prerequisites will typically by installed by a command-line tool installed with Android Studio called 'sdkmanager'.

Build

In order to build:

cd HelloWorld
./gradlew assemble

cppbuildcacheworkinprogress's People

Contributors

jomof avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.