国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

iOS--編譯鏈接的過_1

這篇具有很好參考價值的文章主要介紹了iOS--編譯鏈接的過_1。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

iOS 開發(fā)中使用的是編譯語言,所謂編譯語言是在執(zhí)行的時候,必須先通過編譯器生成機(jī)器碼,機(jī)器碼可以直接在CPU上執(zhí)行,所以執(zhí)行效率較高,是使用 Clang / LLVM 來編譯的。LLVM是一個模塊化和可重用的編譯器和工具鏈技術(shù)的集合,Clang 是 LLVM 的子項目,是 C,C++ 和 Objective-C 編譯器,目的是提供驚人的快速編譯。下面我們來看看編譯過程,總的來說編譯過程分為幾個階段:預(yù)處理 -> 詞法分析 -> 語法分析 -> 靜態(tài)分析 -> 生成中間代碼和優(yōu)化 -> 匯編 -> 鏈接
iOS--編譯鏈接的過_1,ios,cocoa,macos
iOS--編譯鏈接的過_1,ios,cocoa,macos

預(yù)處理

這一步編譯器所做的處理是:
clang -E main.m -F

  • 宏替換(在源碼中使用的宏定義會被替換為對應(yīng)#define的內(nèi)容)1. #define 刪除,并展開對應(yīng)的宏定義。
    建議大家不要在需要預(yù)處理的代碼中加入內(nèi)聯(lián)代碼邏輯。
  • 頭文件引入(#include,#import)
    使用對應(yīng)文件.h的內(nèi)容替換這一行的內(nèi)容,所以盡量減少頭文件中的#import,使用@class替代,把#import放到.m文件中。
  • 處理所有的條件預(yù)編譯指令。如#if、#ifdef、#else#endif。
  • 刪除所有的注釋 ///**/等。
  • 添加行號文件名標(biāo)識。如 # 1 “main.m"(編譯調(diào)試會用到)。

編譯

clang -S main.i -o main.s
這個過程就是把上面的main.i文件進(jìn)行:詞法分析、語法分析、靜態(tài)分析,優(yōu)化生成相應(yīng)的匯編代碼,最終生成main.s文件。
這里我們需要了解一下這幾個名詞:

  • 詞法分析:把源代碼的字符序列分割成一個個token(關(guān)鍵字、表示符、字面量、特殊符號),比如把標(biāo)識符放到符號表里面。
  • 語法分析: 生成抽象語法樹AST,此時運(yùn)算符號的優(yōu)先級確定了;有些符號具有多重含義也確定了,比如:*是乘號還是對指針取內(nèi)容;表達(dá)式不合法、括號不匹配等等,都會報錯.
  • 靜態(tài)分析:分析類型聲明和匹配問題。比如整型和字符串相加,肯定會報錯。
  • 中間語法生成: CodeGen根據(jù)AST(抽象語法樹)自上向下逐步翻譯成LLVM IR,并且對在編譯期就可以確定的表達(dá)式進(jìn)行優(yōu)化,比如代碼里面的a=1+3,可以優(yōu)化成a=4。(假如開啟了bitcode)
  • 目標(biāo)代碼生成與優(yōu)化: 根據(jù)中間語法生成依賴具體機(jī)器的匯編語言;并優(yōu)化匯編語言。`這個過程中,假如有變量且定義在同一個編譯單元里,那么就給這個變量分配空間,確定變量的地址。假如變量或者函數(shù)不定義在這個編譯單元里面,那就等到鏈接的時候才能確定地址。``

詞法解析

這一步把源文件中的代碼轉(zhuǎn)化為特殊的標(biāo)記流,源碼被分割成一個一個的字符和單詞,在行尾Loc中都標(biāo)記出了源碼所在的對應(yīng)源文件和具體行數(shù),方便在報錯時定位問題。Clang定義的所有Token類型。 可以分為下面這4類:
clang -Xclang -dump-tokens main.m
關(guān)鍵字:語法中的關(guān)鍵字,比如 if、else、while、for 等;
標(biāo)識符:變量名;
字面量:值、數(shù)字、字符串;
特殊符號:加減乘除等符號。
iOS--編譯鏈接的過_1,ios,cocoa,macos

語法解析

clang -Xclang -ast-dump -fsyntax-only main.m
iOS--編譯鏈接的過_1,ios,cocoa,macos
這一步是把詞法分析生成的標(biāo)記流,解析成一個抽象語法樹(abstract syntax tree -- AST),同樣地,在這里面每一節(jié)點(diǎn)也都標(biāo)記了其在源碼中的位置。[[AST抽象語法樹]]

靜態(tài)分析

把源碼轉(zhuǎn)化為抽象語法樹之后,編譯器就可以對這個樹進(jìn)行分析處理。靜態(tài)分析會對代碼進(jìn)行錯誤檢查,如出現(xiàn)方法被調(diào)用但是未定義、定義但是未使用的變量等,以此提高代碼質(zhì)量。當(dāng)然,還可以通過使用 Xcode 自帶的靜態(tài)分析工具(Product -> Analyze)
類型檢查
在此階段clang會做檢查,最常見的是檢查程序是否發(fā)送正確的消息給正確的對象,是否在正確的值上調(diào)用了正常函數(shù)。如果你給一個單純的 NSObject* 對象發(fā)送了一個 hello 消息,那么 clang 就會報錯,同樣,給屬性設(shè)置一個與其自身類型不相符的對象,編譯器會給出一個可能使用不正確的警告。

一般會把類型分為兩類:動態(tài)的和靜態(tài)的。動態(tài)的在運(yùn)行時做檢查,靜態(tài)的在編譯時做檢查。以往,編寫代碼時可以向任意對象發(fā)送任何消息,在運(yùn)行時,才會檢查對象是否能夠響應(yīng)這些消息。由于只是在運(yùn)行時做此類檢查,所以叫做動態(tài)類型。
至于靜態(tài)類型,是在編譯時做檢查。當(dāng)在代碼中使用 ARC 時,編譯器在編譯期間,會做許多的類型檢查:因為編譯器需要知道哪個對象該如何使用。

其他分析
ObjCUnusedIVarsChecker.cpp是用來檢查是否有定義了,但是從未使用過的變量。(
This file defines a CheckObjCUnusedIvars, a checker that analyzes an Objective-C class’s interface/implementation to determine if it has any ivars that are never accessed.)
ObjCSelfInitChecker.cpp是檢查在 你的初始化方法中中調(diào)用 self 之前,是否已經(jīng)調(diào)用 [self initWith…] 或 [super init] 了(
This checks initialization methods to verify that they assign ‘self’ to the result of an initialization call (e.g. [super init], or [self initWith…]) before using ‘self’ or any instance variable.)。
iOS--編譯鏈接的過_1,ios,cocoa,macos

中間代碼生成和優(yōu)化

LLVM IR有3種表示形式,但本質(zhì)上是等價的。

  • text:便于閱讀的文本格式,類似于匯編語言,拓展名 .ll
  • memory:內(nèi)存格式
  • bitcode:二進(jìn)制格式,拓展名 .bc
    我們對下面代碼使用clang -O3 -S -emit-llvm main.m -o main.ll,生成main.ll
#import <Foundation/Foundation.h>

#define a1 1

  

**int** sum(**int** a, **int** b) {

    **int** c = a + b;

    **return** c;

}

  

**int** main(**int** argc, **const** **char** * argv[]) {

    **@autoreleasepool** {

        // insert code here...

        NSLog(@"Hello, World!");

        **int** a = 5;

        NSLog(@"%d", sum(a1, a));

    }

    **return** 0;

}
; ModuleID = 'main.m'
source_filename = "main.m"
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx13.0.0"

%struct.__NSConstantString_tag = type { i32*, i32, i8*, i64 }

@__CFConstantStringClassReference = external global [0 x i32]
@.str = private unnamed_addr constant [14 x i8] c"Hello, World!\00", section "__TEXT,__cstring,cstring_literals", align 1
@_unnamed_cfstring_ = private global %struct.__NSConstantString_tag { i32* getelementptr inbounds ([0 x i32], [0 x i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 1992, i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i32 0, i32 0), i64 13 }, section "__DATA,__cfstring", align 8 #0
@.str.1 = private unnamed_addr constant [3 x i8] c"%d\00", section "__TEXT,__cstring,cstring_literals", align 1
@_unnamed_cfstring_.2 = private global %struct.__NSConstantString_tag { i32* getelementptr inbounds ([0 x i32], [0 x i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 1992, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i32 0, i32 0), i64 2 }, section "__DATA,__cfstring", align 8 #0

; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone ssp uwtable willreturn
define i32 @sum(i32 %0, i32 %1) local_unnamed_addr #1 {
  %3 = add nsw i32 %1, %0
  ret i32 %3
}

; Function Attrs: ssp uwtable
define i32 @main(i32 %0, i8** nocapture readnone %1) local_unnamed_addr #2 {
  %3 = tail call i8* @llvm.objc.autoreleasePoolPush() #3
  notail call void (i8*, ...) @NSLog(i8* bitcast (%struct.__NSConstantString_tag* @_unnamed_cfstring_ to i8*))
  notail call void (i8*, ...) @NSLog(i8* bitcast (%struct.__NSConstantString_tag* @_unnamed_cfstring_.2 to i8*), i32 6)
  tail call void @llvm.objc.autoreleasePoolPop(i8* %3)
  ret i32 0
}

; Function Attrs: nounwind
declare i8* @llvm.objc.autoreleasePoolPush() #3

declare void @NSLog(i8*, ...) local_unnamed_addr #4

; Function Attrs: nounwind
declare void @llvm.objc.autoreleasePoolPop(i8*) #3

attributes #0 = { "objc_arc_inert" }
attributes #1 = { mustprogress nofree norecurse nosync nounwind readnone ssp uwtable willreturn "darwin-stkchk-strong-link" "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "probe-stack"="___chkstk_darwin" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "tune-cpu"="generic" }
attributes #2 = { ssp uwtable "darwin-stkchk-strong-link" "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "probe-stack"="___chkstk_darwin" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "tune-cpu"="generic" }
attributes #3 = { nounwind }
attributes #4 = { "darwin-stkchk-strong-link" "frame-pointer"="all" "no-trapping-math"="true" "probe-stack"="___chkstk_darwin" "stack-protector-buffer-size"="8" "target-cpu"="penryn" "target-features"="+cx16,+cx8,+fxsr,+mmx,+sahf,+sse,+sse2,+sse3,+sse4.1,+ssse3,+x87" "tune-cpu"="generic" }

!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10}
!llvm.ident = !{!11}

!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 13, i32 1]}
!1 = !{i32 1, !"Objective-C Version", i32 2}
!2 = !{i32 1, !"Objective-C Image Info Version", i32 0}
!3 = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"}
!4 = !{i32 1, !"Objective-C Garbage Collection", i8 0}
!5 = !{i32 1, !"Objective-C Class Properties", i32 64}
!6 = !{i32 1, !"Objective-C Enforce ClassRO Pointer Signing", i8 0}
!7 = !{i32 1, !"wchar_size", i32 4}
!8 = !{i32 7, !"PIC Level", i32 2}
!9 = !{i32 7, !"uwtable", i32 1}
!10 = !{i32 7, !"frame-pointer", i32 2}
!11 = !{!"Apple clang version 14.0.0 (clang-1400.0.29.202)"}

接下來 LLVM 會對代碼進(jìn)行編譯優(yōu)化,例如針對全局變量優(yōu)化、循環(huán)優(yōu)化、尾遞歸優(yōu)化等,最后輸出匯編代碼。使用xcrun clang -S -o - main.m | open -f生成匯編代碼:

	.section	__TEXT,__text,regular,pure_instructions
	.build_version macos, 13, 0	sdk_version 13, 1
	.globl	_sum                            ## -- Begin function sum
	.p2align	4, 0x90
_sum:                                   ## @sum
	.cfi_startproc
## %bb.0:
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset %rbp, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register %rbp
	movl	%edi, -4(%rbp)
	movl	%esi, -8(%rbp)
	movl	-4(%rbp), %eax
	addl	-8(%rbp), %eax
	movl	%eax, -12(%rbp)
	movl	-12(%rbp), %eax
	popq	%rbp
	retq
	.cfi_endproc
                                        ## -- End function
	.globl	_main                           ## -- Begin function main
	.p2align	4, 0x90
_main:                                  ## @main
	.cfi_startproc
## %bb.0:
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset %rbp, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register %rbp
	subq	$32, %rsp
	movl	$0, -4(%rbp)
	movl	%edi, -8(%rbp)
	movq	%rsi, -16(%rbp)
	callq	_objc_autoreleasePoolPush
	movq	%rax, -32(%rbp)                 ## 8-byte Spill
	leaq	L__unnamed_cfstring_(%rip), %rdi
	movb	$0, %al
	callq	_NSLog
	movl	$5, -20(%rbp)
	movl	-20(%rbp), %esi
	movl	$1, %edi
	callq	_sum
	movl	%eax, %esi
	leaq	L__unnamed_cfstring_.2(%rip), %rdi
	movb	$0, %al
	callq	_NSLog
	movq	-32(%rbp), %rdi                 ## 8-byte Reload
	callq	_objc_autoreleasePoolPop
	xorl	%eax, %eax
	addq	$32, %rsp
	popq	%rbp
	retq
	.cfi_endproc
                                        ## -- End function
	.section	__TEXT,__cstring,cstring_literals
L_.str:                                 ## @.str
	.asciz	"Hello, World!"

	.section	__DATA,__cfstring
	.p2align	3                               ## @_unnamed_cfstring_
L__unnamed_cfstring_:
	.quad	___CFConstantStringClassReference
	.long	1992                            ## 0x7c8
	.space	4
	.quad	L_.str
	.quad	13                              ## 0xd

	.section	__TEXT,__cstring,cstring_literals
L_.str.1:                               ## @.str.1
	.asciz	"%d"

	.section	__DATA,__cfstring
	.p2align	3                               ## @_unnamed_cfstring_.2
L__unnamed_cfstring_.2:
	.quad	___CFConstantStringClassReference
	.long	1992                            ## 0x7c8
	.space	4
	.quad	L_.str.1
	.quad	2                               ## 0x2

	.section	__DATA,__objc_imageinfo,regular,no_dead_strip
L_OBJC_IMAGE_INFO:
	.long	0
	.long	64

.subsections_via_symbols
	.section	__TEXT,__text,regular,pure_instructions
	.build_version macos, 13, 0	sdk_version 13, 1
	.globl	_sum                            ## -- Begin function sum
	.p2align	4, 0x90

看這幾行,他們是匯編指令不是匯編代碼
.section指令指定了接下來會執(zhí)行哪一個段
.globl指令說明_main是一個外部符號。這就是我們的main()函數(shù)。這個函數(shù)對外部是可見的,因為系統(tǒng)要調(diào)用它來運(yùn)行可執(zhí)行文件。
.p2align指令指出了后面代碼的對齊方式。在我們的代碼中,后面的代碼會按照 16(2^4) 字節(jié)對齊,如果需要的話,用 0x90 補(bǔ)齊。

匯編

在這一階段,匯編器將上一步生成的可讀的匯編代碼轉(zhuǎn)化為機(jī)器代碼。最終產(chǎn)物就是 以 .o 結(jié)尾的目標(biāo)文件。使用Xcode構(gòu)建的程序會在DerivedData目錄中找到這個文件。

鏈接

這一階段是將上個階段生成的目標(biāo)文件和引用的靜態(tài)庫鏈接起來,最終生成可執(zhí)行文件,鏈接器解決了目標(biāo)文件和庫之間的鏈接。
可執(zhí)行文件類型為 Mach-O 類型,在 MAC OS 和 iOS 平臺的可執(zhí)行文件都是這種類型
至此,編譯過程結(jié)束。
iOS--編譯鏈接的過_1,ios,cocoa,macos文章來源地址http://www.zghlxwxcb.cn/news/detail-602085.html

到了這里,關(guān)于iOS--編譯鏈接的過_1的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • macOS Sonoma編譯OpenCV源碼輸出IOS平臺庫

    macOS Sonoma編譯OpenCV源碼輸出IOS平臺庫

    1.macOS下載并編譯OpenCV源碼:? 克隆源碼: 主倉:?git clone https://github.com/opencv/opencv.git 擴(kuò)展倉:? git clone https://github.com/opencv/opencv_contrib.git ? ?編譯xcode源碼需要CMake與XCode命令行工具 確認(rèn)已安裝CMake ?確認(rèn)已安裝XCode ?安裝xcode command line tools 確認(rèn)系統(tǒng)已安裝python環(huán)境

    2024年02月10日
    瀏覽(19)
  • 如何建設(shè)一個用于編譯 iOS App 的 macOS 云服務(wù)器集群?

    作者:京東零售 葉萌 現(xiàn)代軟件開發(fā)一般會借助 CI/CD 來提升代碼質(zhì)量、加快發(fā)版速度、自動化重復(fù)的事情,iOS App 只能在 mac 機(jī)器上編譯,CI/CD 工具因此需要有一個 macOS 云服務(wù)器集群來執(zhí)行 iOS App 的編譯。 今天就來談?wù)勅绾谓ㄔO(shè) macOS 云服務(wù)器集群 最簡單的方式就是購買一批

    2023年04月25日
    瀏覽(21)
  • 【iOS】動態(tài)鏈接器dyld

    【iOS】動態(tài)鏈接器dyld

    參考:認(rèn)識 dyld :動態(tài)鏈接器 dyld(Dynamic Linker)是 macOS 和 iOS 系統(tǒng)中的動態(tài)鏈接器,它是負(fù)責(zé)在運(yùn)行時加載和鏈接動態(tài)共享庫(dylib)或可執(zhí)行文件的組件。在 macOS 系統(tǒng)中,dyld 位于 D/usr/lib/dyld 。 dyld源碼地址 dyld 2(Dynamic Linker 2)是 macOS 和 iOS 系統(tǒng)中的第二代動態(tài)鏈接器。

    2024年02月16日
    瀏覽(15)
  • Charles證書過期解決方法macos/ios

    Charles證書過期解決方法macos/ios

    今天心血來潮打開Charles想試試看抓包手機(jī)APP(ios),結(jié)果發(fā)現(xiàn)各種x和提示ssl錯誤。開始以為是和魔法的代理沖突或者ip變了,捯飭很久后發(fā)現(xiàn)web的也報錯。 然后搜了一會原因發(fā)現(xiàn)時證書過期了 1、搜索“鑰匙串訪問”,直接搜索“charles”,找到打叉的名稱,直接刪掉 2、打開

    2024年02月03日
    瀏覽(23)
  • Charles 鏈接安卓和ios手機(jī)操作

    Charles 鏈接安卓和ios手機(jī)操作

    重點(diǎn):手機(jī)和電腦在同一個Wi-Fi網(wǎng)絡(luò)?。?! 一、、安卓手機(jī) 設(shè)置 - 無線和網(wǎng)絡(luò) - WLAN 長按當(dāng)前 WiFi - 修改網(wǎng)絡(luò) 勾選顯示高級選項 代理 - 手動 服務(wù)器主機(jī)名 - 填寫 Mac 的IP 地址,服務(wù)器端口 - 默認(rèn):8888 Mac電腦 IP 獲取方法:Charles - Help - Local IP Address? ?2、下載證書 打開手機(jī)瀏

    2024年02月08日
    瀏覽(32)
  • iOS textView支持超鏈接跳轉(zhuǎn)

    iOS textView支持超鏈接跳轉(zhuǎn)

    將某些文字變成高量可以點(diǎn)擊的超鏈接核心功能代碼 同時,要實(shí)現(xiàn)點(diǎn)擊超鏈接的UITextView代理方法 完整代碼 實(shí)現(xiàn)代理方法 效果圖

    2024年02月12日
    瀏覽(20)
  • iOS通用鏈接(UniversalLink)配置詳細(xì)流程

    iOS通用鏈接(UniversalLink)配置詳細(xì)流程

    登錄蘋果賬號后,點(diǎn)擊創(chuàng)建的APP 的Bundle ID,跳轉(zhuǎn)到APP 信息頁面。 記錄下 Team ID ?和 Bundle ID ?備用。 勾選上 功能列表上的 ”Associated Domains“選項。 配置蘋果后臺 創(chuàng)建一個text空文本文件,去掉文件后綴,命名為 apple-app-site-association (不能修改,且不能添加后綴)。 文件內(nèi)添加

    2024年02月13日
    瀏覽(20)
  • XCODE IOS 靜態(tài)鏈接庫替換升級

    XCODE?版本15.2.? 一個很久需求沒更新的IOS 應(yīng)用,近來有新需求要開發(fā)。 拉下代碼運(yùn)行,出現(xiàn)了個BAD_ACCESS錯誤。出錯的位置位于一個調(diào)用的第三方的.a靜態(tài)庫內(nèi)部。因為調(diào)用代碼并沒有修改,很容易想到可能XCODE相關(guān)升級,導(dǎo)致的問題。 由于是第三方的一個.a靜態(tài)庫,兼容問題

    2024年02月02日
    瀏覽(17)
  • iOS-配置Universal Links通用鏈接

    iOS-配置Universal Links通用鏈接

    1、開啟Associated Domains服務(wù) 登錄蘋果開發(fā)者網(wǎng)站,在 Certificates, Identifiers Profiles 頁面左側(cè)選擇 Identifiers ,右側(cè)選擇對應(yīng)的 App ID ,點(diǎn)擊進(jìn)入配置詳情頁,開啟 Associated Domains 服務(wù); 2、更新Profile文件(配置文件) 在 Certificates, Identifiers Profiles 頁面左側(cè)選擇 Profiles ,右側(cè)選擇對

    2024年02月11日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包