[init] 初始化0.1.0版本

This commit is contained in:
walon 2022-09-22 08:56:07 +08:00
parent 0bdd9edaf4
commit a52ab358b3
254 changed files with 11428 additions and 352 deletions

350
.gitignore vendored
View File

@ -1,350 +0,0 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/

5
CHANGELOG.md Normal file
View File

@ -0,0 +1,5 @@
# change logs
- 2022.8.30 创建

7
CHANGELOG.md.meta Normal file
View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7b2d5d0a85ef3bf44be6cbe94ed5ed2a
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Data.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1c3bdcb0d35a8834aadbee0e5e02a093
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 68f56e29afb52164b85f220d1033b461
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1cd43f2247d29084fa2b393c30648e64
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 22f11da50eb60c245b40028549937af6
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 94322e93a1f61b340bdc1d5042dab659
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8f2a6638b09b52f4c9dc8906d090b710
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a96a2c46326d2a84984c2820bd4bfc91
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 33c064b00b452284f93cd6e89de8a06d
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d104ab5da8136154899a40116dc88731
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: f42c0f03663d4c14f8a49912c08a514f
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b3b3b1f0cbc038149acb4d23bc6d5bf5
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Data/Templates.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f54201f21d7421d4c894298aa5266c73
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,22 @@
#include "MethodBridge.h"
#include <codegen/il2cpp-codegen-metadata.h>
#include "vm/ClassInlines.h"
#include "vm/Object.h"
#include "vm/Class.h"
#include "../metadata/MetadataModule.h"
#include "../metadata/MetadataUtil.h"
#include "Interpreter.h"
#include "MemoryUtil.h"
#include "InstrinctDef.h"
using namespace hybridclr::interpreter;
using hybridclr::GetInterpreterDirectlyCallMethodPointer;
#if HYBRIDCLR_ABI_ARM_64
//!!!{{INVOKE_STUB
//!!!}}INVOKE_STUB
#endif

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 1249fb131a848a14f8dd0938e3cc2558
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,22 @@
#include "MethodBridge.h"
#include <codegen/il2cpp-codegen-metadata.h>
#include "vm/ClassInlines.h"
#include "vm/Object.h"
#include "vm/Class.h"
#include "../metadata/MetadataModule.h"
#include "../metadata/MetadataUtil.h"
#include "Interpreter.h"
#include "MemoryUtil.h"
#include "InstrinctDef.h"
using namespace hybridclr::interpreter;
using hybridclr::GetInterpreterDirectlyCallMethodPointer;
#if HYBRIDCLR_ABI_UNIVERSAL_32
//!!!{{INVOKE_STUB
//!!!}}INVOKE_STUB
#endif

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: e06e14385d246aa4ab853d3fd04d6eec
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,22 @@
#include "MethodBridge.h"
#include <codegen/il2cpp-codegen-metadata.h>
#include "vm/ClassInlines.h"
#include "vm/Object.h"
#include "vm/Class.h"
#include "../metadata/MetadataModule.h"
#include "../metadata/MetadataUtil.h"
#include "Interpreter.h"
#include "MemoryUtil.h"
#include "InstrinctDef.h"
using namespace hybridclr::interpreter;
using hybridclr::GetInterpreterDirectlyCallMethodPointer;
#if HYBRIDCLR_ABI_UNIVERSAL_64
//!!!{{INVOKE_STUB
//!!!}}INVOKE_STUB
#endif

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2965fa89651ee0c4eb4c4fdcf95b76b8
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,36 @@
#include "ReversePInvokeMethodStub.h"
#include "MetadataModule.h"
namespace hybridclr
{
namespace metadata
{
//!!!{{REVERSE_PINVOKE_METHOD_STUB
void CallLuaFunction(void* xState, int32_t wrapperIndex)
{
const MethodInfo* method = MetadataModule::GetMethodInfoByReversePInvokeWrapperIndex(wrapperIndex);
typedef void (*Callback)(void* xState, const MethodInfo* method);
((Callback)GetInterpreterDirectlyCallMethodPointer(method))(xState, method);
}
void __ReversePInvokeMethod_0(void* xState)
{
CallLuaFunction(xState, 0);
}
void __ReversePInvokeMethod_1(void* xState)
{
CallLuaFunction(xState, 1);
}
Il2CppMethodPointer s_ReversePInvokeMethodStub[]
{
(Il2CppMethodPointer)__ReversePInvokeMethod_0,
(Il2CppMethodPointer)__ReversePInvokeMethod_1,
nullptr,
};
//!!!}}REVERSE_PINVOKE_METHOD_STUB
}
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 6447cdc1825eeef49a3679545ac31d95
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Data/iOSBuild.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c9442afcb42f28646a509d70ffe3d880
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,88 @@
# file: CMakeList.txt
cmake_minimum_required(VERSION 3.0)
set(CMAKE_OSX_DEPLOYMENT_TARGET iOS)
set(TMP $ENV{HUATUO_IL2CPP_SOURCE_DIR})
if ( NOT TMP )
message(FATAL_ERROR "需要设置环境变量: HUATUO_IL2CPP_SOURCE_DIR")
else()
message(STATUS "unity il2cpp 路径为: ${TMP}")
endif()
set(SDK_VERSION $ENV{IPHONESIMULATOR_VERSION})
if ( SDK_VERSION )
message(STATUS "使用iPhoneSimulator版本:" ${SDK_VERSION})
else()
message(STATUS "当前使用默认版本的iPhoneSimulator可以通过设置环境变量IPHONESIMULATOR_VERSION指定版本")
endif()
project(il2cpp)
execute_process(COMMAND sh gen_lump.sh ${PROJECT_BINARY_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
add_subdirectory(external)
add_subdirectory(objective)
set(IL2CPP_SOURCE_DIR $ENV{HUATUO_IL2CPP_SOURCE_DIR})
message(STATUS "il2cpp project, binary dir: " ${CMAKE_BINARY_DIR})
message(STATUS "il2cpp project, build dir: " ${PROJECT_BINARY_DIR})
message(STATUS "il2cpp project, il2cpp source dir: " ${IL2CPP_SOURCE_DIR})
SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON)
find_program(CLANG_EXECUTABLE NAMES clang clang-7 clang-8 clang-9 clang-10)
if (NOT CLANG_EXECUTABLE)
message(FATAL_ERROR "Cannot find any clang executable.")
endif()
set(CMAKE_OSX_SYSROOT /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator${SDK_VERSION}.sdk)
#set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_C_COMPILER clang)
#add_compile_options(-x objective-c++)
# Xcode
set(CMAKE_CXX_FLAGS "-target arm64-apple-ios11.0 -fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0 -std=gnu++1z -fmodules -fmodules-prune-interval=86400 -fmodules-prune-after=345600 -fmodules-ignore-macro=IL2CPP_TARGET_IOS=1 -fembed-bitcode -fmodules-ignore-macro=BASELIB_DYNAMICLIBRARY=1 -fmodules-ignore-macro=BASELIB_INLINE_NAMESPACE=il2cpp_baselib -fmodules-ignore-macro=AARCH64 -fmodules-ignore-macro=__aarch64__ -fmodules-ignore-macro=IL2CPP_SUPPORT_THREADS -fmodules-ignore-macro=IL2CPP_THREADS_PTHREAD -Wnon-modular-include-in-framework-module -Werror=non-modular-include-in-framework-module -Wno-trigraphs -fpascal-strings -Os -fno-common -Wno-missing-field-initializers -Wno-missing-prototypes -Werror=return-type -Wdocumentation -Wunreachable-code -Wquoted-include-in-framework-header -Werror=deprecated-objc-isa-usage -Werror=objc-root-class -Wno-non-virtual-dtor -Wno-overloaded-virtual -Wno-exit-time-destructors -Wno-missing-braces -Wparentheses -Wswitch -Wno-unused-function -Wno-unused-label -Wno-unused-parameter -Wno-unused-variable -Wunused-value -Wempty-body -Wuninitialized -Wconditional-uninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wconstant-conversion -Wint-conversion -Wbool-conversion -Wenum-conversion -Wno-float-conversion -Wnon-literal-null-conversion -Wobjc-literal-conversion -Wshorten-64-to-32 -Wno-newline-eof -Wno-c++11-extensions -DIL2CPP_TARGET_IOS=1 -isysroot ${CMAKE_OSX_SYSROOT} -fasm-blocks -fstrict-aliasing -Wdeprecated-declarations -Winvalid-offsetof -g -Wno-sign-conversion -Winfinite-recursion -Wmove -Wcomma -Wblock-capture-autoreleasing -Wstrict-prototypes -Wrange-loop-analysis -Wno-semicolon-before-method-body -Wunguarded-availability ")
add_definitions(-DIL2CPP_TARGET_IOS=1)
add_definitions(-DBASELIB_DYNAMICLIBRARY=1)
add_definitions(-DBASELIB_INLINE_NAMESPACE=il2cpp_baselib)
add_definitions(-DAARCH64)
add_definitions(-D__aarch64__)
add_definitions(-DIL2CPP_SUPPORT_THREADS)
add_definitions(-DIL2CPP_THREADS_PTHREAD)
#add_definitions(-DCMAKE_C_COMPILER=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang)
#add_definitions(-DCMAKE_CXX_COMPILER=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++)
#add_definitions(-DIL2CPP_TARGET_DARWIN)
add_definitions(-DIL2CPP_PLATFORM_SUPPORTS_TIMEZONEINFO)
add_definitions(-MMD)
add_definitions(-MT dependencies)
include_directories(${IL2CPP_SOURCE_DIR}/libil2cpp/)
include_directories(${IL2CPP_SOURCE_DIR}/external/)
include_directories(${IL2CPP_SOURCE_DIR}/external/baselib/Include/)
include_directories(${IL2CPP_SOURCE_DIR}/external/bdwgc/include/)
include_directories(${IL2CPP_SOURCE_DIR}/external/baselib/Platforms/OSX/Include/)
# SDK
include_directories(SYSTEM /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/c++/v1)
include_directories(SYSTEM /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include)
aux_source_directory(${PROJECT_BINARY_DIR}/lump_cpp LUMP_SOURCE_LIST)
aux_source_directory(${IL2CPP_SOURCE_DIR}/libil2cpp LIBIL2CPP_SOURCE_LIST)
#find_library(zlib ${PROJECT_SOURCE_DIR}/external)
add_library(il2cpp_original STATIC ${LIBIL2CPP_SOURCE_LIST} ${LUMP_SOURCE_LIST})
add_dependencies(il2cpp_original external objective)
add_custom_command(TARGET il2cpp_original
POST_BUILD
COMMAND xcrun -r libtool -static -o libil2cpp.a libil2cpp_original.a external/libexternal.a objective/libobjective.a
COMMENT "post build this is command combine libil2cpp_original.a, libojjective.a and libzlib.a into libil2cpp"
)

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 3436274d6dd0cc64fb4d15c898cc1d1d
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Data/iOSBuild/build.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 94c0855e86b12b64b8c1d29c51ac795d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,19 @@
#!/bin/bash
export HUATUO_IL2CPP_SOURCE_DIR=$(pushd ../LocalIl2CppData-OSXEditor/il2cpp > /dev/null && pwd && popd > /dev/null)
export IPHONESIMULATOR_VERSION=
rm -rf build
mkdir build
cd build
cmake ..
make -j24
if [ -f "libil2cpp.a" ]
then
echo 'build succ'
else
echo "build fail"
exit 1
fi

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: cbb71cfc70bb1304f9527eb7ca5d38ee
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8ed3bb85d9526f9468289a2e26dadf0b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

47
Data/iOSBuild/external/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,47 @@
# file: external/CMakeList.txt
cmake_minimum_required(VERSION 3.0)
set(CMAKE_OSX_DEPLOYMENT_TARGET iOS)
set(IL2CPP_SOURCE_DIR $ENV{HUATUO_IL2CPP_SOURCE_DIR})
set(SDK_VERSION $ENV{IPHONESIMULATOR_VERSION})
message(STATUS "external project, external source dir: " ${IL2CPP_SOURCE_DIR})
SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON)
find_program(CLANG_EXECUTABLE NAMES clang clang-7 clang-8 clang-9 clang-10)
if (NOT CLANG_EXECUTABLE)
message(FATAL_ERROR "Cannot find any clang executable.")
endif()
set(CMAKE_OSX_SYSROOT /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator${SDK_VERSION}.sdk)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_C_COMPILER clang)
set(CMAKE_C_FLAGS "-x c -target arm64-apple-ios11.0 -fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0 -std=gnu11 -fmodules -fmodules-prune-interval=86400 -fmodules-prune-after=345600 -fmodules-ignore-macro=IL2CPP_TARGET_IOS=1 -fembed-bitcode -fmodules-ignore-macro=BASELIB_DYNAMICLIBRARY=1 -fmodules-ignore-macro=BASELIB_INLINE_NAMESPACE=il2cpp_baselib -fmodules-ignore-macro=AARCH64 -fmodules-ignore-macro=__aarch64__ -fmodules-ignore-macro=IL2CPP_SUPPORT_THREADS -fmodules-ignore-macro=IL2CPP_THREADS_PTHREAD -Wnon-modular-include-in-framework-module -Werror=non-modular-include-in-framework-module -Wno-trigraphs -fpascal-strings -Os -fno-common -Wno-missing-field-initializers -Wno-missing-prototypes -Werror=return-type -Wdocumentation -Wunreachable-code -Wquoted-include-in-framework-header -Werror=deprecated-objc-isa-usage -Werror=objc-root-class -Wno-missing-braces -Wparentheses -Wswitch -Wunused-function -Wno-unused-label -Wno-unused-parameter -Wunused-variable -Wunused-value -Wempty-body -Wuninitialized -Wconditional-uninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wconstant-conversion -Wint-conversion -Wbool-conversion -Wenum-conversion -Wno-float-conversion -Wnon-literal-null-conversion -Wobjc-literal-conversion -Wshorten-64-to-32 -Wpointer-sign -Wno-newline-eof -DIL2CPP_TARGET_IOS=1 -isysroot ${CMAKE_OSX_SYSROOT} -fstrict-aliasing -Wdeprecated-declarations -g -Wno-sign-conversion -Winfinite-recursion -Wcomma -Wblock-capture-autoreleasing -Wstrict-prototypes -Wno-semicolon-before-method-body -Wunguarded-availability")
add_definitions(-DIL2CPP_TARGET_IOS=1)
add_definitions(-DBASELIB_DYNAMICLIBRARY=1)
add_definitions(-DBASELIB_INLINE_NAMESPACE=il2cpp_baselib)
add_definitions(-DAARCH64)
add_definitions(-D__aarch64__)
#add_definitions(-D__arm64__)
add_definitions(-DIL2CPP_SUPPORT_THREADS)
add_definitions(-DIL2CPP_THREADS_PTHREAD)
#add_definitions(-DCMAKE_C_COMPILER=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang)
#add_definitions(-DCMAKE_CXX_COMPILER=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++)
#add_definitions(-DIL2CPP_TARGET_DARWIN)
add_definitions(-DIL2CPP_PLATFORM_SUPPORTS_TIMEZONEINFO=0)
add_definitions(-MMD)
add_definitions(-MT dependencies)
include_directories(${IL2CPP_SOURCE_DIR}/external/)
include_directories(${IL2CPP_SOURCE_DIR}/external/baselib/Include/)
include_directories(${IL2CPP_SOURCE_DIR}/external/bdwgc/include/)
include_directories(${IL2CPP_SOURCE_DIR}/external/baselib/Platforms/OSX/Include/)
aux_source_directory(${IL2CPP_SOURCE_DIR}/external/zlib/ ZLIB_C_SOURCE_LIST)
add_library(external STATIC ${ZLIB_C_SOURCE_LIST})

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 03b1d6a5f25828042a1d215904917995
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

64
Data/iOSBuild/gen_lump.sh Normal file
View File

@ -0,0 +1,64 @@
echo '====================================================================='
echo 'gen lump'
echo '$HUATUO_IL2CPP_SOURCE_DIR='${HUATUO_IL2CPP_SOURCE_DIR} #/Applications/Unity/Unity.app/Contents/il2cpp/
GEN_SOURCE_DIR=$1
BASE_DIR=${HUATUO_IL2CPP_SOURCE_DIR}/libil2cpp
echo base dir: ${BASE_DIR}
echo " "
#BASE_DIR=${HUATUO_IL2CPP_SOURCE_DIR}/libil2cpp
function SearchCppFile()
{
for f in $(ls $1)
do
SUB_DIR=$1/$f
if [ -d ${SUB_DIR} ]; then
SearchCppFile ${SUB_DIR}
fi
done
CPP_FILE_NUM=`ls -l $1/ | grep "\.cpp$"|wc -l`
if (( ${CPP_FILE_NUM} > 0 ))
then
for f in $1/*.cpp
do
echo "#include \""$f"\"" >> ${OUTPUT_FILE_NAME}
done
fi
MM_FILE_NUM=`ls -l $1/ | grep "\.mm$"|wc -l`
if (( ${MM_FILE_NUM} > 0 ))
then
for f in $1/*.mm
do
echo "#include \""$f"\"" >> ${OBJECTIVE_FILE_NAME}
done
fi
}
rm -rf ${GEN_SOURCE_DIR}/lump_cpp
rm -rf ${GEN_SOURCE_DIR}/lump_mm
mkdir ${GEN_SOURCE_DIR}/lump_cpp
mkdir ${GEN_SOURCE_DIR}/lump_mm
OBJECTIVE_FILE_NAME=${GEN_SOURCE_DIR}/lump_mm/lump_libil2cpp_ojective.mm
echo "#include \"${BASE_DIR}/il2cpp-config.h\"" > ${OBJECTIVE_FILE_NAME}
echo gen file: ${OBJECTIVE_FILE_NAME}
for FOLDER in hybridclr vm pch utils vm-utils codegen metadata os debugger mono gc icalls
do
OUTPUT_FILE_NAME=${GEN_SOURCE_DIR}/lump_cpp/lump_libil2cpp_${FOLDER}.cpp
echo "#include \"${BASE_DIR}/il2cpp-config.h\"" > ${OUTPUT_FILE_NAME}
if [ $FOLDER = hybridclr ] || [ $FOLDER = vm ]
then
echo "#include \"${BASE_DIR}/codegen/il2cpp-codegen.h\"" >> ${OUTPUT_FILE_NAME}
fi
SearchCppFile ${BASE_DIR}/${FOLDER}
echo gen file: ${OUTPUT_FILE_NAME}
done
echo gen done.
echo '====================================================================='
echo " "

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 641944d55f4cbc4449c3f8b3fcd4d7e5
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 01ed218875eaf574694fbe3a8e0c4a64
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,62 @@
# file: CMakeList.txt
cmake_minimum_required(VERSION 3.0)
set(CMAKE_OSX_DEPLOYMENT_TARGET iOS)
project(il2cpp)
set(IL2CPP_SOURCE_DIR $ENV{HUATUO_IL2CPP_SOURCE_DIR})
set(SDK_VERSION $ENV{IPHONESIMULATOR_VERSION})
message(STATUS "objective project, binary dir: " ${PROJECT_BINARY_DIR})
message(STATUS "objective project, il2cpp source dir: " ${PROJECT_SOURCE_DIR})
SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON)
find_program(CLANG_EXECUTABLE NAMES clang clang-7 clang-8 clang-9 clang-10)
if (NOT CLANG_EXECUTABLE)
message(FATAL_ERROR "Cannot find any clang executable.")
endif()
set(CMAKE_OSX_SYSROOT /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator${SDK_VERSION}.sdk)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_C_COMPILER clang)
#add_compile_options(-x objective-c++)
# Xcode
set(CMAKE_CXX_FLAGS "-target arm64-apple-ios11.0 -fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0 -std=gnu++1z -fmodules -fmodules-prune-interval=86400 -fmodules-prune-after=345600 -fmodules-ignore-macro=IL2CPP_TARGET_IOS=1 -fembed-bitcode -fmodules-ignore-macro=BASELIB_DYNAMICLIBRARY=1 -fmodules-ignore-macro=BASELIB_INLINE_NAMESPACE=il2cpp_baselib -fmodules-ignore-macro=AARCH64 -fmodules-ignore-macro=__aarch64__ -fmodules-ignore-macro=IL2CPP_SUPPORT_THREADS -fmodules-ignore-macro=IL2CPP_THREADS_PTHREAD -Wnon-modular-include-in-framework-module -Werror=non-modular-include-in-framework-module -Wno-trigraphs -fpascal-strings -Os -fno-common -Wno-missing-field-initializers -Wno-missing-prototypes -Werror=return-type -Wdocumentation -Wunreachable-code -Wquoted-include-in-framework-header -Werror=deprecated-objc-isa-usage -Werror=objc-root-class -Wno-non-virtual-dtor -Wno-overloaded-virtual -Wno-exit-time-destructors -Wno-missing-braces -Wparentheses -Wswitch -Wno-unused-function -Wno-unused-label -Wno-unused-parameter -Wno-unused-variable -Wunused-value -Wempty-body -Wuninitialized -Wconditional-uninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wconstant-conversion -Wint-conversion -Wbool-conversion -Wenum-conversion -Wno-float-conversion -Wnon-literal-null-conversion -Wobjc-literal-conversion -Wshorten-64-to-32 -Wno-newline-eof -Wno-c++11-extensions -DIL2CPP_TARGET_IOS=1 -isysroot ${SDK_VERSION} -fasm-blocks -fstrict-aliasing -Wdeprecated-declarations -Winvalid-offsetof -g -Wno-sign-conversion -Winfinite-recursion -Wmove -Wcomma -Wblock-capture-autoreleasing -Wstrict-prototypes -Wrange-loop-analysis -Wno-semicolon-before-method-body -Wunguarded-availability ")
add_definitions(-DIL2CPP_TARGET_IOS=1)
add_definitions(-DBASELIB_DYNAMICLIBRARY=1)
add_definitions(-DBASELIB_INLINE_NAMESPACE=il2cpp_baselib)
add_definitions(-DAARCH64)
add_definitions(-D__aarch64__)
add_definitions(-DIL2CPP_SUPPORT_THREADS)
add_definitions(-DIL2CPP_THREADS_PTHREAD)
#add_definitions(-DCMAKE_C_COMPILER=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang)
#add_definitions(-DCMAKE_CXX_COMPILER=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++)
#add_definitions(-DIL2CPP_TARGET_DARWIN)
add_definitions(-DIL2CPP_PLATFORM_SUPPORTS_TIMEZONEINFO)
add_definitions(-MMD)
add_definitions(-MT dependencies)
include_directories(${IL2CPP_SOURCE_DIR}/libil2cpp)
include_directories(${IL2CPP_SOURCE_DIR}/external)
include_directories(${IL2CPP_SOURCE_DIR}/external/baselib/Include/)
include_directories(${IL2CPP_SOURCE_DIR}/external/bdwgc/include/)
include_directories(${IL2CPP_SOURCE_DIR}/external/baselib/Platforms/OSX/Include/)
# SDK
include_directories(SYSTEM /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include/c++/v1)
include_directories(SYSTEM /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include)
get_filename_component(PARENT_PATH ${PROJECT_BINARY_DIR} PATH)
aux_source_directory(${PARENT_PATH}/lump_mm LUMP_SOURCE_LIST)
#find_library(zlib ${PROJECT_SOURCE_DIR}/external)
add_library(objective STATIC ${LUMP_SOURCE_LIST})

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 76642fe740b6fd74b9a4491ce83b897e
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Editor.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c3fabc41cf17c444995fc01a76c5dbe6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Editor/AOT.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b4071bf66ac9c544487ae88b5ee9b20a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

188
Editor/AOT/Analyzer.cs Normal file
View File

@ -0,0 +1,188 @@
using dnlib.DotNet;
using HybridCLR.Editor.Meta;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace HybridCLR.Editor.AOT
{
public class Analyzer
{
public class Options
{
public AssemblyReferenceDeepCollector Collector { get; set; }
public int MaxIterationCount { get; set; }
}
private readonly int _maxInterationCount;
private readonly AssemblyReferenceDeepCollector _assemblyCollector;
private readonly HashSet<GenericClass> _genericTypes = new HashSet<GenericClass>();
private readonly HashSet<GenericMethod> _genericMethods = new HashSet<GenericMethod>();
private List<GenericMethod> _processingMethods = new List<GenericMethod>();
private List<GenericMethod> _newMethods = new List<GenericMethod>();
public IReadOnlyCollection<GenericClass> GenericTypes => _genericTypes;
public IReadOnlyCollection<GenericMethod> GenericMethods => _genericMethods;
private readonly MethodReferenceAnalyzer _methodReferenceAnalyzer;
private readonly HashSet<string> _hotUpdateAssemblyFiles;
public Analyzer(Options options)
{
_assemblyCollector = options.Collector;
_maxInterationCount = options.MaxIterationCount;
_methodReferenceAnalyzer = new MethodReferenceAnalyzer(this.OnNewMethod);
_hotUpdateAssemblyFiles = new HashSet<string>(options.Collector.GetRootAssemblyNames().Select(assName => assName + ".dll"));
}
private void TryAddAndWalkGenericType(GenericClass gc)
{
if (gc == null)
{
return;
}
gc = gc.ToGenericShare();
if (_genericTypes.Add(gc) && NeedWalk(gc.Type))
{
WalkType(gc);
}
}
private bool NeedWalk(TypeDef type)
{
return _hotUpdateAssemblyFiles.Contains(type.Module.Name);
}
private void OnNewMethod(GenericMethod method)
{
if(method == null)
{
return;
}
if (_genericMethods.Add(method) && NeedWalk(method.Method.DeclaringType))
{
_newMethods.Add(method);
}
if (method.KlassInst != null)
{
TryAddAndWalkGenericType(new GenericClass(method.Method.DeclaringType, method.KlassInst));
}
}
private void TryAddMethodNotWalkType(GenericMethod method)
{
if (method == null)
{
return;
}
if (_genericMethods.Add(method) && NeedWalk(method.Method.DeclaringType))
{
_newMethods.Add(method);
}
}
private void WalkType(GenericClass gc)
{
//Debug.Log($"typespec:{sig} {sig.GenericType} {sig.GenericType.TypeDefOrRef.ResolveTypeDef()}");
//Debug.Log($"== walk generic type:{new GenericInstSig(gc.Type.ToTypeSig().ToClassOrValueTypeSig(), gc.KlassInst)}");
ITypeDefOrRef baseType = gc.Type.BaseType;
if (baseType != null && baseType.TryGetGenericInstSig() != null)
{
GenericClass parentType = GenericClass.ResolveClass((TypeSpec)baseType, new GenericArgumentContext(gc.KlassInst, null));
TryAddAndWalkGenericType(parentType);
}
foreach (var method in gc.Type.Methods)
{
if (method.HasGenericParameters || !method.HasBody || method.Body.Instructions == null)
{
continue;
}
var gm = new GenericMethod(method, gc.KlassInst, null).ToGenericShare();
//Debug.Log($"add method:{gm.Method} {gm.KlassInst}");
TryAddMethodNotWalkType(gm);
}
}
private void WalkType(TypeDef typeDef)
{
if (typeDef.HasGenericParameters)
{
return;
}
ITypeDefOrRef baseType = typeDef.BaseType;
if (baseType != null && baseType.TryGetGenericInstSig() != null)
{
GenericClass gc = GenericClass.ResolveClass((TypeSpec)baseType, null);
TryAddAndWalkGenericType(gc);
}
}
private void Prepare()
{
// 将所有非泛型函数全部加入函数列表同时立马walk这些method。
// 后续迭代中将只遍历MethodSpec
foreach (var ass in _assemblyCollector.GetLoadedModulesOfRootAssemblies())
{
foreach (TypeDef typeDef in ass.GetTypes())
{
WalkType(typeDef);
}
for (uint rid = 1, n = ass.Metadata.TablesStream.TypeSpecTable.Rows; rid <= n; rid++)
{
var ts = ass.ResolveTypeSpec(rid);
if (!ts.ContainsGenericParameter)
{
var cs = GenericClass.ResolveClass(ts, null)?.ToGenericShare();
TryAddAndWalkGenericType(cs);
}
}
for (uint rid = 1, n = ass.Metadata.TablesStream.MethodSpecTable.Rows; rid <= n; rid++)
{
var ms = ass.ResolveMethodSpec(rid);
if (ms.DeclaringType.ContainsGenericParameter || ms.GenericInstMethodSig.ContainsGenericParameter)
{
continue;
}
var gm = GenericMethod.ResolveMethod(ms, null)?.ToGenericShare();
TryAddMethodNotWalkType(gm);
}
}
Debug.Log($"PostPrepare genericTypes:{_genericTypes.Count} genericMethods:{_genericMethods.Count} newMethods:{_newMethods.Count}");
}
private void RecursiveCollect()
{
for (int i = 0; i < _maxInterationCount && _newMethods.Count > 0; i++)
{
var temp = _processingMethods;
_processingMethods = _newMethods;
_newMethods = temp;
_newMethods.Clear();
foreach (var method in _processingMethods)
{
_methodReferenceAnalyzer.WalkMethod(method.Method, method.KlassInst, method.MethodInst);
}
Debug.Log($"iteration:[{i}] genericClass:{_genericTypes.Count} genericMethods:{_genericMethods.Count} newMethods:{_newMethods.Count}");
}
}
public void Run()
{
Prepare();
RecursiveCollect();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 30bbf4a80a6cf3a43b3f489747d9dd6a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,46 @@
using HybridCLR.Editor.Meta;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace HybridCLR.Editor.AOT
{
public class GenericReferenceWriter
{
public void Write(List<GenericClass> types, List<GenericMethod> methods, string outputFile)
{
string parentDir = Directory.GetParent(outputFile).FullName;
Directory.CreateDirectory(parentDir);
List<string> codes = new List<string>();
codes.Add("public class AOTGenericReferences : UnityEngine.MonoBehaviour");
codes.Add("{");
foreach(var type in types)
{
codes.Add($"\t//{type.Type}");
}
codes.Add("\tpublic void RefMethods()");
codes.Add("\t{");
foreach(var method in methods)
{
codes.Add($"\t\t// {method.Method}");
}
codes.Add("\t}");
codes.Add("}");
var utf8WithoutBOM = new System.Text.UTF8Encoding(false);
File.WriteAllText(outputFile, string.Join("\n", codes), utf8WithoutBOM);
Debug.Log($"[GenericReferenceWriter] write {outputFile}");
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d1243cf04685361478972f93b5ca868a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f80d2287f01c89642a74b0a60f7a3305
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine;
namespace HybridCLR.Editor.BuildProcessors
{
internal class CheckSettings : IPreprocessBuildWithReport
{
public int callbackOrder => 0;
public void OnPreprocessBuild(BuildReport report)
{
#if !UNITY_2020_1_OR_NEWER || !UNITY_IOS
if (!SettingsUtil.Enable)
{
string oldIl2cppPath = Environment.GetEnvironmentVariable("UNITY_IL2CPP_PATH");
if (!string.IsNullOrEmpty(oldIl2cppPath))
{
Environment.SetEnvironmentVariable("UNITY_IL2CPP_PATH", "");
Debug.Log($"[CheckSettings] 清除 UNITY_IL2CPP_PATH, 旧值为:'{oldIl2cppPath}'");
}
}
else
{
string curIl2cppPath = Environment.GetEnvironmentVariable("UNITY_IL2CPP_PATH");
if (curIl2cppPath != SettingsUtil.LocalIl2CppDir)
{
Environment.SetEnvironmentVariable("UNITY_IL2CPP_PATH", SettingsUtil.LocalIl2CppDir);
Debug.Log($"[CheckSettings] UNITY_IL2CPP_PATH 当前值为:'{curIl2cppPath}',更新为:'{SettingsUtil.LocalIl2CppDir}'");
}
}
#endif
if (!SettingsUtil.Enable)
{
return;
}
if (UnityEditor.PlayerSettings.gcIncremental)
{
Debug.LogError($"[CheckSettings] HybridCLR不支持增量式GC已经自动将该选项关闭");
UnityEditor.PlayerSettings.gcIncremental = false;
}
var installer = new Installer.InstallerController();
if (!installer.HasInstalledHybridCLR())
{
throw new Exception($"你没有初始化HybridCLR请通过菜单'HybridCLR/Installer'安装");
}
HybridCLRGlobalSettings gs = SettingsUtil.GlobalSettings;
if (((gs.hotUpdateAssemblies?.Length + gs.hotUpdateAssemblyDefinitions?.Length) ?? 0) == 0)
{
throw new Exception($"GlobalSettings中未配置热更新dll");
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fb4ba063068b17247b2d0233420aa5f0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEditor.Il2Cpp;
using UnityEditor.UnityLinker;
using UnityEngine;
namespace HybridCLR.Editor.BuildProcessors
{
internal class CopyStrippedAOTAssemblies : IPostprocessBuildWithReport
#if !UNITY_2021_1_OR_NEWER
, IIl2CppProcessor
#endif
{
public int callbackOrder => 0;
#if UNITY_2021_1_OR_NEWER
public static string GetStripAssembliesDir2021(BuildTarget target)
{
string projectDir = SettingsUtil.ProjectDir;
#if UNITY_STANDALONE_WIN
return $"{projectDir}/Library/Bee/artifacts/WinPlayerBuildProgram/ManagedStripped";
#elif UNITY_ANDROID
return $"{projectDir}/Library/Bee/artifacts/Android/ManagedStripped";
#elif UNITY_IOS
return $"{projectDir}/Temp/StagingArea/Data/Managed/tempStrip";
#elif UNITY_WEBGL
return $"{projectDir}/Library/Bee/artifacts/WebGL/ManagedStripped";
#elif UNITY_EDITOR_OSX
return $"{projectDir}/Library/Bee/artifacts/MacStandalonePlayerBuildProgram/ManagedStripped";
#else
throw new NotSupportedException("GetOriginBuildStripAssembliesDir");
#endif
}
#else
private string GetStripAssembliesDir2020(BuildTarget target)
{
string subPath = target == BuildTarget.Android ?
"assets/bin/Data/Managed" :
"Data/Managed/";
return $"{SettingsUtil.ProjectDir}/Temp/StagingArea/{subPath}";
}
public void OnBeforeConvertRun(BuildReport report, Il2CppBuildPipelineData data)
{
// 此回调只在 2020中调用
CopyStripDlls(GetStripAssembliesDir2020(data.target), data.target);
}
#endif
public static void CopyStripDlls(string srcStripDllPath, BuildTarget target)
{
Debug.Log($"[CopyStrippedAOTAssemblies] CopyScripDlls. src:{srcStripDllPath} target:{target}");
var dstPath = SettingsUtil.GetAssembliesPostIl2CppStripDir(target);
Directory.CreateDirectory(dstPath);
foreach (var fileFullPath in Directory.GetFiles(srcStripDllPath, "*.dll"))
{
var file = Path.GetFileName(fileFullPath);
Debug.Log($"[CopyStrippedAOTAssemblies] copy strip dll {fileFullPath} ==> {dstPath}/{file}");
File.Copy($"{fileFullPath}", $"{dstPath}/{file}", true);
}
}
public void OnPostprocessBuild(BuildReport report)
{
#if UNITY_2021_1_OR_NEWER && !UNITY_IOS
BuildTarget target = EditorUserBuildSettings.activeBuildTarget;
CopyStripDlls(GetStripAssembliesDir2021(target), target);
#endif
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f7884710ec2f8e545b3fe9aa05def5a8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
using UnityEditor.Build;
using UnityEngine;
namespace HybridCLR.Editor.BuildProcessors
{
/// <summary>
/// 将热更新dll从Build过程中过滤防止打包到主工程中
/// </summary>
internal class FilterHotFixAssemblies : IFilterBuildAssemblies
{
public int callbackOrder => 0;
public string[] OnFilterAssemblies(BuildOptions buildOptions, string[] assemblies)
{
if (!SettingsUtil.Enable)
{
Debug.Log($"[FilterHotFixAssemblies] disabled");
return assemblies;
}
List<string> allHotUpdateDllFiles = SettingsUtil.HotUpdateAssemblyFiles;
// 检查是否重复填写
var hotUpdateDllSet = new HashSet<string>();
foreach(var hotUpdateDll in allHotUpdateDllFiles)
{
if (!hotUpdateDllSet.Add(hotUpdateDll))
{
throw new Exception($"热更新 assembly:{hotUpdateDll} 在列表中重复,请除去重复条目");
}
}
// 检查是否填写了正确的dll名称
foreach (var hotUpdateDll in allHotUpdateDllFiles)
{
if (assemblies.All(ass => !ass.EndsWith(hotUpdateDll)))
{
throw new Exception($"热更新 assembly:{hotUpdateDll} 不存在,请检查拼写错误");
}
Debug.Log($"[FilterHotFixAssemblies] 过滤热更新assembly:{hotUpdateDll}");
}
// 将热更dll从打包列表中移除
return assemblies.Where(ass => allHotUpdateDllFiles.All(dll => !ass.EndsWith(dll, StringComparison.OrdinalIgnoreCase))).ToArray();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9dec2922e3df5464aa047b636eb19e0d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,143 @@
using HybridCLR.Editor.UnityBinFileReader;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
using UnityEditor.Android;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEditor.Il2Cpp;
using UnityEditor.UnityLinker;
using UnityEngine;
using UnityFS;
namespace HybridCLR.Editor.BuildProcessors
{
public class PatchScriptingAssemblyList :
#if UNITY_ANDROID
IPostGenerateGradleAndroidProject,
#endif
IPostprocessBuildWithReport
{
public int callbackOrder => 0;
public void OnPostGenerateGradleAndroidProject(string path)
{
// 如果直接打包apk没有机会在PostprocessBuild中修改ScriptingAssemblies.json。
// 因此需要在这个时机处理
PathScriptingAssembilesFile(path);
}
public void OnPostprocessBuild(BuildReport report)
{
// 如果target为Android,由于已经在OnPostGenerateGradelAndroidProject中处理过
// 这里不再重复处理
#if !UNITY_ANDROID
PathScriptingAssembilesFile(report.summary.outputPath);
#endif
}
private void PathScriptingAssembilesFile(string path)
{
if (!SettingsUtil.Enable)
{
Debug.Log($"[PatchScriptingAssemblyList] disabled");
return;
}
Debug.Log($"[PatchScriptingAssemblyList]. path:{path}");
if (!Directory.Exists(path))
{
path = Path.GetDirectoryName(path);
Debug.Log($"[PatchScriptingAssemblyList] get path parent:{path}");
}
#if UNITY_2020_1_OR_NEWER
AddHotFixAssembliesToScriptingAssembliesJson(path);
#else
AddHotFixAssembliesToBinFile(path);
#endif
}
private void AddHotFixAssembliesToScriptingAssembliesJson(string path)
{
Debug.Log($"[PatchScriptingAssemblyList]. path:{path}");
/*
* ScriptingAssemblies.json dll名称
* dll在资源反序列化时无法被找到其类型
* OnFilterAssemblies
*/
string[] jsonFiles = Directory.GetFiles(path, SettingsUtil.ScriptingAssembliesJsonFile, SearchOption.AllDirectories);
if (jsonFiles.Length == 0)
{
Debug.LogError($"can not find file {SettingsUtil.ScriptingAssembliesJsonFile}");
return;
}
foreach (string file in jsonFiles)
{
var patcher = new ScriptingAssembliesJsonPatcher();
patcher.Load(file);
patcher.AddScriptingAssemblies(SettingsUtil.HotUpdateAssemblyFiles);
patcher.Save(file);
}
}
private void AddHotFixAssembliesToBinFile(string path)
{
if (AddHotFixAssembliesToGlobalgamemanagers(path))
{
return;
}
if (AddHotFixAssembliesTodataunity3d(path))
{
return;
}
Debug.LogError($"[PatchScriptingAssemblyList] can not find file '{SettingsUtil.GlobalgamemanagersBinFile}' or '{SettingsUtil.Dataunity3dBinFile}' in '{path}'");
}
private bool AddHotFixAssembliesToGlobalgamemanagers(string path)
{
string[] binFiles = Directory.GetFiles(path, SettingsUtil.GlobalgamemanagersBinFile, SearchOption.AllDirectories);
if (binFiles.Length == 0)
{
return false;
}
foreach (string binPath in binFiles)
{
var binFile = new UnityBinFile();
binFile.Load(binPath);
binFile.AddScriptingAssemblies(SettingsUtil.HotUpdateAssemblyFiles);
binFile.Save(binPath);
Debug.Log($"[PatchScriptingAssemblyList] patch {binPath}");
}
return true;
}
private bool AddHotFixAssembliesTodataunity3d(string path)
{
string[] binFiles = Directory.GetFiles(path, SettingsUtil.Dataunity3dBinFile, SearchOption.AllDirectories);
if (binFiles.Length == 0)
{
return false;
}
foreach (string binPath in binFiles)
{
var patcher = new Dataunity3dPatcher();
patcher.ApplyPatch(binPath, SettingsUtil.HotUpdateAssemblyFiles);
Debug.Log($"[PatchScriptingAssemblyList] patch {binPath}");
}
return true;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9bb6e2908d8948648979c9ff6bb7937d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

8
Editor/Commands.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 92f51c069d2607447ae2f61de80540fb
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,46 @@
using HybridCLR.Editor.AOT;
using HybridCLR.Editor.Meta;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;
namespace HybridCLR.Editor.Commands
{
public static class AOTReferenceGeneratorCommand
{
[MenuItem("HybridCLR/GenerateAOTGenericReference", priority = 18)]
public static void GenerateAOTGenericReference()
{
GenerateAOTGenericReference(true);
}
public static void GenerateAOTGenericReference(bool compileDll)
{
// 此处理论会有点问题,打每个平台的时候,都得针对当前平台生成桥接函数
// 但影响不大,先这样吧
if (compileDll)
{
CompileDllCommand.CompileDllActiveBuildTarget();
}
var gs = SettingsUtil.GlobalSettings;
var analyzer = new Analyzer(new Analyzer.Options
{
MaxIterationCount = Math.Min(20, gs.maxGenericReferenceIteration),
Collector = new AssemblyReferenceDeepCollector(MetaUtil.CreateBuildTargetAssemblyResolver(EditorUserBuildSettings.activeBuildTarget), SettingsUtil.HotUpdateAssemblyNames),
});
analyzer.Run();
var writer = new GenericReferenceWriter();
writer.Write(analyzer.GenericTypes.ToList(), analyzer.GenericMethods.ToList(), $"{Application.dataPath}/{gs.outputAOTGenericReferenceFile}");
AssetDatabase.Refresh();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2b464872c07f6ba4f9a4e4a02ca9a28c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
using UnityEditor.Build.Player;
using UnityEngine;
namespace HybridCLR.Editor.Commands
{
public class CompileDllCommand
{
public static void CompileDll(string buildDir, BuildTarget target)
{
var group = BuildPipeline.GetBuildTargetGroup(target);
ScriptCompilationSettings scriptCompilationSettings = new ScriptCompilationSettings();
scriptCompilationSettings.group = group;
scriptCompilationSettings.target = target;
Directory.CreateDirectory(buildDir);
ScriptCompilationResult scriptCompilationResult = PlayerBuildInterface.CompilePlayerScripts(scriptCompilationSettings, buildDir);
foreach (var ass in scriptCompilationResult.assemblies)
{
//Debug.LogFormat("compile assemblies:{1}/{0}", ass, buildDir);
}
}
public static void CompileDll(BuildTarget target)
{
CompileDll(SettingsUtil.GetHotFixDllsOutputDirByTarget(target), target);
}
[MenuItem("HybridCLR/CompileDll/ActiveBuildTarget")]
public static void CompileDllActiveBuildTarget()
{
CompileDll(EditorUserBuildSettings.activeBuildTarget);
}
[MenuItem("HybridCLR/CompileDll/Win32")]
public static void CompileDllWin32()
{
CompileDll(BuildTarget.StandaloneWindows);
}
[MenuItem("HybridCLR/CompileDll/Win64")]
public static void CompileDllWin64()
{
CompileDll(BuildTarget.StandaloneWindows64);
}
[MenuItem("HybridCLR/CompileDll/Android")]
public static void CompileDllAndroid()
{
CompileDll(BuildTarget.Android);
}
[MenuItem("HybridCLR/CompileDll/IOS")]
public static void CompileDllIOS()
{
CompileDll(BuildTarget.iOS);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bf11b6c8bbc5afd4cb4a11921e5bd81e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,61 @@
using HybridCLR.Editor.LinkGenerator;
using HybridCLR.Editor.Meta;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;
namespace HybridCLR.Editor.Commands
{
public static class LinkGeneratorCommand
{
[MenuItem("HybridCLR/GenerateLinkXml", priority = 10)]
public static void GenerateLinkXml()
{
GenerateLinkXml(true);
}
public static void GenerateLinkXml(bool compileDll)
{
if (compileDll)
{
CompileDllCommand.CompileDllActiveBuildTarget();
}
var ls = SettingsUtil.GlobalSettings;
var allAssByNames = new Dictionary<string, Assembly>();
foreach (var ass in AppDomain.CurrentDomain.GetAssemblies())
{
allAssByNames[ass.GetName().Name] = ass;
}
var hotfixAssembles = new List<Assembly>();
foreach(var assName in SettingsUtil.HotUpdateAssemblyNames)
{
if (allAssByNames.TryGetValue(assName, out var ass))
{
hotfixAssembles.Add(ass);
}
else
{
throw new Exception($"assembly:{assName} 不存在");
}
}
var analyzer = new Analyzer(MetaUtil.CreateBuildTargetAssemblyResolver(EditorUserBuildSettings.activeBuildTarget));
var refTypes = analyzer.CollectRefs(hotfixAssembles);
Debug.Log($"[LinkGeneratorCommand] hotfix assembly count:{hotfixAssembles.Count}, ref type count:{refTypes.Count} output:{Application.dataPath}/{ls.outputLinkFile}");
var linkXmlWriter = new LinkXmlWriter();
linkXmlWriter.Write($"{Application.dataPath}/{ls.outputLinkFile}", refTypes);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4f5b96abdbc4c424eb1bc3bc34b3a1a4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,103 @@
using HybridCLR.Editor;
using HybridCLR.Editor.Meta;
using HybridCLR.Editor.MethodBridgeGenerator;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;
namespace HybridCLR.Editor.Commands
{
public class MethodBridgeGeneratorCommand
{
public static void CleanIl2CppBuildCache()
{
string il2cppBuildCachePath = SettingsUtil.Il2CppBuildCacheDir;
if (!Directory.Exists(il2cppBuildCachePath))
{
return;
}
Debug.Log($"clean il2cpp build cache:{il2cppBuildCachePath}");
Directory.Delete(il2cppBuildCachePath, true);
}
private static string GetTemplateCode(PlatformABI platform)
{
string tplFile;
switch (platform)
{
case PlatformABI.Universal32: tplFile = "Universal32"; break;
case PlatformABI.Universal64: tplFile = "Universal64"; break;
case PlatformABI.Arm64: tplFile = "Arm64"; break;
default: throw new NotSupportedException();
};
return AssetDatabase.LoadAssetAtPath<TextAsset>($"{SettingsUtil.TemplatePathInPackage}/MethodBridge_{tplFile}.cpp.txt").text;
}
private static void GenerateMethodBridgeCppFile(Analyzer analyzer, PlatformABI platform, string templateCode, string outputFile)
{
var g = new Generator(new Generator.Options()
{
CallConvention = platform,
TemplateCode = templateCode,
OutputFile = outputFile,
GenericMethods = analyzer.GenericMethods,
NotGenericMethods = analyzer.NotGenericMethods,
});
g.PrepareMethods();
g.Generate();
Debug.LogFormat("== output:{0} ==", outputFile);
CleanIl2CppBuildCache();
}
[MenuItem("HybridCLR/GenerateMethodBridge", priority = 15)]
public static void GenerateMethodBridge()
{
GenerateMethodBridge(true);
}
public static void GenerateMethodBridge(bool compileDll)
{
// 此处理论会有点问题,打每个平台的时候,都得针对当前平台生成桥接函数
// 但影响不大,先这样吧
if (compileDll)
{
CompileDllCommand.CompileDllActiveBuildTarget();
}
var analyzer = new Analyzer(new Analyzer.Options
{
MaxIterationCount = Math.Min(20, SettingsUtil.GlobalSettings.maxMethodBridgeGenericIteration),
Collector = new AssemblyReferenceDeepCollector(MetaUtil.CreateBuildTargetAssemblyResolver(EditorUserBuildSettings.activeBuildTarget), SettingsUtil.HotUpdateAssemblyNames),
});
analyzer.Run();
var generateJobs = new List<(PlatformABI, string)>()
{
(PlatformABI.Arm64, "MethodBridge_Arm64"),
(PlatformABI.Universal64, "MethodBridge_Universal64"),
(PlatformABI.Universal32, "MethodBridge_Universal32"),
};
var tasks = new List<Task>();
foreach (var (platform, stubFile) in generateJobs)
{
string templateCode = GetTemplateCode(platform);
string outputFile = $"{SettingsUtil.MethodBridgeCppDir}/{stubFile}.cpp";
tasks.Add(Task.Run(() =>
{
GenerateMethodBridgeCppFile(analyzer, platform, templateCode, outputFile);
}));
}
Task.WaitAll(tasks.ToArray());
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 46bc62d5236f5e941850776c435a9560
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
namespace HybridCLR.Editor.Commands
{
public static class PrebuildCommand
{
/// <summary>
/// 按照必要的顺序,执行所有生成操作,适合打包前操作
/// </summary>
[MenuItem("HybridCLR/GenerateAll", priority = 30)]
public static void GenerateAll()
{
// 顺序随意
ReversePInvokeWrapperGeneratorCommand.GenerateReversePInvokeWrapper();
// AOTReferenceGeneratorCommand 涉及到代码生成必须在MethodBridgeGeneratorCommand之前
AOTReferenceGeneratorCommand.GenerateAOTGenericReference();
MethodBridgeGeneratorCommand.GenerateMethodBridge();
// 顺序随意,只要保证 GenerateLinkXml之前有调用过CompileDll即可
LinkGeneratorCommand.GenerateLinkXml(false);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c20f09bfbe3f32143aae872d3813d9e9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,31 @@
using HybridCLR.Editor.LinkGenerator;
using HybridCLR.Editor.ReversePInvokeWrap;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;
namespace HybridCLR.Editor.Commands
{
public static class ReversePInvokeWrapperGeneratorCommand
{
[MenuItem("HybridCLR/GenerateReversePInvokeWrapper", priority = 20)]
public static void GenerateReversePInvokeWrapper()
{
string ReversePInvokeWrapperStubFile = $"{SettingsUtil.LocalIl2CppDir}/libil2cpp/hybridclr/metadata/ReversePInvokeMethodStub.cpp";
string wrapperTemplateStr = AssetDatabase.LoadAssetAtPath<TextAsset>($"{SettingsUtil.TemplatePathInPackage}/ReversePInvokeMethodStub.cpp.txt").text;
int wrapperCount = SettingsUtil.GlobalSettings.ReversePInvokeWrapperCount;
var generator = new ReversePInvokeWrapperGenerator();
generator.Generate(wrapperTemplateStr, wrapperCount,ReversePInvokeWrapperStubFile);
Debug.Log($"GenerateReversePInvokeWrapper. wraperCount:{wrapperCount} output:{ReversePInvokeWrapperStubFile}");
MethodBridgeGeneratorCommand.CleanIl2CppBuildCache();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7db18e1736f593c4089c85d764cf8620
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

36
Editor/EqualityUtil.cs Normal file
View File

@ -0,0 +1,36 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HybridCLR.Editor
{
public static class EqualityUtil
{
public static bool EqualsTypeSigArray(List<TypeSig> a, List<TypeSig> b)
{
if (a == b)
{
return true;
}
if (a != null && b != null)
{
if (a.Count != b.Count)
{
return false;
}
for (int i = 0; i < a.Count; i++)
{
if (!TypeEqualityComparer.Instance.Equals(a[i], b[i]))
{
return false;
}
}
return true;
}
return false;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 103704591750908419902643015e920a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

28
Editor/HashUtil.cs Normal file
View File

@ -0,0 +1,28 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HybridCLR.Editor
{
public static class HashUtil
{
public static int CombineHash(int hash1, int hash2)
{
return hash1 * 1566083941 + hash2;
}
public static int ComputHash(List<TypeSig> sigs)
{
int hash = 135781321;
TypeEqualityComparer tc = TypeEqualityComparer.Instance;
foreach (var sig in sigs)
{
hash = hash * 1566083941 + tc.GetHashCode(sig);
}
return hash;
}
}
}

11
Editor/HashUtil.cs.meta Normal file
View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5d4ae4a5c0bba49469c525887d812717
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,18 @@
{
"name": "HybridCLR.Editor",
"rootNamespace": "",
"references": [
"UnityFS"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": true,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2373f786d14518f44b0f475db77ba4de
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,45 @@
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEditorInternal;
using UnityEngine;
[CreateAssetMenu(fileName = "HybridCLRGlobalSettings", menuName = "HybridCLR/GlobalSettings")]
public class HybridCLRGlobalSettings : ScriptableObject
{
[Header("开启HybridCLR插件")]
public bool enable = true;
[Header("从gitee clone插件代码")]
public bool cloneFromGitee = true; // false 则从github上拉取
[Header("热更新Assembly Definition Modules")]
public AssemblyDefinitionAsset[] hotUpdateAssemblyDefinitions;
[Header("热更新dlls")]
public string[] hotUpdateAssemblies;
[Header("自动扫描生成的link.xml路径")]
public string outputLinkFile = "HybridCLR/link.xml";
[Header("自动扫描生成的AOTGenericReferences.cs路径")]
public string outputAOTGenericReferenceFile = "Main/AOTGenericReferences.cs";
[Header("AOT泛型实例化搜索迭代次数")]
public int maxGenericReferenceIteration = 4;
[Header("预留MonoPInvokeCallbackAttribute函数个数")]
public int ReversePInvokeWrapperCount = 10;
[Header("MethodBridge泛型搜索迭代次数")]
public int maxMethodBridgeGenericIteration = 4;
[Header("热更新dll输出目录相对HybridCLRData目录")]
public string hotUpdateDllOutputDir = "HotUpdateDlls";
[Header("HybridCLRData目录相对工程目录")]
public string hybridCLRDataDir = "HybridCLRData";
[Header("裁剪后的AOT assembly输出目录")]
public string strippedAssemblyDir = "AssembliesPostIl2CppStrip";
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e189374413a3f00468e49d51d8b27a09
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

8
Editor/Installer.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a2c8f84b297371d4cbcd5ca655bf360d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,108 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HybridCLR.Editor.Installer
{
public static class BashUtil
{
public static int RunCommand(string workingDir, string program, string[] args)
{
using (Process p = new Process())
{
p.StartInfo.WorkingDirectory = workingDir;
p.StartInfo.FileName = program;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
string argsStr = string.Join(" ", args.Select(arg => "\"" + arg + "\""));
p.StartInfo.Arguments = argsStr;
UnityEngine.Debug.Log($"[BashUtil] run => {program} {argsStr}");
p.Start();
p.WaitForExit();
return p.ExitCode;
}
}
public static (int ExitCode, string StdOut, string StdErr) RunCommand2(string workingDir, string program, string[] args)
{
using (Process p = new Process())
{
p.StartInfo.WorkingDirectory = workingDir;
p.StartInfo.FileName = program;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
string argsStr = string.Join(" ", args.Select(arg => "\"" + arg + "\""));
p.StartInfo.Arguments = argsStr;
UnityEngine.Debug.Log($"[BashUtil] run => {program} {argsStr}");
p.Start();
p.WaitForExit();
string stdOut = p.StandardOutput.ReadToEnd();
string stdErr = p.StandardError.ReadToEnd();
return (p.ExitCode, stdOut, stdErr);
}
}
public static bool ExistProgram(string prog)
{
return RunCommand(".", "where", new string[] {prog}) == 0;
}
public static void RemoveDir(string dir, bool log = false)
{
if (log)
{
UnityEngine.Debug.Log($"[BashUtil] RemoveDir dir:{dir}");
}
if (!Directory.Exists(dir))
{
return;
}
foreach (var file in Directory.GetFiles(dir))
{
File.SetAttributes(file, FileAttributes.Normal);
File.Delete(file);
}
foreach (var subDir in Directory.GetDirectories(dir))
{
RemoveDir(subDir);
}
Directory.Delete(dir);
}
public static void RecreateDir(string dir)
{
if(Directory.Exists(dir))
{
RemoveDir(dir, true);
}
Directory.CreateDirectory(dir);
}
public static void CopyDir(string src, string dst, bool log = false)
{
if (log)
{
UnityEngine.Debug.Log($"[BashUtil] CopyDir {src} => {dst}");
}
RemoveDir(dst);
Directory.CreateDirectory(dst);
foreach(var file in Directory.GetFiles(src))
{
File.Copy(file, $"{dst}/{Path.GetFileName(file)}");
}
foreach(var subDir in Directory.GetDirectories(src))
{
CopyDir(subDir, $"{dst}/{Path.GetFileName(subDir)}");
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 960a0257c3a17f64b810193308ce1558
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,373 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Diagnostics;
using Debug = UnityEngine.Debug;
using System.Text.RegularExpressions;
namespace HybridCLR.Editor.Installer
{
public enum InstallErrorCode
{
Ok,
Il2CppInstallPathNotMatchIl2CppBranch,
Il2CppInstallPathNotExists,
NotIl2CppPath,
}
public partial class InstallerController
{
private string m_Il2CppInstallDirectory;
public string Il2CppInstallDirectory
{
get
{
return m_Il2CppInstallDirectory;
}
set
{
m_Il2CppInstallDirectory = value?.Replace('\\', '/');
if (!string.IsNullOrEmpty(m_Il2CppInstallDirectory))
{
EditorPrefs.SetString("UnityInstallDirectory", m_Il2CppInstallDirectory);
}
}
}
private string GetIl2CppPlusBranchByUnityVersion(string unityVersion)
{
if (unityVersion.Contains("2019."))
{
return "2019.4.40";
}
if (unityVersion.Contains("2020."))
{
return "2020.3.33";
}
if (unityVersion.Contains("2021."))
{
return "2021.3.1";
}
return "not support";
}
public string Il2CppBranch => GetIl2CppPlusBranchByUnityVersion(Application.unityVersion);
public string InitLocalIl2CppBatFile => Application.dataPath + "/../HybridCLRData/init_local_il2cpp_data.bat";
public string InitLocalIl2CppBashFile => Application.dataPath + "/../HybridCLRData/init_local_il2cpp_data.sh";
public InstallerController()
{
PrepareIl2CppInstallPath();
}
private static readonly Regex s_unityVersionPat = new Regex(@"(\d+)\.(\d+)\.(\d+)");
public const int min2019_4_CompatibleMinorVersion = 40;
public const int min2020_3_CompatibleMinorVersion = 21;
public const int min2021_3_CompatibleMinorVersion = 0;
private bool TryParseMinorVersion(string installDir, out (int Major, int Minor1, int Minor2) unityVersion)
{
var matches = s_unityVersionPat.Matches(installDir);
if (matches.Count == 0)
{
unityVersion = default;
return false;
}
// 找最后一个匹配的有的人居然会把Unity安装目录放到其他安装版本下。无语
Match match = matches[matches.Count - 1];
// Debug.Log($"capture count:{match.Groups.Count} {match.Groups[1].Value} {match.Groups[2].Value}");
int major = int.Parse(match.Groups[1].Value);
int minor1 = int.Parse(match.Groups[2].Value);
int minor2 = int.Parse(match.Groups[3].Value);
unityVersion = (major, minor1, minor2);
return true;
}
public string GetCurVersionStr(string installDir)
{
if (TryParseMinorVersion(installDir, out var version))
{
return $"{version.Major}.{version.Minor1}.{version.Minor2}";
}
throw new Exception($"not support version:{installDir}");
}
public string GetMinCompatibleVersion(string branch)
{
switch(branch)
{
case "2019.4.40": return $"2019.4.{min2019_4_CompatibleMinorVersion}";
case "2020.3.33": return $"2020.3.{min2020_3_CompatibleMinorVersion}";
case "2021.3.1": return $"2021.3.{min2021_3_CompatibleMinorVersion}";
default: throw new Exception($"not support version:{branch}");
}
}
private bool IsComaptibleWithIl2CppPlusBranch(string branch, string installDir)
{
if (!TryParseMinorVersion(installDir, out var unityVersion))
{
return false;
}
switch(branch)
{
case "2019.4.40":
{
if (unityVersion.Major != 2019 || unityVersion.Minor1 != 4)
{
return false;
}
return unityVersion.Minor2 >= min2019_4_CompatibleMinorVersion;
}
case "2020.3.33":
{
if (unityVersion.Major != 2020 || unityVersion.Minor1 != 3)
{
return false;
}
return unityVersion.Minor2 >= min2020_3_CompatibleMinorVersion;
}
case "2021.3.1":
{
if (unityVersion.Major != 2021 || unityVersion.Minor1 != 3)
{
return false;
}
return unityVersion.Minor2 >= min2021_3_CompatibleMinorVersion;
}
default: throw new Exception($"not support il2cpp_plus branch:{branch}");
}
}
void PrepareIl2CppInstallPath()
{
#if UNITY_EDITOR_WIN
m_Il2CppInstallDirectory = EditorPrefs.GetString("Il2CppInstallDirectory");
if (CheckValidIl2CppInstallDirectory(Il2CppBranch, m_Il2CppInstallDirectory) == InstallErrorCode.Ok)
{
return;
}
var il2cppBranch = Il2CppBranch;
var curAppInstallPath = EditorApplication.applicationPath;
if (IsComaptibleWithIl2CppPlusBranch(il2cppBranch, curAppInstallPath))
{
Il2CppInstallDirectory = $"{Directory.GetParent(curAppInstallPath)}/Data/il2cpp";
return;
}
string unityHubRootDir = Directory.GetParent(curAppInstallPath).Parent.Parent.ToString();
// Debug.Log("unity hub root dir:" + unityHubRootDir);
foreach (var unityInstallDir in Directory.GetDirectories(unityHubRootDir, "*", SearchOption.TopDirectoryOnly))
{
// Debug.Log("Unity install dir:" + unityInstallDir);
if (IsComaptibleWithIl2CppPlusBranch(il2cppBranch, unityInstallDir))
{
Il2CppInstallDirectory = $"{unityInstallDir}/Editor/Data/il2cpp";
return;
}
}
Il2CppInstallDirectory = $"{Directory.GetParent(curAppInstallPath)}/Data/il2cpp";
#else
m_Il2CppInstallDirectory = EditorPrefs.GetString("Il2CppInstallDirectory");
if (CheckValidIl2CppInstallDirectory(Il2CppBranch, m_Il2CppInstallDirectory) == InstallErrorCode.Ok)
{
return;
}
var il2cppBranch = Il2CppBranch;
var curAppInstallPath = EditorApplication.applicationPath;
if (IsComaptibleWithIl2CppPlusBranch(il2cppBranch, curAppInstallPath))
{
Il2CppInstallDirectory = $"{curAppInstallPath}/Contents/il2cpp";
return;
}
string unityHubRootDir = Directory.GetParent(curAppInstallPath).Parent.Parent.ToString();
foreach (var unityInstallDir in Directory.GetDirectories(unityHubRootDir, "*", SearchOption.TopDirectoryOnly))
{
Debug.Log("nity install dir:" + unityInstallDir);
if (IsComaptibleWithIl2CppPlusBranch(il2cppBranch, unityInstallDir))
{
Il2CppInstallDirectory = $"{unityInstallDir}/Unity.app/Contents/il2cpp";
return;
}
}
Il2CppInstallDirectory = $"{curAppInstallPath}/Contents/il2cpp";
#endif
}
public void InitHybridCLR(string il2cppBranch, string il2cppInstallPath)
{
if (CheckValidIl2CppInstallDirectory(il2cppBranch, il2cppInstallPath) != InstallErrorCode.Ok)
{
Debug.LogError($"请正确设置 il2cpp 安装目录");
return;
}
RunInitLocalIl2CppData(il2cppBranch, il2cppInstallPath);
}
public bool HasInstalledHybridCLR()
{
return Directory.Exists($"{SettingsUtil.LocalIl2CppDir}/libil2cpp/hybridclr");
}
public InstallErrorCode CheckValidIl2CppInstallDirectory(string il2cppBranch, string installDir)
{
installDir = installDir.Replace('\\', '/');
if (!Directory.Exists(installDir))
{
return InstallErrorCode.Il2CppInstallPathNotExists;
}
if (!IsComaptibleWithIl2CppPlusBranch(il2cppBranch, installDir))
{
return InstallErrorCode.Il2CppInstallPathNotMatchIl2CppBranch;
}
if (!installDir.EndsWith("/il2cpp"))
{
return InstallErrorCode.NotIl2CppPath;
}
return InstallErrorCode.Ok;
}
public bool IsUnity2019(string branch)
{
return branch.Contains("2019.");
}
private string GetUnityIl2CppDllInstallLocation()
{
#if UNITY_EDITOR_WIN
return $"{SettingsUtil.LocalIl2CppDir}/build/deploy/net471/Unity.IL2CPP.dll";
#else
return $"{SettingsUtil.LocalIl2CppDir}/build/deploy/il2cppcore/Unity.IL2CPP.dll";
#endif
}
private string GetUnityIl2CppDllModifiedPath(string curVersionStr)
{
#if UNITY_EDITOR_WIN
return $"{SettingsUtil.ProjectDir}/{SettingsUtil.HybridCLRDataPathInPackage}/ModifiedUnityAssemblies/{curVersionStr}/Unity.IL2CPP-Win.dll.bytes";
#else
return $"{SettingsUtil.ProjectDir}/{SettingsUtil.HybridCLRDataPathInPackage}/ModifiedUnityAssemblies/{curVersionStr}/Unity.IL2CPP-Mac.dll.bytes";
#endif
}
private static string GetRepoUrl(string repoName)
{
string repoProvider = SettingsUtil.GlobalSettings.cloneFromGitee ? "gitee" : "github";
return $"https://{repoProvider}.com/focus-creative-games/{repoName}";
}
private void RunInitLocalIl2CppData(string il2cppBranch, string il2cppInstallPath)
{
#if UNITY_EDITOR_WIN
if (!BashUtil.ExistProgram("git"))
{
throw new Exception($"安装本地il2cpp需要使用git从远程拉取仓库请先安装git");
}
#endif
string workDir = SettingsUtil.HybridCLRDataDir;
Directory.CreateDirectory(workDir);
//BashUtil.RecreateDir(workDir);
string buildiOSDir = $"{workDir}/iOSBuild";
BashUtil.RemoveDir(buildiOSDir);
BashUtil.CopyDir($"{SettingsUtil.HybridCLRDataPathInPackage}/iOSBuild", buildiOSDir, true);
// clone hybridclr
string hybridclrRepoDir = $"{workDir}/hybridclr_repo";
{
BashUtil.RemoveDir(hybridclrRepoDir);
var ret = BashUtil.RunCommand(workDir, "git", new string[]
{
"clone",
"--depth=1",
GetRepoUrl("hybridclr"),
hybridclrRepoDir,
});
//if (ret != 0)
//{
// throw new Exception($"git clone 失败");
//}
}
// clone il2cpp_plus
string il2cppPlusRepoDir = $"{workDir}/il2cpp_plus_repo";
{
BashUtil.RemoveDir(il2cppPlusRepoDir);
var ret = BashUtil.RunCommand(workDir, "git", new string[]
{
"clone",
"--depth=1",
"-b",
il2cppBranch,
GetRepoUrl("il2cpp_plus"),
il2cppPlusRepoDir,
});
//if (ret != 0)
//{
// throw new Exception($"git clone 失败");
//}
}
// create LocalIl2Cpp
string localUnityDataDir = SettingsUtil.LocalUnityDataDir;
BashUtil.RecreateDir(localUnityDataDir);
// copy MonoBleedingEdge
BashUtil.CopyDir($"{Directory.GetParent(il2cppInstallPath)}/MonoBleedingEdge", $"{localUnityDataDir}/MonoBleedingEdge", true);
// copy il2cpp
BashUtil.CopyDir(Il2CppInstallDirectory, SettingsUtil.LocalIl2CppDir, true);
// replace libil2cpp
string dstLibil2cppDir = $"{SettingsUtil.LocalIl2CppDir}/libil2cpp";
BashUtil.CopyDir($"{il2cppPlusRepoDir}/libil2cpp", dstLibil2cppDir, true);
BashUtil.CopyDir($"{hybridclrRepoDir}/hybridclr", $"{dstLibil2cppDir}/hybridclr", true);
// clean Il2cppBuildCache
BashUtil.RemoveDir($"{SettingsUtil.ProjectDir}/Library/Il2cppBuildCache", true);
if (IsUnity2019(il2cppBranch))
{
string curVersionStr = GetCurVersionStr(il2cppInstallPath);
string srcIl2CppDll = GetUnityIl2CppDllModifiedPath(curVersionStr);
if (File.Exists(srcIl2CppDll))
{
string dstIl2CppDll = GetUnityIl2CppDllInstallLocation();
File.Copy(srcIl2CppDll, dstIl2CppDll, true);
Debug.Log($"copy {srcIl2CppDll} => {dstIl2CppDll}");
}
else
{
Debug.LogError($"未找到当前版本:{curVersionStr} 对应的改造过的 Unity.IL2CPP.dll打包出的程序将会崩溃");
}
}
if (HasInstalledHybridCLR())
{
Debug.Log("安装成功!");
}
else
{
Debug.LogError("安装失败!");
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 44c8627d126b30d4e9560b1f738264ca
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEditor ;
using UnityEngine;
namespace HybridCLR.Editor.Installer
{
public class InstallerWindow : EditorWindow
{
private InstallerController m_Controller;
[MenuItem("HybridCLR/Installer...", false, 0)]
private static void Open()
{
InstallerWindow window = GetWindow<InstallerWindow>("HybridCLR Installer", true);
window.minSize = new Vector2(800f, 500f);
}
private void OnEnable()
{
m_Controller = new InstallerController();
}
private void OnGUI()
{
string minCompatibleVersion = m_Controller.GetMinCompatibleVersion(m_Controller.Il2CppBranch);
GUI.enabled = true;
GUILayout.Space(10f);
EditorGUILayout.LabelField("=======================说明====================");
EditorGUILayout.LabelField(
$"你所在项目的Unity版本可以与il2cpp_plus版本:{m_Controller.Il2CppBranch} 不一样。\n"
+ $"如果你的Unity的版本号 >= {minCompatibleVersion}, 可以直接安装。\n"
+ $"如果你的Unity的版本号 < {minCompatibleVersion}, \n"
+ $"由于安装HybridCLR时需要从il2cpp_plus对应版本{m_Controller.Il2CppBranch}而不是你项目版本拷贝il2cpp目录\n"
+ $"你必须同时安装相应版本 {m_Controller.Il2CppBranch} 才能完成安装", EditorStyles.wordWrappedLabel);
EditorGUILayout.LabelField("==============================================");
GUILayout.Space(10f);
EditorGUILayout.BeginVertical("box");
EditorGUILayout.LabelField($"安装状态:{(m_Controller.HasInstalledHybridCLR() ? "" : "")}", EditorStyles.boldLabel);
GUILayout.Space(5f);
EditorGUILayout.LabelField($"当前Unity版本: {Application.unityVersion}匹配的il2cpp_plus分支: {m_Controller.Il2CppBranch}");
GUISelectUnityDirectory($"il2cpp_plus分支对应Unity版本的il2cpp路径", "Select");
GUILayout.Space(10f);
GUIInstallButton("安装最新HybridCLR插件代码到本项目", "安装", InitHybridCLR);
EditorGUILayout.EndVertical();
}
private void GUIInstallButton(string content, string button, Action onClick)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(content);
GUI.enabled = m_Controller.CheckValidIl2CppInstallDirectory(m_Controller.Il2CppBranch, m_Controller.Il2CppInstallDirectory) == InstallErrorCode.Ok;
if (GUILayout.Button(button, GUILayout.Width(100)))
{
onClick?.Invoke();
GUIUtility.ExitGUI();
}
GUI.enabled = true;
EditorGUILayout.EndHorizontal();
}
private void GUISelectUnityDirectory(string content, string selectButton)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(content, GUILayout.MaxWidth(300));
string il2cppInstallDirectory = m_Controller.Il2CppInstallDirectory = EditorGUILayout.TextField(m_Controller.Il2CppInstallDirectory);
if (GUILayout.Button(selectButton, GUILayout.Width(100)))
{
string temp = EditorUtility.OpenFolderPanel(content, m_Controller.Il2CppInstallDirectory, string.Empty);
if (!string.IsNullOrEmpty(temp))
{
il2cppInstallDirectory = m_Controller.Il2CppInstallDirectory = temp;
}
}
EditorGUILayout.EndHorizontal();
InstallErrorCode err = m_Controller.CheckValidIl2CppInstallDirectory(m_Controller.Il2CppBranch, il2cppInstallDirectory);
switch (err)
{
case InstallErrorCode.Ok:
{
break;
}
case InstallErrorCode.Il2CppInstallPathNotExists:
{
EditorGUILayout.HelpBox("li2cpp 路径不存在", MessageType.Error);
break;
}
case InstallErrorCode.Il2CppInstallPathNotMatchIl2CppBranch:
{
EditorGUILayout.HelpBox($"il2cpp 版本不兼容,最小版本为 {m_Controller.GetMinCompatibleVersion(m_Controller.Il2CppBranch)}", MessageType.Error);
break;
}
case InstallErrorCode.NotIl2CppPath:
{
EditorGUILayout.HelpBox($"当前选择的路径不是il2cpp目录必须类似 xxx/il2cpp", MessageType.Error);
break;
}
default: throw new Exception($"not support {err}");
}
}
private void InitHybridCLR()
{
m_Controller.InitHybridCLR(m_Controller.Il2CppBranch, m_Controller.Il2CppInstallDirectory);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 959fbf0bb06629542969354505189240
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5186a137e0258034cb3832bdf6b16a70
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using dnlib.DotNet;
using HybridCLR.Editor.Meta;
using IAssemblyResolver = HybridCLR.Editor.Meta.IAssemblyResolver;
namespace HybridCLR.Editor.LinkGenerator
{
class Analyzer
{
private readonly IAssemblyResolver _resolver;
public Analyzer(IAssemblyResolver resolver)
{
_resolver = resolver;
}
public HashSet<TypeRef> CollectRefs(List<Assembly> rootAssemblies)
{
var assCollector = new AssemblyCache(_resolver);
var rootAssemblyName = new HashSet<string>();
foreach(var ass in rootAssemblies)
{
if (!rootAssemblyName.Add(ass.GetName().Name))
{
throw new Exception($"assembly:{ass.GetName().Name} 重复");
}
}
var typeRefs = new HashSet<TypeRef>(TypeEqualityComparer.Instance);
foreach (var rootAss in rootAssemblies)
{
var dnAss = assCollector.LoadModule(rootAss.GetName().Name);
foreach(var type in dnAss.GetTypeRefs())
{
if (!rootAssemblyName.Contains(type.DefinitionAssembly.Name))
{
typeRefs.Add(type);
}
}
}
return typeRefs;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fd3dd4871efd10e46947cb61c13797fd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,47 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace HybridCLR.Editor.LinkGenerator
{
internal class LinkXmlWriter
{
public void Write(string outputLinkXmlFile, HashSet<TypeRef> refTypes)
{
string parentDir = Directory.GetParent(outputLinkXmlFile).FullName;
Directory.CreateDirectory(parentDir);
var writer = System.Xml.XmlWriter.Create(outputLinkXmlFile,
new System.Xml.XmlWriterSettings { Encoding = Encoding.UTF8, Indent = true});
writer.WriteStartDocument();
writer.WriteStartElement("linker");
var typesByAssembly = refTypes.GroupBy(t => t.DefinitionAssembly.Name.String).ToList();
typesByAssembly.Sort((a, b) => a.Key.CompareTo(b.Key));
foreach(var assembly in typesByAssembly)
{
writer.WriteStartElement("assembly");
writer.WriteAttributeString("fullname", assembly.Key);
List<TypeRef> assTypes = assembly.ToList();
assTypes.Sort((a, b) => a.FullName.CompareTo(b.FullName));
foreach(var type in assTypes)
{
writer.WriteStartElement("type");
writer.WriteAttributeString("fullname", type.FullName);
writer.WriteAttributeString("preserve", "all");
writer.WriteEndElement();
}
writer.WriteEndElement();
}
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Close();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d5cc4ae4adc319b4bb1e115567d7613e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

8
Editor/Meta.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3787c7d8b775c754aa4ae06bf78e96ea
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,55 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace HybridCLR.Editor.Meta
{
public class AssemblyCache
{
private readonly IAssemblyResolver _assemblyPathResolver;
private readonly ModuleContext _modCtx;
private readonly AssemblyResolver _asmResolver;
public Dictionary<string, ModuleDefMD> LoadedModules { get; } = new Dictionary<string, ModuleDefMD>();
public AssemblyCache(IAssemblyResolver assemblyResolver)
{
_assemblyPathResolver = assemblyResolver;
_modCtx = ModuleDef.CreateModuleContext();
_asmResolver = (AssemblyResolver)_modCtx.AssemblyResolver;
_asmResolver.EnableTypeDefCache = true;
_asmResolver.UseGAC = false;
}
public ModuleDefMD LoadModule(string moduleName)
{
// Debug.Log($"load module:{moduleName}");
if (LoadedModules.TryGetValue(moduleName, out var mod))
{
return mod;
}
mod = DoLoadModule(_assemblyPathResolver.ResolveAssembly(moduleName, true));
LoadedModules.Add(moduleName, mod);
foreach (var refAsm in mod.GetAssemblyRefs())
{
LoadModule(refAsm.Name);
}
return mod;
}
private ModuleDefMD DoLoadModule(string dllPath)
{
//Debug.Log($"do load module:{dllPath}");
ModuleDefMD mod = ModuleDefMD.Load(dllPath, _modCtx);
_asmResolver.AddToCache(mod);
return mod;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fa4650e79a52228488aa85e0690ca52c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,82 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace HybridCLR.Editor.Meta
{
public class AssemblyReferenceDeepCollector
{
private readonly IAssemblyResolver _assemblyPathResolver;
private readonly List<string> _rootAssemblies;
private readonly ModuleContext _modCtx;
private readonly AssemblyResolver _asmResolver;
public Dictionary<string, ModuleDefMD> LoadedModules { get; } = new Dictionary<string, ModuleDefMD>();
public IReadOnlyList<string> GetRootAssemblyNames()
{
return _rootAssemblies;
}
public List<ModuleDefMD> GetLoadedModulesExcludeRootAssemblies()
{
return LoadedModules.Where(e => !_rootAssemblies.Contains(e.Key)).Select(e => e.Value).ToList();
}
public List<ModuleDefMD> GetLoadedModulesOfRootAssemblies()
{
return _rootAssemblies.Select(ass => LoadedModules[ass]).ToList();
}
public AssemblyReferenceDeepCollector(IAssemblyResolver assemblyResolver, List<string> rootAssemblies)
{
_assemblyPathResolver = assemblyResolver;
_rootAssemblies = rootAssemblies;
_modCtx = ModuleDef.CreateModuleContext();
_asmResolver = (AssemblyResolver)_modCtx.AssemblyResolver;
_asmResolver.EnableTypeDefCache = true;
_asmResolver.UseGAC = false;
LoadAllAssembiles();
}
private void LoadAllAssembiles()
{
foreach (var asm in _rootAssemblies)
{
LoadModule(asm);
}
}
private ModuleDefMD LoadModule(string moduleName)
{
// Debug.Log($"load module:{moduleName}");
if (LoadedModules.TryGetValue(moduleName, out var mod))
{
return mod;
}
mod = DoLoadModule(_assemblyPathResolver.ResolveAssembly(moduleName, true));
LoadedModules.Add(moduleName, mod);
foreach (var refAsm in mod.GetAssemblyRefs())
{
LoadModule(refAsm.Name);
}
return mod;
}
private ModuleDefMD DoLoadModule(string dllPath)
{
//Debug.Log($"do load module:{dllPath}");
ModuleDefMD mod = ModuleDefMD.Load(dllPath, _modCtx);
_asmResolver.AddToCache(mod);
return mod;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0342c7d8575fdea49896260c77285286
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HybridCLR.Editor.Meta
{
public class CombinedAssemblyResolver : IAssemblyResolver
{
private readonly IAssemblyResolver[] _resolvers;
public CombinedAssemblyResolver(params IAssemblyResolver[] resolvers)
{
_resolvers = resolvers;
}
public string ResolveAssembly(string assemblyName, bool throwExIfNotFind)
{
foreach(var resolver in _resolvers)
{
var assembly = resolver.ResolveAssembly(assemblyName, false);
if (assembly != null)
{
return assembly;
}
}
if (throwExIfNotFind)
{
throw new Exception($"resolve assembly:{assemblyName} fail");
}
return null;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 89b83906438c52d4b9af4aaef055f177
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,103 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HybridCLR.Editor.Meta
{
/// <summary>
/// Replaces generic type/method var with its generic argument
/// </summary>
public sealed class GenericArgumentContext
{
List<TypeSig> typeArgsStack = new List<TypeSig>();
List<TypeSig> methodArgsStack = new List<TypeSig>();
public GenericArgumentContext(List<TypeSig> typeArgsStack, List<TypeSig> methodArgsStack)
{
this.typeArgsStack = typeArgsStack;
this.methodArgsStack = methodArgsStack;
}
/// <summary>
/// Replaces a generic type/method var with its generic argument (if any). If
/// <paramref name="typeSig"/> isn't a generic type/method var or if it can't
/// be resolved, it itself is returned. Else the resolved type is returned.
/// </summary>
/// <param name="typeSig">Type signature</param>
/// <returns>New <see cref="TypeSig"/> which is never <c>null</c> unless
/// <paramref name="typeSig"/> is <c>null</c></returns>
public TypeSig Resolve(TypeSig typeSig)
{
if (!typeSig.ContainsGenericParameter)
{
return typeSig;
}
switch (typeSig.ElementType)
{
case ElementType.Ptr: return new PtrSig(Resolve(typeSig.Next));
case ElementType.ByRef: return new PtrSig(Resolve(typeSig.Next));
case ElementType.SZArray: return new PtrSig(Resolve(typeSig.Next));
case ElementType.Array:
{
var ara = (ArraySig)typeSig;
return new ArraySig(Resolve(typeSig.Next), ara.Rank, ara.Sizes, ara.LowerBounds);
}
case ElementType.Var:
{
GenericVar genericVar = (GenericVar)typeSig;
var newSig = Resolve(typeArgsStack, genericVar.Number, true);
if (newSig == null)
{
throw new Exception();
}
return newSig;
}
case ElementType.MVar:
{
GenericMVar genericVar = (GenericMVar)typeSig;
var newSig = Resolve(methodArgsStack, genericVar.Number, true);
if (newSig is null)
{
throw new Exception();
}
return newSig;
}
case ElementType.GenericInst:
{
var gia = (GenericInstSig)typeSig;
return new GenericInstSig(gia.GenericType, gia.GenericArguments.Select(ga => Resolve(ga)).ToList());
}
case ElementType.FnPtr:
{
throw new NotSupportedException(typeSig.ToString());
}
case ElementType.ValueArray:
{
var vas = (ValueArraySig)typeSig;
return new ValueArraySig(Resolve(vas.Next), vas.Size);
}
default: return typeSig;
}
}
private TypeSig Resolve(List<TypeSig> args, uint number, bool isTypeVar)
{
var typeSig = args[(int)number];
var gvar = typeSig as GenericSig;
if (gvar is null || gvar.IsTypeVar != isTypeVar)
return typeSig;
return gvar;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 07595a9b5b2f54c44a67022ae3e077d4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More