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 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.
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.
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.
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.
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.
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
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.
gcc – L directory 1 – L library name
Linked NDK logstore:
gcc – LC: NDK path \ platforms \ android-21 \ arch arm \ usr \ Lib
gcc — SysRoot = NDK path \ platforms \ android-21 \ arch arm
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.