在 Windows 10 中搭建 Theos 环境


#1

昨天偶然看到上面单独写了 Windows 10 的支持

正好 Windows 版的已经100万年没更新了, 所以决定折腾一下

1. 安装 Linux 子系统

2. 安装最新的 theos

git clone --depth 1 --recursive https://github.com/theos/theos.git
export THEOS=/mnt/d/Dev/iOS/theos

我是装在 D 盘上

3. 下载工具链

https://developer.angelxwind.net/Linux/ios-toolchain_clang%2Bllvm%2Bld64_latest_linux_x86_64.zip

解压到 /mnt/d/Dev/iOS/theos/toolchain 里面

注意不要在 Windows 下直接解压, 要在 bash 里解压

##注意不要在 Windows 下直接解压, 要在 bash 里解压
#注意不要在 Windows 下直接解压, 要在 bash 里解压

unzip ios-toolchain_clang+llvm+ld64_latest_linux_x86_64.zip

4. 下载 SDK

从 Xcode 里抠了个 10.2 的出来, 似乎还不支持, 所以先找个 9.x 用着先

Preconfigured theos with toolchain and iOS 9.2 SDK for Linux (x86_64)

Preconfigured theos with toolchain and iOS 9.2 SDK for Linux (x86_64): https://mega.nz/#!2cgxWKga!5uiyj7dlCXr2K-txg1_GvTu9pOKR0zkgqACz7gIgCtk

这里可以搞到一个 9.2 的, 同样要在 bash 里解压到 /mnt/d/Dev/iOS/theos/sdks

5. 开始编译

现在来新建一个 tweak 编译试一下

果然还是出错了…

另外也可能会遇到这种错误

libstdc++.so.6: version `GLIBCXX_3.4.20' not found

6. 安装依赖

找了半天找到一个能用的

cd /tmp
wget http://security.ubuntu.com/ubuntu/pool/main/g/gcc-5/libstdc++6_5.4.0-6ubuntu1~16.04.4_amd64.deb
dpkg-deb -x libstdc++6_5.4.0-6ubuntu1~16.04.4_amd64.deb libstdc++
cp libstdc++/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21 /usr/lib/x86_64-linux-gnu/
cd /usr/lib/x86_64-linux-gnu/
ln -sf libstdc++.so.6.0.21 libstdc++.so.6

好了, 再来 make 一遍

妈的又出错了, makefiles 看起来又有问题

7. 修改 makefiles

省略一万字, 经过漫长的研究, 最终发现主要问题有两个:

  1. 跟 toolchain 不配套

  2. 另一个是文件权限的问题

因为要方便编辑, 代码肯定是放在 Windows 的分区里, 这些文件在 bash 里的权限全是 0777, 并且 chmod 也修改不了, 于是有些工具就不工作了, 比如 strip ldid dpkg-deb

另外也不能把代码放在 lxss 里面, 因为一样不能直接编辑, 具体原因看 这里

于是我的解决方法就是修改 makefile, 在有权限问题的地方, 把文件先复制到 /tmp 下, 操作完之后, 再复制回去

具体修改如下

diff --git a/makefiles/common.mk b/makefiles/common.mk
index 0f58d49..fa7d839 100644
--- a/makefiles/common.mk
+++ b/makefiles/common.mk
@@ -12,6 +12,21 @@ THEOS_PROJECT_DIR ?= $(shell pwd)
 _THEOS_LOCAL_DATA_DIR := $(THEOS_PROJECT_DIR)/.theos
 _THEOS_BUILD_SESSION_FILE = $(_THEOS_LOCAL_DATA_DIR)/build_session
 
+_THEOS_TMP_FOR_WSL_BASE := /tmp/theos_for_wsl
+_THEOS_TMP_FOR_WSL := $(abspath $(dir $(lastword $(THEOS_PROJECT_DIR))))
+_THEOS_TMP_FOR_WSL := $(_THEOS_TMP_FOR_WSL_BASE)/$(THEOS_PROJECT_DIR:$(_THEOS_TMP_FOR_WSL)/%=%)
+
+all::
+	@mkdir -p $(_THEOS_TMP_FOR_WSL)
+
+ifneq ($(_THEOS_TMP_FOR_WSL),)
+ifneq ($(_THEOS_TMP_FOR_WSL),/)
+clean::
+		@rm -rf $(_THEOS_TMP_FOR_WSL)
+		@# @rmdir --ignore-fail-on-non-empty $(_THEOS_TMP_FOR_WSL_BASE)
+endif
+endif
+
 ### Functions
 # Function for getting a clean absolute path from cd.
 __clean_pwd = $(shell (unset CDPATH; cd "$(1)"; pwd))
@@ -169,6 +184,7 @@ _THEOS_PACKAGE_LAST_FILENAME = $(call __simplify,_THEOS_PACKAGE_LAST_FILENAME,$(
 
 # ObjC/++ stuff is not here, it's in instance/rules.mk and only added if there are OBJC/OBJCC objects.
 _THEOS_INTERNAL_LDFLAGS = $(if $(_THEOS_TARGET_HAS_LIBRARY_PATH),-L$(THEOS_TARGET_LIBRARY_PATH) )-L$(THEOS_LIBRARY_PATH) -L$(THEOS_VENDOR_LIBRARY_PATH)
+_THEOS_INTERNAL_LDFLAGS += -lc++
 
 DEBUGFLAG ?= -ggdb
 DEBUG.CFLAGS = -DDEBUG $(DEBUGFLAG) -O0
diff --git a/makefiles/instance/rules.mk b/makefiles/instance/rules.mk
index bd3ea99..982af3c 100644
--- a/makefiles/instance/rules.mk
+++ b/makefiles/instance/rules.mk
@@ -344,7 +344,8 @@ $$(THEOS_OBJ_DIR)/%/$(1): $(__ALL_FILES)
 ifneq ($$(TARGET_CODESIGN),)
 .INTERMEDIATE: $$(THEOS_OBJ_DIR)/$(1).$(_THEOS_OUT_FILE_TAG).unsigned
 $(THEOS_OBJ_DIR)/$(1): $$(THEOS_OBJ_DIR)/$(1).$(_THEOS_OUT_FILE_TAG).unsigned
-	$$(ECHO_SIGNING)$$(_THEOS_CODESIGN_COMMANDLINE) "$$<" && mv "$$<" "$$@"$$(ECHO_END)
+	$$(ECHO_SIGNING)cp "$$<" $(_THEOS_TMP_FOR_WSL) && $$(_THEOS_CODESIGN_COMMANDLINE) "$(_THEOS_TMP_FOR_WSL)/$(1).$(_THEOS_OUT_FILE_TAG).unsigned" && mv "$(_THEOS_TMP_FOR_WSL)/$(1).$(_THEOS_OUT_FILE_TAG).unsigned" "$$@"$$(ECHO_END)
+	@# $$(ECHO_SIGNING)$$(_THEOS_CODESIGN_COMMANDLINE) "$$<" && mv "$$<" "$$@"$$(ECHO_END)
 $(THEOS_OBJ_DIR)/$(1).$(_THEOS_OUT_FILE_TAG).unsigned: $$(ARCH_FILES_TO_LINK)
 else
 $(THEOS_OBJ_DIR)/$(1): $$(ARCH_FILES_TO_LINK)
@@ -361,7 +362,9 @@ endif
 	$$(ECHO_NOTHING)mkdir -p $(shell dirname "$(THEOS_OBJ_DIR)/$(1)")$$(ECHO_END)
 	$$(ECHO_LINKING)$$(ECHO_UNBUFFERED)$$(TARGET_LD) $$(ALL_LDFLAGS) -o "$$@" $$^ | (grep -v 'usr/lib/dylib1.o, missing required architecture' || true)$$(ECHO_END)
 ifeq ($(SHOULD_STRIP),$(_THEOS_TRUE))
-	$$(ECHO_STRIPPING)$$(ECHO_UNBUFFERED)$$(TARGET_STRIP) $$(ALL_STRIP_FLAGS) "$$@"$$(ECHO_END)
+	@mkdir -p "$(_THEOS_TMP_FOR_WSL)/$(THEOS_CURRENT_ARCH)"
+	$$(ECHO_STRIPPING)$$(ECHO_UNBUFFERED)cp "$$@" "$(_THEOS_TMP_FOR_WSL)/$(THEOS_CURRENT_ARCH)" && $$(TARGET_STRIP) $$(ALL_STRIP_FLAGS) "$(_THEOS_TMP_FOR_WSL)/$(THEOS_CURRENT_ARCH)/$(1)" && mv "$(_THEOS_TMP_FOR_WSL)/$(THEOS_CURRENT_ARCH)/$(1)" $$(THEOS_OBJ_DIR)$$(ECHO_END)
+	@# $$(ECHO_STRIPPING)$$(ECHO_UNBUFFERED)$$(TARGET_STRIP) $$(ALL_STRIP_FLAGS) "$$@"$$(ECHO_END)
 endif
 endif
 endif
diff --git a/makefiles/package/deb.mk b/makefiles/package/deb.mk
index da23b63..d51a248 100644
--- a/makefiles/package/deb.mk
+++ b/makefiles/package/deb.mk
@@ -3,7 +3,7 @@ _THEOS_PACKAGE_FORMAT_LOADED := 1
 
 _THEOS_PLATFORM_DU ?= du
 _THEOS_PLATFORM_DPKG_DEB ?= dpkg-deb
-_THEOS_PLATFORM_DPKG_DEB_COMPRESSION ?= lzma
+_THEOS_PLATFORM_DPKG_DEB_COMPRESSION ?= gzip
 
 _THEOS_DEB_PACKAGE_CONTROL_PATH := $(or $(wildcard $(THEOS_PROJECT_DIR)/control),$(wildcard $(THEOS_LAYOUT_DIR)/DEBIAN/control))
 _THEOS_DEB_CAN_PACKAGE := $(if $(_THEOS_DEB_PACKAGE_CONTROL_PATH),$(_THEOS_TRUE),$(_THEOS_FALSE))
@@ -37,7 +37,10 @@ before-package:: $(_THEOS_ESCAPED_STAGING_DIR)/DEBIAN/control
 
 _THEOS_DEB_PACKAGE_FILENAME = $(THEOS_PACKAGE_DIR)/$(THEOS_PACKAGE_NAME)_$(_THEOS_INTERNAL_PACKAGE_VERSION)_$(THEOS_PACKAGE_ARCH).deb
 internal-package::
-	$(ECHO_NOTHING)COPYFILE_DISABLE=1 $(FAKEROOT) -r $(_THEOS_PLATFORM_DPKG_DEB) -Z$(_THEOS_PLATFORM_DPKG_DEB_COMPRESSION) -b "$(THEOS_STAGING_DIR)" "$(_THEOS_DEB_PACKAGE_FILENAME)"$(ECHO_END)
+	@cp -ar "$(THEOS_STAGING_DIR)" "$(_THEOS_TMP_FOR_WSL)"
+	@chmod -R 0755 "$(_THEOS_TMP_FOR_WSL)/$(THEOS_STAGING_DIR_NAME)"
+	$(ECHO_NOTHING)COPYFILE_DISABLE=1 $(FAKEROOT) -r $(_THEOS_PLATFORM_DPKG_DEB) -Z$(_THEOS_PLATFORM_DPKG_DEB_COMPRESSION) -b "$(_THEOS_TMP_FOR_WSL)/$(THEOS_STAGING_DIR_NAME)" "$(_THEOS_DEB_PACKAGE_FILENAME)"$(ECHO_END)
+	@# $(ECHO_NOTHING)COPYFILE_DISABLE=1 $(FAKEROOT) -r $(_THEOS_PLATFORM_DPKG_DEB) -Z$(_THEOS_PLATFORM_DPKG_DEB_COMPRESSION) -b "$(THEOS_STAGING_DIR)" "$(_THEOS_DEB_PACKAGE_FILENAME)"$(ECHO_END)
 
 # This variable is used in package.mk
 after-package:: __THEOS_LAST_PACKAGE_FILENAME = $(_THEOS_DEB_PACKAGE_FILENAME)
diff --git a/makefiles/platform/Linux.mk b/makefiles/platform/Linux.mk
index 58f1274..7c730bc 100644
--- a/makefiles/platform/Linux.mk
+++ b/makefiles/platform/Linux.mk
@@ -6,7 +6,7 @@ _THEOS_PLATFORM_DEFAULT_TARGET := iphone
 _THEOS_PLATFORM_DU_EXCLUDE := --exclude
 _THEOS_PLATFORM_MD5SUM := md5sum
 # TODO: Figure out if hardcoding "/iphone/" in _THEOS_PLATFORM_LIPO's path is a good idea or not
-_THEOS_PLATFORM_LIPO = $(THEOS)/toolchain/$(THEOS_PLATFORM_NAME)/iphone/bin/armv7-apple-darwin11-lipo
+_THEOS_PLATFORM_LIPO = $(THEOS)/toolchain/$(THEOS_PLATFORM_NAME)/iphone/bin/arm64-apple-darwin14-lipo
 # TODO: Find some better way to determine _THEOS_PLATFORM_SHOW_IN_FILE_MANAGER, as not all desktop environments use Nautilus as the file manager
 _THEOS_PLATFORM_SHOW_IN_FILE_MANAGER := nautilus
 endif
diff --git a/makefiles/targets/Linux/iphone.mk b/makefiles/targets/Linux/iphone.mk
index 8a4ab94..479ace1 100644
--- a/makefiles/targets/Linux/iphone.mk
+++ b/makefiles/targets/Linux/iphone.mk
@@ -2,7 +2,7 @@ ifeq ($(_THEOS_TARGET_LOADED),)
 _THEOS_TARGET_LOADED := 1
 THEOS_TARGET_NAME := iphone
 
-SDKTARGET ?= armv7-apple-darwin11
+SDKTARGET ?= arm64-apple-darwin14
 SDKBINPATH ?= $(THEOS)/toolchain/$(THEOS_PLATFORM_NAME)/$(THEOS_TARGET_NAME)/bin
 
 _THEOS_TARGET_CC := clang

好了, 再来 make 一遍

tmd 终于正常了


总是自带符号
ADDITIONAL_CFLAGS += -fvisibility=hidden
Init_Func坑爹执行顺序
执行顺序与makefile中 xxx_FILES顺序一致, %ctor 必须放最后
NSLog 会修改 errno, 注意不要被坑

#2

所以直接装个Ubuntu不就好了


#3

感谢。
等我mac安装个win10虚拟机,然后操作一遍……go go go !


#4

在之前我也想尝试吧Theos装到win10里,但是没什么时间.
刚好你搞定了…既然这样…我就不折腾了


#5

全屏的f**k也挺带感的