objc4-750源碼編譯

OC的一個主要特性Runtime運行時特性,在平常開發中咱們使用到的都是不可見的,還好官方提供了Runtimeobjc4)源碼供開發者研究,我是小白,下面就開始邁出源碼探索的第一步,源碼編譯。ios

源碼地址git

1、下載objc4-750,編譯解決報錯問題

一、進入源碼區,搜索objc4並下載macos

objc4.png

同時下載objc4相關依賴dyld、launchd、Libc、libauto、libclosure、libdispatch、libplatform、libpthread、xnu。放在方便操做的文件夾,方便搜索查找。api

dependent.png

二、下載後解壓,並打開工程,以下圖:xcode

project.png

三、運行工程編譯報錯以下:bash

error.png

報錯信息: error: The i386 architecture is deprecated. You should update your ARCHS build setting to remove the i386 architecture. (in target 'objc') error: The i386 architecture is deprecated. You should update your ARCHS build setting to remove the i386 architecture. (in target 'objc-trampolines') 解決方法:target-Build Settings -Architecture設置爲Standard arcgutecturesapp

architectures.png

四、解決問題後編譯,繼續報錯:ide

reasonerror.png

一看發現reason.h頭文件沒找到,缺失依賴文件,在步驟1下載的文件中搜索sys/reason.h文件,加入便可。咱們須要建立一個include文件來存放這些缺失的依賴文件。 設置頭文件路徑:ui

header.png

搜索缺失文件:spa

find.png

添加頭文件後繼續編譯,繼續添加缺失文件……

五、添加的過程當中發現pthread_machdep.h在依賴中沒有,CrashReporterClient.h也沒有找到,也不知道在哪一個庫,一臉懵逼,直接谷歌找到鏈接:

opensource.apple.com/source/Libc…

opensource.apple.com/source/Libc…

打開鏈接複製源碼到新建文件,解決,啼笑皆非。最新的源碼竟然缺乏文件,還要在歷史版本庫找。

編譯後pthread_machdep.h文件報錯:

Typedef redefinition with different types ('int' vs 'volatile OSSpinLock' (aka 'volatile int’))

重複定義,註釋便可。

編譯繼續報錯:

Static declaration of '_pthread_getspecific_direct' follows non-static declaration

註釋掉pthread_machdep.h中全部的錯誤信息。

六、編譯報錯: Expected ','

extern bool dyld_program_minos_at_least(dyld_build_version_t version) __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0), bridgeos(3.0));
複製代碼

直接註釋掉就行。繼續編譯,問題繼續出現報錯:

Use of undeclared identifier 'DYLD_MACOSX_VERSION_10_14'

dyld_priv.h頂部添加:

#define DYLD_MACOSX_VERSION_10_11 0x000A0B00
#define DYLD_MACOSX_VERSION_10_12 0x000A0C00
#define DYLD_MACOSX_VERSION_10_13 0x000A0D00
#define DYLD_MACOSX_VERSION_10_14 0x000A0E00
複製代碼

問題解決。

七、接着步驟6編譯出現: 'isa.h' file not found isa.h文件在工程runtime文件中複製粘貼到include文件下便可。

isa.png

八、繼續編譯繼續報錯:'_simple.h' file not found 搜索文件添加。

九、編譯報錯:Use of undeclared identifier 'CRGetCrashLogMessage'

解決方法:target -> Build Settings -> Preprocessor Macros 添加LIBC_NO_LIBCRASHREPORTERCLIENT

preprocessor.png

十、編譯報錯:

clang:-1: linker command failed with exit code 1 (use -v to see invocation) no such file or directory: 'lCrashReporterClient'

解決方法:在 Build Settings -> Linking -> Other Linker Flags裏刪掉"-lCrashReporterClient"DebugRelease都刪了)

ICrashReporter.png

十一、編譯報錯:

ld: can't open order file: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/AppleInternal/OrderFiles/libobjc.order clang: error: linker command failed with exit code 1 (use -v to see invocation)

解決方法: Build Settings->Linking->Order File 改爲$(SRCROOT)/libobjc.order

libobjc.png

十二、編譯報錯:

Showing All Messages /xcodebuild:-1: SDK "macosx.internal" cannot be located. /xcrun:-1: unable to find utility "clang++", not a developer tool or in PATH

解決方法:將Target->Build Phases->Run-Script(markgc)裏的內容macosx.internal改成macosx

macosx.png

1三、編譯報錯:

error: no such public header file: '/tmp/objc.dst/usr/include/objc/ObjectiveC.apinotes'

解決方法:Target->Build Settings->Other Text-Based InstallAPI Flags裏的內容設爲空;

Text-Based InstallAPI Verification Model裏的值改成Errors Only

ObjectiveC.apinotes.png

1四、編譯報錯,額…… 竟然編譯經過了。

2、添加Debug Target

一、添加一個target取名爲 objc-test

objctest.png

二、引入頭文件#import <objc/message.h>建立一個新類HBObject,繼承自NSObject類。添加屬性,方法,並給屬性賦值,調用方法。運行以下:

objc_test.png

代碼:

#import <Foundation/Foundation.h>
#import <objc/message.h>

void hb_test_method(Class cla, SEL _cmd){
    NSLog(@"我這個添加的方法被調用了");
}
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Class HBObject = objc_allocateClassPair(objc_getClass("NSObject"), "HBObject", 0);
        class_addIvar(HBObject, "name", sizeof(id), log2(sizeof(id)), @encode(id));
        class_addMethod(HBObject, sel_registerName("hb_test_method"), (IMP)hb_test_method, "v@:");
        objc_registerClassPair(HBObject);
        id newObject = [[HBObject alloc]init];
        [newObject setValue:@"yahibo" forKey:@"name"];
        NSLog(@"name:%@",[newObject valueForKey:@"name"]);
        objc_msgSend(newObject,sel_registerName("hb_test_method"));
    }
    return 0;
}
複製代碼

至此完成了源碼調試,編譯經過。

調試成功的源碼地址

相關文章
相關標籤/搜索