Library (library)

In the course of normal development, we must have touched on libraries, so what is a library?

In plain English, a library is a piece of compiled binary code with a header file that others can use.

The usefulness of the library

  1. Some code needs to be used by others, but you don’t want others to see the source code, so it is wrapped in the form of a library, exposing only the initial files.
  2. For code that doesn’t require major changes, and we want to reduce compile time, we can package it as a library, because a library is a compiled binary, and we just need toLinkWill not waste compilation time.

Link

Libraries need to be linked when they are used, and there are two types of links: static and dynamic.

Static library

Definition: A static library is a static linked library: it can be simply viewed as a collection of object files, that is, many object files are compressed and packaged to form a file. For example, lib for Windows,.A for Linux and.framework for Mac.

Disadvantages: waste of memory and disk space, module update difficult.

Static library file format

Common file formats for static libraries:

  • .a
  • .framework(Both dynamic libraries and dynamic libraries)
  • xcframeworkIs officially recommended and supported by Apple to more easily represent a multiple platform and architecture distribution binary library format, requiredXcode11The above support

Xcframework: Compare xcFramework to traditional framework:

  1. You can use a singlexcframeworkFile provides distribution binaries for multiple platforms
  2. withFat HeaderIn contrast, it can be divided by platform and can contain different platform files for the same architecture
  3. Scripts are no longer needed to strip away unwanted architecture at use

Exploring static libraries

I just said that static libraries are collections of object files, so is that the case?

Here we take the most familiar AFNetWorking for analysis and get the. A file

Run the file libAFNetworking. A command to check that this is an archive file

Ar was mentioned earlier. View the AR command through the terminal

Use the ar -t libAFNetworking. A command to view the files

Verify that a static library is indeed a collection of object files.

Linked static library

Write AFNetWorking in.m and see how you can link to it using Clang

As you can see, Clang is a compiler for C, C++, Objc, including preprocessing, parsing, optimization, code generation, assembly, and linking.

To link, first compile test.m into the target file test.o

Use clang-x objective-c \ -target arm64-apple-macos12.0.1 \ -fobjc-arc \ -isysroot / Applications/Xcode. App/Contents/Developer/Platforms/MacOSX platform/Developer/SDKs/MacOSX12.0 SDK \ – c test. M – o Test.o but found an error

If the Header file is not found, we need to tell it the Path, Header Search Path, or -i for Clang

Use the following command:

Clang-x objective-c \ -target arm64-apple-macos12.0.1 \ -fobjc-arc \ -isysroot / Applications/Xcode. App/Contents/Developer/Platforms/MacOSX platform/Developer/SDKs/MacOSX12.0 SDK \ -i/AFNetworking \ -c test.m -o test.o

The test.o file has been successfully generated

Then use the command:

Clang-target arm64-apple-macos12.0.1 \ -fobjc-arc \-isysroot / Applications/Xcode. App/Contents/Developer/Platforms/MacOSX platform/Developer/SDKs/MacOSX12.0 SDK \ - l. / AFNetworking \-lAFNetworking \test.o -o test

Link successful, get executable file

Clang instruction analysis

clang:

  • -x: Specifies the language type of the compiled file
  • -g: Generates debugging information
  • -c: Generates the target file and runs onlypreprocess,compile,assembleBut it doesn’t link
  • -o: Output file
  • -I<directory>: Looks for header files in the specified directory
  • -L<dir>: specify the path to the library file (.a.dylib library file)
  • -l<library_name>: specify the name of the linked library file (.a/.dylib library files)
  • -F<directory>: Searches in the specified directoryframeworkThe header file
  • -framework<framework_name>In the specifiedframeworkThe name generates the corresponding LLVM file format to carry out link time optimization when used in conjunction-SAssembler language files are generated when used, otherwisebitcodeFormat the target file

Create and link static libraries

Objective:TestExampleEncapsulated as a static library, generatedtest.oFile and link to the generated static library Process:

1. Compile testexample. m to generate the target file

Clang-x objective-c \-target arm64-apple-macos12.0 \-fobjc-arc \-isysroot / Applications/Xcode. App/Contents/Developer/Platforms/MacOSX platform/Developer/SDKs/MacOSX12.0 SDK \ - c the TestExample. M - o TestExample.o

2. Rename testexample. o to libtestexample. dylib, delete. Dylib, and run the file command to view

3. Generate the target price test.o from test. m

Clang-x objective-c \-target arm64-apple-macos12.0 \-fobjc-arc \-isysroot / Applications/Xcode. App/Contents/Developer/Platforms/MacOSX platform/Developer/SDKs/MacOSX12.0 SDK \ -i/StaticLibrary \-c test.m -o test.o

4. Link library generates executable files

Clang-target arm64-apple-macos12.0 \-fobjc-arc \-isysroot / Applications/Xcode. App/Contents/Developer/Platforms/MacOSX platform/Developer/SDKs/MacOSX12.0 SDK \ - l. / StaticLibrary \-lTestExample \test.o -o test

5. Run the LLDB executable file. In the LLDB environment, run the file test and run commands

Merge static libraries

There are two options for static library merging, using AR or libtool

Now list two static library files

ar

Use ar-x libAFNetworking. A and AR-x libsdwebimage. a to extract all the files from the two static libraries

Use AR-VR Combinelib. a *.o __.SYMDEF to package all the target files into combinelib.a, then use file or AR-t to see if the merged file format is correct

libtool

Take a look at the documentation for libtool

Use libtool -static -o combinelib.a libAFNetworking. A libsdwebimage.a

Having also merged static libraries, libtool is obviously much easier

Framework

The Framework is also available for MacOS and iOS platforms. The Framework is actually a way of packaging library binaries, header files, and related resource files together for easy management and distribution. The Framework of the system does not need to be copied to the target program, and the Framework made by ourselves even if it is dynamic also needs to be copied to the target program, so this Framework is also called Embedded Framework.

Framework:

  • Static library:Header+.a+The signature+ Resource file
  • The dynamic library:Header+.dylib+The signature+ Resource file
  • If theEmbeddedIn all cases, copy to the target file

Making Framework

O file: clang-x objective-c \-target arm64-apple-macos12.0 \-fobjc-arc \-isysroot / Applications/Xcode. App/Contents/Developer/Platforms/MacOSX platform/Developer/SDKs/MacOSX12.0 SDK \ – c the TestExample. M – o Testexample. o Run the ar-rc TestExample testexample. o command

So far we have Header+.a

After creating the Framework folder and creating the Headers folder within it, see the following

Now also compile test.m as an object file and link to framwork

Clang-x objective-c \-target arm64-apple-macos12.0 \-isysroot / Applications/Xcode. App/Contents/Developer/Platforms/MacOSX platform/Developer/SDKs/MacOSX12.0 SDK \ - fobjc - arc \-I./Frameworks/TestExample.framework/Headers \-c test.m -o test.o

Clang-target arm64-apple-macos12.0 \-fobjc-arc \-isysroot / Applications/Xcode. App/Contents/Developer/Platforms/MacOSX platform/Developer/SDKs/MacOSX12.0 SDK \ - F/Frameworks \-framework TestExample \test.o -o test

The LLDB is displayed, and the link is successful

Dead Code Strip

If the main program does not use methods in the linked static library, do unused methods appear in the executable’s code snippet?

It can be used for different situationsobjdump --macho -dTo view the code snippet

You can see that static library code does not appear in the executable code section in the case of comments. This may seem to have no effect, but it strips the useless code, but if the linked static library calls the classified code, there is a problem, because the Dead Code strip takes effect while linking, but the categories are created dynamically while the application is running.

This situation is shown in the figure, the program will report an error after running

So since it is stripped during linking, can you configure parameters to tell the linker how to strip or not strip

Default parameters are not loaded

Use full load

Parameters passed to the linker for full load

This will work, but Duck does not need all links, and only needs to keep what it needs

There are three methods :-all_load, -objc, and -force_load

-Objc: Only the OC method is reserved

-force_load: loads all specified loads

Note: -all_load, -objc, -force_load are for static libraries only

-dead_strip removes data and methods that are not used by the entry or export symbol table.

The objdump –macho –syms command is used to view the symbol table

Objdump –macho –exports-trie view exported symbol table

Global_func exists even though it is not called

If -dead_strip is used, the symbol will not be in the symbol table