https://github.com/theos/theos/wiki/Installation
昨天偶然看到上面单独写了 Windows 10 的支持
正好 Windows 版的已经100万年没更新了, 所以决定折腾一下
1. 安装 Linux 子系统
2. 安装最新的 theos
https://github.com/theos/theos/wiki/Installation#installation
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
省略一万字, 经过漫长的研究, 最终发现主要问题有两个:
-
跟 toolchain 不配套
-
另一个是文件权限的问题
因为要方便编辑, 代码肯定是放在 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, 注意不要被坑