NDK cross compilation foundation of audio and video learning


I have collected some learning materials, including a lot of learning, interview, middle and high-level fluuter materials, and a lot of video explanations. If any students want to know more, please see the end of the article for details. We also welcome all the great gods to install X.

Cross compilation

Cross compilation is that the compilation environment of a program is inconsistent with the actual running environment, that is, executable code on one platform is generated on another platform.

For example, in NDK, if the C / C + + code generated on MAC, win or Linux wants to run on Android platform, cross compilation needs to be used.

Generally speaking, your computer and mobile phone use different CPUs, so the instruction set of CPU is different. For example, the instruction set of arm cannot run on X86.

Common compiler tool chain


GNU   C compiler. Originally, it could only deal with C language, and soon expanded to deal with C + +( The GNU program, also known as the granu program. The goal is to create a completely free operating system)

After that, Android completely removed GCC and used clang compilation by default, so when cross compiling ffmpeg with different versions of NDK, the same script can be compiled in the old version of NDK, but the old version will not.

The author will use the latest NDK to cross compile the latest version of ffmpeg in the later learning process, and will record the learning process through articles. Interested students can continue to pay attention.


GNU   C + + compiler

Both GCC and G + + can compile C / C + +, but the behavior is different when compiling.

There are the following differences between GCC and G + +

For the source file with suffix. C, GCC regards it as a C program and G + + as a C + + program; If the suffix is. CPP, both will be considered as C + + programs

G + + will automatically link to the C + + standard library STL, but GCC will not

GCC does not define__ Cplusplus macro, and G + + will


clang   Is a lightweight compiler for C, C + +, object-c. Based on llvm  ( Llvm is a framework system of architecture compiler written in C + +, which can be said to be a library for developing compiler related

Compared with GCC, clang has the advantages of faster compilation speed and smaller compilation output, but some software will make errors when compiling with clang because of the content in the source code.

In addition, clang + + is also a compiler. Clang + + and clang are equivalent to the difference between GCC and G + +.

Static and dynamic libraries

Static library refers to adding all the code of the library file to the executable file when compiling the link, so the generated file is relatively large, but the library file is no longer needed at run time. The suffix in Linux is “. A”.

In contrast to the static library, the dynamic library does not add the code of the library file to the executable file when compiling the link, but loads the library from the runtime link file when the program is executed. The suffix in Linux is “. So”. GCC uses dynamic libraries by default at compile time.

To sum up, the static library saves running time, the dynamic library saves running space, and the typical time for space can be selected according to the situation in the development process.

In Java, dynamic libraries can only be used directly without encapsulation.

Compiler process

A C / C + + file can become an executable file only after preprocessing, compilation, assembly, and linking.

Let’s take the simplest c language program as an example:


gcc -E main.c -o main.i

-The function of E is to make GCC stop compiling after preprocessing.

The preprocessing stage mainly deals with include and define. It includes #include. H   Insert the file into the location of #include, and replace the macro defined with #define in the source program with the actual string.

Compilation phase

gcc -S main.i -o main.s

-S is used to compile and generate assembly files.

At this stage, GCC should first check the standardization of the code and whether there are syntax errors, so as to determine the actual work of the code. After checking that there is no error, GCC translates the code into assembly language.

Assembly phase

gcc -c main.s -o main.o

Assembly stage  . S file is translated into binary machine instruction file. O, and. C is received at this stage,  . i,  . There is no problem with the files of S.

Link phase

gcc -o main main.s

In the link phase, the function library is linked. There is no function implementation of “printf” defined in main. C, and only the declaration of this function is included in “stdio. H” included in precompiling. The system implements these functions asLibc.so dynamic library.

One step:

gcc main.c -o main

Here we succeed in   mac   The platform generates an executable file, and you can see the output when running. Imagine that we can copy this executable file to an Android phone for execution?

Certainly not. The main reason is the of the two platforms   CPU   The instruction set is different, and the instructions cannot be recognized at all. At this time, cross compilation is in use.

If you don’t believe it, you can   main   Executable file   push   To mobile phone  / data/local/tmp   Inside, verify whether it can be output correctly.

It doesn’t have to be / data / local / tmp. You can push it to any directory with read, write and executable permissions for testing.

Cross compilation experiment

Next, we use NDK to cross compile main. C to see if the compiled executable can really run on Android.

The author takes armeabi as an example to cross compile on Mac platform.

Since GCC has been removed, we use clang for cross compilation.

First find the clang tool chain

Execute command

The executable files can be generated normally on the Mac platform. We can push the executable files to this directory, and then execute them with ADB to see the output. It shows that our cross compilation is successful.

How to cross compile GCC without using clang?

First, find the GCC tool chain

Then execute the GCC compile command

We found that the report was wrong

Stdio. H header file not found

This error means that the compiler can’t find what we introduced when we compiled it   stdio.h   Header file, how do you tell the compiler   stdio.h   Where is the header file?   The following knowledge points explain how to specify these error header files

We tell the GCC tool to chain to that directory to find the header file through the parameters, pass the parameters in and try again

Or report an error

The types. H header file was not found

Because we couldn’t find the header file, we went to the header file search directory configured by – issystem and found that both aarch64 Linux Android and arm linux Android have a subdirectory of ASM, so the compiler doesn’t know to use that. Let’s specify it again.

Finally, we succeeded. We pushed the executable file to the directory of the mobile phone, and then executed it with ADB to see the output.

Here, we use clang and GCC for cross compilation. It is found that clang is simpler and can be compiled directly by finding the path of the tool chain. However, GCC is more complex and needs to specify multiple parameters.

Here we need to understand what each parameter means:

for example   gcc  — SysRoot = directory 1  – isysroot   Catalog 2  – isystem   Catalog 3  – I directory 4   main.c

What I mean is   lookup   Directory 1 / usr / Lib   Library files

Find directory 2  / usr/include   Header file

lookup   Catalog 3   Header file under

lookup   Table of contents 4   Header file under.

For example:

gcc  – L directory 1  – L library name

Linked NDK logstore:

gcc  – LC: NDK path \ platforms \ android-21 \ arch arm \ usr \ Lib

-llog -lGLESv2


gcc  — SysRoot = NDK path \ platforms \ android-21 \ arch arm

-llog -lGLESv2

Generate dynamic library

gcc -fPIC -shared main.c -o libTest.so


clang -fPIC -shared main.c -o libTest.so

The. So file can be generated even without – FPIC, but there are requirements for the source file,

Because so compiled without FPIC must redirect all target addresses when loaded into the address space of the user program, it cannot refer to code from other places.

To verify whether the compiled so dynamic library can be used normally, you can call the test through JNI.

To learn more about Android advanced, advanced, fluent and interview materials, please stamp the link below

https://shimo.im/docs/dYkqrQcyr98jPKYX/The advanced materials of Android learning interview fuluter are available for free. You can copy the link and open it with a graphite document app or applet.