objc4-709工程搭建

导语

objc 运行时的最新版本为 709 ,一回生,二回熟,简单的记录一下过程。

环境 & 工具

macOS Sierra 10.12.4
Xcode 8.3.2
objc-709
搭建 objc-706 时的头文件

流程

✘ 'sys/reason.h’ file not found (objc-os.h)

 

  因为打算把缺少的头文件统一放到工程下的 include 目录下,因此在 Building Setting > Header Search Paths 添加 $(SRCROOT)/include 字段

1
2
cd /path/to/objc4-709
➜ objc4-709 mkdir -p include/sys

递归创建目录,将 reason.h 拷贝到 sys 目录中

✘ mach-o/dyld_priv.h file not found (objc-os.h)

同理,创建 mach-o 目录 & 拷贝 dyld_priv.hmach-o

✘ os/lock_private.h file not found (objc-os.h)

创建目录 & 拷贝 lock_private.h

✘ 'System/pthread_machdep.h’ file not found (objc-os.h)

创建目录 & 拷贝 pthread_machdep.h

✘ System/machine/cpu_capabilities.h file not found (pthread_machdep.h)

创建目录 & 拷贝 cpu_capabilities.h

✘ CrashReporterClient.h file not found (objc-os.h)

创建目录 & 拷贝 cpu_capabilities.h

✘ CrashReporterClient.h file not found (CrashReporterClient.h)

根据 objc-706 的经验

Build Settings->Preprocessor Macros(Debug & Release) 加入:

LIBC_NO_LIBCRASHREPORTERCLIENT

编译报了很多错,先解决缺少头文件的问题

✘ phread/workqueue_private.h file not found (objc-os.h)

创建目录 & 拷贝 workqueue_private.h

✘ pthread/qos_private.h file not found (objc-os.h)

拷贝 qos_private.hpthread 目录

✘ sys/qos_private.h file not found (objc-os.h)

拷贝 qos_private.hsys 目录

✘ objc-shared-cache.h file not found (objc-os.h)

拷贝 objc-shared-cache.hinclude 目录,不报缺少头文件的错误了,继续解决变量未定义的问题,用 grep 的方式去找出来

1
➜  grep -rne "#define.*_PTHREAD_TSD_SLOT_MACH_THREAD_SELF" .

✔︎ /libpthread-218.20.1/private/tsd_private.h

workqueue_private.h 也是来自于 /libpthread-218.20.1/private ,已拷贝到 pthread 目录,将 tsd_private.h 也拷贝至pthread目录下

还是报错,检查 objc-os.h 发现并未引入 tsd_private.h 头文件

在第 34 行上下加一句

1
#include <pthread/tsd_private.h>

✘ 'os/tsd.h’ file not found (tsd_private.h)

拷贝 tsd.hos 目录

✘ 'pthread/spinlock_private.h’ file not found (tsd_private.h)

拷贝 spinlock_private.hpthread 目录

因为我拷贝的是原来自己已经处理过的文件,所以没有出现重复定义的错误

✘ Unknown type name 'pthread_priority_t’ (objc-os.h)

引入 qos_private.h 头文件,如下所示

1
2
3
4
5
6
7
8
9
10
11
#include <pthread/qos_private.h>

#if SUPPORT_QOS_HACK

static inline pthread_priority_t pthread_self_priority_direct()
{
pthread_priority_t pri = (pthread_priority_t)
_pthread_getspecific_direct(_PTHREAD_TSD_SLOT_PTHREAD_QOS_CLASS);
return pri & ~_PTHREAD_PRIORITY_FLAGS_MASK;
}
#endif

✘ Unknown type name 'os_unfair_lock (objc-os.h)'

同样的问题,已经在 objc-706 中出现过了

解决方法是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include "objc-lockdebug.h"

// 引入这个文件
#include <os/lock.h>

template <bool Debug>
class mutex_tt : nocopy_t {
os_unfair_lock mLock;
public:
mutex_tt() : mLock(OS_UNFAIR_LOCK_INIT) { }

// void lock() {
// lockdebug_mutex_lock(this);
//
// os_unfair_lock_lock(&mLock);
// os_unfair_lock_lock_with_options_inline
// (&mLock, OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION);
// }

// void unlock() {
// lockdebug_mutex_unlock(this);
//
// os_unfair_lock_unlock_inline(&mLock);
// }

void lock() {
lockdebug_mutex_lock(this);

os_unfair_lock_lock(&mLock);
}

void unlock()
{
lockdebug_mutex_unlock(this);

os_unfair_lock_unlock(&mLock);
}

void assertLocked() {
lockdebug_mutex_assert_locked(this);
}

void assertUnlocked() {
lockdebug_mutex_assert_unlocked(this);
}


// Address-ordered lock discipline for a pair of locks.

static void lockTwo(mutex_tt *lock1, mutex_tt *lock2) {
if (lock1 > lock2) {
lock1->lock();
lock2->lock();
} else {
lock2->lock();
if (lock2 != lock1) lock1->lock();
}
}

static void unlockTwo(mutex_tt *lock1, mutex_tt *lock2) {
lock1->unlock();
if (lock2 != lock1) lock2->unlock();
}
};

✘ '_simple.h’ file not found (objc-errors.mm)

拷贝 _simple.hinclude 目录

✘ 'Block_private.h’ file not found (objc-block-trampolines.mm)

拷贝 Block_private.hinclude 目录

libobjc.order 链接失败

解决办法是将 Building Settings 中的 Order File 的字段 改为 $(PROJECT_DIR)/libobjc.order

因为工程中并没有 CrashReporterClient 的库
Other Linker flags 中的 -lCrashReporterClient 参数去掉

编译通过

创建一个 debug-objctarget ,导入修改的 libobjc.A.dylib,就又可以愉快的调试了。

objc-709

参考

  1. objc-706工程搭建