“This is the first day of my participation in the First Challenge 2022. For details: First Challenge 2022”

preface

Hi Coder, I’m CoderStar!

In the New Year, I wish you all success in your work, promotion and salary increase.

In our daily development, we will more or less use some built-in CLI tools of Xcode, but most of our friends may only use some specific commands. Today, we will talk about the common Command Lines Tool built in Xcode.

The introduction may not be complete, you can go to the path of the article to see more tools.

The Command Line Tool is essentially a Command Line toolkit with many useful tools, such as Apple LLVM Compiler, Make and so on. These toolkits are not just for Apple applications. Homebrew prompts you to install the Command Line Tool when installing python or JS libraries.

In this section, the Command Line Tool is abbreviated to CLI. XXX generally refers to the corresponding path address.

We can download it separately from the Developer website Command Line Tool, and of course it will be included with each version of Xcode installation package.

In fact, some of the following tools belong to the LLVM sequence, such as dwarfdump and AR, and the startup essence is llVM-dwarfdump and LLVm-AR, both of which are part of the LLVM tool chain.

The front tool

Before I introduce the rest of the kit, I’ll introduce two tools that I’ll call front-loading tools because they’ll make it easier to use the rest of the kit.

xcode-select

This tool can help you download and install the CLI more easily than manually. It can also solve another problem, that is, if we have more than one Xcode installed, when we use cli-related tools, the system will not know which version or which location of the CLI to use. Using this tool can help us set and switch the current default CLI.

This section describes the common commands of the tool.

  • xcode-select --install: To install the CLI/Library/Developer/CommandLineTools/
  • xcode-select -p: Displays the Xcode path of the specified tool package
  • xcode-select -s <path>: Switch to the Xcode directory where the default tool package is stored
  • xcode-select -r: Resets the Xcode path of the tool package

Env DEVELOPER_DIR=”/Applications/ xcode-beta. app” /usr/bin/xcodebuild

Xcode-select Select the path not the CLI path but the path of the xcode. Then use the CLI corresponding to the xcode. By default, the CLI contained in the xcode package is selected. But if we have adjusted the CLI for that Xcode through Xcode Preferences, the adjusted CLI will be used.

This tool is installed in /usr/bin/xcode-select and is not downloaded along with the CLI toolkit.

xcrun

Recall that we used to run xcodeBuild directly on the terminal when we used some CLI commands. This way, no specific CLI path is specified, and we get /usr/bin/xcodebuild when we execute which xcodebuild. How does this command get to the default CLI path that we set with xcode-select? That brings us to the tool we’re about to introduce, xcRun.

Xcodebuild = /usr/bin/xcodebuild = /usr/bin/xcodebuild Then let us see the/usr/bin/xcodebuild under instruction is how to cooperate with xcode – select find/Applications/xcode. App/Contents/Developer/usr/bin/xcodebuild?

Otool -tv /usr/bin/xcodebuild

(__TEXT,__text) section
_main:
0000000100003f63	pushq	%rbp
0000000100003f64	movq	%rsp, %rbp
0000000100003f67	pushq	%r14
0000000100003f69	pushq	%rbx
0000000100003f6a	movq	%rsi, %r14
0000000100003f6d	movl	%edi, %ebx
0000000100003f6f	callq	0x100003f88                     ## symbol stub for: __NSGetProgname
0000000100003f74	movq	(%rax), %rdi
0000000100003f77	leal	-0x1(%rbx), %esi
0000000100003f7a	leaq	0x8(%r14), %rdx
0000000100003f7e	movl	$0x1, %ecx
0000000100003f83	callq	0x100003f8e                     ## symbol stub for: _xcselect_invoke_xcrun
Copy the code

You can see that this command calls the _xcselect_invoke_xcrun function.

Then we check its name list with nm /usr/bin/xcodebuild

                 U __NSGetProgname
0000000100008018 d __dyld_private
0000000100000000 T __mh_execute_header
0000000100003f63 t _main
0000000100008010 s _shim_marker
                 U _xcselect_invoke_xcrun
                 U dyld_stub_binder
Copy the code

The U identifier in front of _xcselect_Invoke_xcrun shows that this function is an external symbol that is handled by another dynamic library.

Later, we can know more detailed process through SWIFt-SwifTC. Here we only say the conclusion:

Libxcself. dylib 👇🏻 _xcselect_invoke_xcrun 👇🏻 libxcrun.dylib byte excrun_mainCopy the code

We’ll actually end up calling xcrun_main, which will internally select the appropriate CLI path based on xcode-select and other Settings, See Developer Binaries on OS X, xcode-select and xcRun for the execution order.

Xcrun (Xcode Command Line Tool Runner) is Xcode’s basic command-line Tool. Use it to call other CLI tools, and you should know why you need it to call other CLI tools.

The /usr/bin/xcrun command is the same as the /usr/bin/xcrun command, which is the same as the /usr/bin command in the CLI toolkit. The following commands are equivalent:

  • xcodebuild
  • /usr/bin/xcodebuild
  • xcrun xcodebuild
  • Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild

Some commands in the toolkit are not in /usr/bin, so we need to add xcrun in front of the command, such as swift-demangle. If we use swift-demangle directly, the command cannot be found. Use xcRun swift-demangle.

Related commands:

  • Xcrun –find clang // find the specified tool path
  • xcrun –sdk iphoneos –find pngcrush
  • xcrun –sdk macosx –show-sdk-path

Through xcode – select installation in CLI path: / Library/Developer/CommandLineTools /. Xcode embedded in CLI path: / Applications/Xcode. The app/Contents/Developer/usr/bin

It is also important to note that xcRun does not only look for paths under the Xcode-select setting, but also looks for other xcode paths to execute commands, including

  • Developer/usr
  • Developer/Platforms
  • Developer/ToolChain

Examples are as follows:

Xcodebuild: / Applications/Xcode. App/Contents/Developer/usr/bin/xcodebuild swift – demangle: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-demangle

Xcode Command Lines Tool -libxcselect. dylib -xcrun Xcode Command Lines -xcrun

There is an open source implementation of xcode-Tools for both tools.

Symbol table correlation

A brief introduction to DWARF and dSYM.

The relationship between DWARF and dSYM is that DWARF is the file format, while dSYM usually refers to a single file. Debug information is stored in the Executable file unless specified otherwise in Xcode. Because of DWARF, we can see the function name and other information when debugging. Because of dSYM file, we can symbolize and solve Crash.

There was a previous article on symbolic parsing on iOS symbolic parsing.

dwarfdump

Purpose: Parse DWARF sections in object files, archives, and.dsym packages, and print their contents in human-readable form; Usage scenario: Crash symbolization; Path: / Applications/Xcode. App/Contents/Developer/Toolchains/XcodeDefault xctoolchain/usr/bin/dwarfdump;

#Use the sample
dwarfdump -h

#Check the UUID of the xx.app file
dwarfdump --uuid xx.app/xx

#Check the UUID of the xx.app.dSYM file
dwarfdump --uuid xx.app.dSYM

#Export the debug_info information to the debug_line. TXT file
dwarfdump --debug-info xx.app.dSYM > debug_info.txt

#Output the debug_line information to the debug_line. TXT file
dwarfdump --debug-line xx.app.dSYM > debug_line.txt

#Verify the validity of DWARF
dwarfdump --verify iOSTest.app.dSYM

#Finds information about the specified address
#Crash, Crash, Crash
dwarfdump --arch arm64 --lookup 0x100006694 iOSTest.app.dSYM

Copy the code

Llvm-dwarfdump can be seen in more commands.

dsymutil

Dsymutil can be used to extract dSYM files from binary and perform some operations on dSYM files. Usage scenario: When a dSYM file is lost, it can be used as a way to retrieve the dSYM file. Path: / Applications/Xcode. App/Contents/Developer/Toolchains/XcodeDefault xctoolchain/usr/bin/dsymutil;


#'.dysm 'files are extracted from binary packages containing' DSYM 'information
dsymutil XXX

#Updates the existing dSYM with the specified symbol map
#Process dSYM files with the bitcode option turned on
dsymutil -symbol-map /Users/XXXXX/Library/Developer/Xcode/Archives/2019-09-27/YYYY.xcarchive/BCSymbolMaps 0f1e9458-9741-36fb-b47c-694546728ea1.dSYM
Copy the code

symbolicatecrash

What it does: is a Perl script that integrates step-by-step parsing (you can copy the command and call it directly). Scenario: The Crash file is symbolized; Path: / Applications/Xcode. App/Contents/SharedFrameworks/DVTFoundation framework Versions/A/Resources/symbolicatecrash;

#You need to run this command first, otherwise the following symbolicatecrash command will appear
# Error: "DEVELOPER_DIR" is not defined at ./symbolicatecrash line 69.
export DEVELOPER_DIR="/Applications/XCode.App/Contents/Developer"

#Before running the command, you need to copy the crash log, dSYM, and Symbolicatecrash to the same directory
symbolicatecrash log.crash -d xxx.app.dSYM > symbol.log
Copy the code

atos

Function: symbolization of Crash; Path: / Applications/Xcode. App/Contents/Developer/usr/bin/atos;

#0x0000000100298000 is load Address; 0 x000000010029e694 symbol for the address
#The last I shows the inline function
atos -arch arm64  -o iOSTest.app.dSYM/Contents/Resources/DWARF/iOSTest -l 0x0000000100298000 0x000000010029e694 -i
Copy the code

Building related

xcodebuild

Functions: We can use it to clean up, analyze, build, test and archive Xcode projects; Scenario: CI construction, etc. Path: / Applications/Xcode. App/Contents/Developer/usr/bin/xcodebuild;

You can view the manual through man XcodeBuild.

The man command is used to view the user manual of a specified command.

#Clean up the
xcodebuild clean -workspace ${WORKSPACE_PATH} -scheme ${SCHEME_NAME} -configuration ${BUILD_TYPE}

#build
xcodebuild archive -workspace ${WORKSPACE_PATH} -scheme ${SCHEME_NAME} -archivePath ${ARCHIVE_PATH}

## file
xcodebuild -exportArchive -archivePath $ARCHIVE_PATH -exportPath ${IPA_PATH} -exportOptionsPlist ${EXPORTOPTIONSPLIST_PATH}
Copy the code
  • xctool:xctoolfacebookDerived for replacementxcodebuildA command line tool that makes it easier to test iOS and MAC apps, especially for continuous integration of iOS apps;
  • xcbuild:xcbuildIs a compatibleXcodeCompilation tool, which makes compilation faster, faster and friendlier compilation process log, can run on multiple platforms (mainly refers to OS X and Linux);

altool

Function: Use it to verify IPA and upload IPA to Store; Path: / Applications/Xcode. App/Contents/Developer/usr/bin/altool

#validation
#Check whether the version and build number are correctcase
xcrun altool --validate-app -f xxx.ipa -t ios --apiKey xxx --apiIssuer xxx --verbose

#upload
xcrun altool --upload-app -f xxx.ipa -t ios --apiKey xxx --apiIssuer xxx --verbose
Copy the code

Tool chain correlation

swiftc

Function: Swift language compiler front-end; Path: / Applications/Xcode. App/Contents/Developer/Toolchains/XcodeDefault xctoolchain/usr/bin/swiftc;

Swiftc is just a stand-in, originally swift-frontend.

clang

Function: OC language compiler front-end; Path: / Applications/Xcode. App/Contents/Developer/Toolchains/XcodeDefault xctoolchain/usr/bin/clang.

sourcekit-lsp

Language-server-protocol (LSP) An open source Language Server Protocol. Launched by Red Hat, Microsoft, and Codenvy, it makes it easy for different program editors and integrated development environments (ides) to embed various programming languages, allowing developers to write programs in a variety of languages in their favorite tools, Sourcekit-lsp is an LSP maintained by Apple for Swift. Its existence allows us to develop Swift using other ides, such as VSCode;

Path: / Applications/Xcode. App/Contents/Developer/Toolchains/XcodeDefault xctoolchain/usr/bin/sourcekit – LSP

The tool

actool

Function: Compress and process Assets files in the project to generate. Car files. Path: / Applications/Xcode. App/Contents/Developer/usr/bin/actool;

Actool is not a script, but a compiled binary, so the compile Asset Catalog process is a black box.

swift-demangle

In Swift, mangle is required for the class name due to namespace reasons, and demangle is also required to display the correct name. In fact, there are two ways to implement it and you can see it in the following link,

Mangle: copySwiftV1MangledName

Demangle: copySwiftV1DemangledName

Of course, Apple itself has specially prepared a CLI tool for us – swift-Demangle to facilitate us.

Command: xcrun swift - demangle _TtC7iOSTest27PickImageDemoViewController results: _TtC7iOSTest27PickImageDemoViewController - > iOSTest. PickImageDemoViewController command: Xcrun swift - demangle - compact _TtC7iOSTest27PickImageDemoViewController results: iOSTest. PickImageDemoViewControllerCopy the code

Swift_demangle_getDemangledName = swift_demangle_getDemangledName = swift_demangle.tbd = libswiftDemangle.tbd = libswiftDemangle.tbd = libswiftDemangle.tbd = libswiftDemangle.tbd = libswiftDemangle.tbd = libswiftDemangle.tbd

Mach-o operation related

In fact, most of the tools for mach-O operations are under LLVM, including otool, objdump, nm, dwarfdump, etc. The commands are essentially surrogates for llVM-xxx.

nm

Function: the nm command is a special file analysis tool that comes with Linux. It is generally used to check and analyze the symbol table in binary files, library files and executable files. It returns the information of each section in binary files and views the symbols of binary object files, mainly function names and global variables. Path: / Applications/Xcode. App/Contents/Developer/Toolchains/XcodeDefault xctoolchain/usr/bin/nm;

#Get the program symbol table in XXX
nm XXX

#If you look at all the symbols, it prints out where did the symbols come from
nm -nm XXX

#Find the undefined symbol, the external symbol
nm -u XXX
Copy the code

We looked at the XcodeBuild symbol earlier, and the output is as follows.

                 U __NSGetProgname
0000000100008018 d __dyld_private
0000000100000000 T __mh_execute_header
0000000100003f63 t _main
0000000100008010 s _shim_marker
                 U _xcselect_invoke_xcrun
                 U dyld_stub_binder
Copy the code

The uppercase letters in the middle are the types of corresponding symbols, all of which include:

  • A The value of this symbol will not change in future links;
  • B This symbol is placed in the BSS section, usually those global variables that are not initialized;
  • D The symbol is placed in ordinary data segments, usually global variables that have been initialized;
  • T this symbol is placed in the code segment, usually those global non-static functions;
  • U This symbol is not defined and needs to be linked in from other object files.
  • W unspecified weak link symbol; It is used if it is defined in other linked object files, otherwise a system-specific default value is used.

otool & objdump

Why put these two tools together? Because there is a relationship between these two tools. Otool is essentially a wrapper layer for objdump. The underlying layer is implemented using objdump.

For example, otool -l XXX is essentially equivalent to objdump –macho -dylibs-used XXX.

Both functions: a presentation tool for object files, used to discover which system libraries are used in the application, which methods are called, and which objects and properties from the library are used.

otool

Path: / Applications/Xcode. App/Contents/Developer/Toolchains/XcodeDefault xctoolchain/usr/bin/otool

MachOView is a GUI tool for this CLI tool.

#Check the use to which the dynamic Library, usually involves the/usr/lib / / System/Library/Frameworks / @ rpath the three position, without their own dynamic libraries, there would be no @ rpath behind
otool -L XXX

#Filter whether the XXX library is linked
otool -L XXX | grep "xxx"

#View sink code
otool -tV XXX

#Output object-c class structure and defined methods
otool -ov XXX

#View header content
otool -h XXX

#Check the load commands
otool -l XXX

#Check whether the application cracks the shell
#See the cryptid parameter of the output result, where 0: shell smashing, 1: not shell smashing.
otool -l XXX | grep -B 2 crypt

#View the start address of the code snippet
otool -l iOSTest.app.dSYM/Contents/Resources/DWARF/iOSTest | grep __TEXT -C 5

#View the relocation symbol table
otool -r XXX
Copy the code

objdump

Path: / Applications/Xcode. App/Contents/Developer/Toolchains/XcodeDefault xctoolchain/usr/bin/objdump

#To view the Mach - the header
objdump --macho -private-header XXX

#Look at the text segment
objdump --macho -d XXX

#View the symbol table
objdump --macho --syms XXX

#View the exported symbol table
objdump --macho --exports-trie XXX

#Look at the indirect symbol table
objdump --macho --indirect-symbols XXX

#View the relocation symbol table
objdump --macho --reloc XXX
Copy the code

In fact, one of objdump’s functions can replace the nm command, where objdump –macho –syms XXX can also output the symbol table.

strings

Function: View a string in a binary file. Path: / Applications/Xcode. App/Contents/Developer/Toolchains/XcodeDefault xctoolchain/usr/bin/strings;

#View the specified string
strings XXX | grep "xxx"
Copy the code

lipo

Lipo is a tool that works with Universal Binaries in MAC OS X.

#Check out the CPU architectures supported by static libraries
lipo -info frameworkName.framework/frameworkName
lipo -info frameworkName.a

### Merge static librariesLipo-create Static inventory store path 1 Static inventory store path 2... A frameworkName- armV7s. a frameworkName-i386. A -output frameworkName. A lipo -create frameworkNameOne.framework/frameworkNameOne frameworkNameTwo.framework/frameworkNameTwo -output frameworkName.framework
## static library splitLipo static library source file path -thin CPU architecture name -output Directory for storing files after splitting lipo libname.a -thin armv7 -output libname-armv7.a
### Erases the specified schema
lipo -remove XXX.a arm64 -output XXX.a
Copy the code

ar

Function: establish, modify static library; Path: / Applications/Xcode. App/Contents/Developer/Toolchains/XcodeDefault xctoolchain/usr/bin/libtool;

Ar-x XXX -d Deletes member files from the backup file. -m Changes the order of member files in the backup file. -p Displays the contents of member files in the backup file. -q appends the query to the end of the backup file. -r Inserts the file into the backup file. -t Displays the files contained in the backup file. -x Retrives member files from self-saved files.Copy the code

file

We can use the file command to distinguish dynamic libraries from static libraries.

It is easy to see a dynamically generated keyword, such as file Flutter

Flutter: Mach-O 64-bit dynamically linked shared library arm64
Copy the code

CSPickerView is a static library

CSPickerView: Mach-O universal binary with 5 architectures: [i386:current ar archive] [arm_v7] [arm_v7s] [x86_64] [arm64]
CSPickerView (for architecture i386):	current ar archive
CSPickerView (for architecture armv7):	current ar archive
CSPickerView (for architecture armv7s):	current ar archive
CSPickerView (for architecture x86_64):	current ar archive
CSPickerView (for architecture arm64):	current ar archive
Copy the code

class-dump

Download address

This is a command line utility that checks objective-C runtime information stored in a Mach-O file. It generates declarations for classes, categories, and protocols. This is the same information provided using ‘otool-ov’, but is rendered as a normal Objective-C declaration, so it is more compact and readable.

If you install MonkeyDev with class-dump built in, you don’t need to install it.

The last

Of course, there are many other CLI commands. Here are just some common ones. For others, you can directly follow the paths mentioned at the beginning to find them.

Try harder!

Let’s be CoderStar!

  • Common command tools in iOS development (xcode-select, lipo, xcrun, etc.
  • Xcode related terminal tools
  • Building from the Command Line with Xcode FAQ

It is very important to have a technical circle and a group of like-minded people, come to my technical official account, here only talk about technical dry stuff.

Wechat official account: CoderStar