数据源
研究平台是Mac。用Mac来打包的好处是一个平台能打出两种经常使用的平台包:Android和iOS。
首先定位Unity的PID。打开Unity工程执行ps aux | grep Unity第2列就是PID。假设本次的PID是45731
编写如下脚本。以45731为参数调用这个脚本,在开始编译时执行,编译结束结束脚本执行。
pid=$1
echo "">`echo ${pid}.txt`
while true;do
pstree -p `echo $pid`>>`echo ${pid}.txt`
sleep 0.1
done
生成的中间文件为45731.txt。再执行cat 45731.txt | sort -r | uniq>target.txt。这命令排除重复的条目。target.txt就是研究目标。根据编译的平台不同,内部的处理流程有很大的差异。
Android
Unity使用多进程来编译着色器。输出到不同log文件
/Applications/Unity/Unity.app/Contents/Tools/UnityShaderCompiler /Applications/Unity/Unity.app/Contents ./Library/shadercompiler-UnityShaderCompiler0.log 59710 /Applications/Unity/PlaybackEngines 其他的输出到UnityShaderCompiler{1-7}.log中去
Unity使用了开源的Rosly编译器来编译C#代码
/Applications/Unity/Unity.app/Contents/Tools/Roslyn/csc /noconfig /shared @Temp/UnityTempFile-aa7e87a1171084f5684a02bff6c8a917
用.net工具把C#代码编译为cpp
/Applications/Unity/Unity.app/Contents/NetCore/Sdk/dotnet /Applications/Unity/Unity.app/Contents/il2cpp/build/il2cppcore/il2cppcore.dll --convert-to-cpp --emit-null-checks --enable-array-bounds-check --dotnetprofile=unityaot --enable-debugger --compile-cpp --libil2cpp-static --platform=Android --architecture=ARMv7 --configuration=Release --outputpath={PROJECT}/Temp/StagingArea/assets/bin/Data/Native/armeabi-v7a/libil2cpp.so --cachedirectory={PROJECT}/Assets/../Library/il2cpp_android_armeabi-v7a/il2cpp_cache --additional-include-directories=/Applications/Unity/PlaybackEngines/AndroidPlayer/Tools/bdwgc/include --additional-include-directories=/Applications/Unity/PlaybackEngines/AndroidPlayer/Tools/libil2cpp/include --tool-chain-path=/Volumes/Samsung_T5/share/android-ndk-r16b --map-file-parser=/Applications/Unity/Unity.app/Contents/Tools/MapFileParser/MapFileParser --directory={PROJECT}/Temp/StagingArea/assets/bin/Data/Managed --generatedcppdir={PROJECT}/Temp/StagingArea/Il2Cpp/il2cppOutput
以及这个:
/Applications/Unity/Unity.app/Contents/NetCore/Sdk/dotnet /Applications/Unity/Unity.app/Contents/il2cpp/build/il2cppcore/il2cppcore.dll --compile-cpp --libil2cpp-static --platform=Android --architecture=x86 --configuration=Release --outputpath={PROJECT}/Temp/StagingArea/assets/bin/Data/Native/x86/libil2cpp.so --cachedirectory={PROJECT}/Assets/../Library/il2cpp_android_x86/il2cpp_cache --additional-include-directories=/Applications/Unity/PlaybackEngines/AndroidPlayer/Tools/bdwgc/include --additional-include-directories=/Applications/Unity/PlaybackEngines/AndroidPlayer/Tools/libil2cpp/include --tool-chain-path=/Volumes/Samsung_T5/share/android-ndk-r16b --map-file-parser=/Applications/Unity/Unity.app/Contents/Tools/MapFileParser/MapFileParser --generatedcppdir={PROJECT}/Temp/StagingArea/Il2Cpp/il2cppOutput --dotnetprofile=unityaot --enable-debugger
编译单个cpp是如下方式
/Volumes/Samsung_T5/share/android-ndk-r16b/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ -cc1 -triple armv7-none-linux-android -emit-obj -disable-free -disable-llvm-verifier -discard-value-names -main-file-name UnityICallRegistration.cpp -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu cortex-a8 -target-feature +soft-float-abi -target-feature -fp-only-sp -target-feature -d16 -target-feature +vfp3 -target-feature +fp16 -target-feature -vfp4 -target-feature -fp-armv8 -target-feature +neon -target-feature -crypto -target-abi aapcs-linux -mfloat-abi soft -target-linker-version 2.24 -dwarf-column-info -debug-info-kind=limited -dwarf-version=4 -debugger-tuning=gdb -ffunction-sections -fdata-sections -coverage-notes-file {PROJECT}/Temp/StagingArea/strip/armeabi-v7a/UnityICallRegistration.gcno -resource-dir /Volumes/Samsung_T5/share/android-ndk-r16b/toolchains/llvm/prebuilt/darwin-x86_64/lib64/clang/5.0.300080 -D __ARM_ARCH_7__ -D __ARM_ARCH_7A__ -D __ANDROID_API__=16 -D ANDROID -D HAVE_INTTYPES_H -D DEBUGGER_FIXED_PORT=56000 -D ENABLE_ALTERNATIVE_LISTEN_PORT=0 -D ENABLE_AUDIO=1 -D ENABLE_CACHING=1 -isysroot /Volumes/Samsung_T5/share/android-ndk-r16b/sysroot -internal-isystem /Volumes/Samsung_T5/share/android-ndk-r16b/sysroot/usr/local/include -internal-isystem /Volumes/Samsung_T5/share/android-ndk-r16b/toolchains/llvm/prebuilt/darwin-x86_64/lib64/clang/5.0.300080/include -internal-externc-isystem /Volumes/Samsung_T5/share/android-ndk-r16b/sysroot/include -internal-externc-isystem /Volumes/Samsung_T5/share/android-ndk-r16b/sysroot/usr/include -Os -Wno-missing-braces -std=c++11 -fdeprecated-macro -fdebug-compilation-dir {PROJECT} -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -femulated-tls -stack-protector 1 -fallow-half-arguments-and-returns -fno-rtti -fno-signed-char -fobjc-runtime=gcc -fdiagnostics-show-option -fdiagnostics-format msvc -fcolor-diagnostics -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -o Temp/StagingArea/strip/armeabi-v7a/UnityICallRegistration.o -x c++ Temp/StagingArea/Il2Cpp/Managed/UnityICallRegistration.cpp
省略了大量的编译选项参数。比较有意思的是使用的并不是gcc而是llvm+clang【安卓官方早就在推广这种编译方式了】
/Volumes/Samsung_T5/share/android-ndk-r16b/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ -cc1 -triple aarch64-none-linux-android -emit-obj -mnoexecstack -disable-free -disable-llvm-verifier -discard-value-names -main-file-name Il2CppAttributes.cpp -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -relaxed-aliasing -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu generic -target-feature +neon -target-abi aapcs -backend-option -aarch64-fix-cortex-a53-835769=1 -target-linker-version 2.24 -dwarf-column-info -debug-info-kind=standalone -dwarf-version=4 -debugger-tuning=gdb -ffunction-sections -fdata-sections -coverage-notes-file {PROJECT}/Library/il2cpp_android_arm64-v8a/il2cpp_cache/9B156A0E401CF3C2B107FC44A9AE730C.gcno -resource-dir /Volumes/Samsung_T5/share/android-ndk-r16b/toolchains/llvm/prebuilt/darwin-x86_64/lib64/clang/5.0.300080 -isystem /Volumes/Samsung_T5/share/android-ndk-r16b/sysroot/usr/include/aarch64-linux-android -D NET_4_0 -D UNITY_AOT -D IL2CPP_MONO_DEBUGGER=1 -D IL2CPP_DEBUGGER_PORT=56000 -D GC_NOT_DLL -D RUNTIME_IL2CPP -D LINUX -D ANDROID -D PLATFORM_ANDROID -D __linux__ -D __STDC_FORMAT_MACROS -D TARGET_ARM64 -I /Applications/Unity/PlaybackEngines/AndroidPlayer/Tools/bdwgc/include -I /Applications/Unity/PlaybackEngines/AndroidPlayer/Tools/libil2cpp/include -I /Applications/Unity/Unity.app/Contents/il2cpp/libil2cpp -I /Applications/Unity/Unity.app/Contents/il2cpp/external/boehmgc/include -I {PROJECT}/Temp/StagingArea/Il2Cpp/il2cppOutput -I . -I /Volumes/Samsung_T5/share/android-ndk-r16b/sources/cxx-stl/gnu-libstdc++/4.9/include -I /Volumes/Samsung_T5/share/android-ndk-r16b/sources/cxx-stl/gnu-libstdc++/4.9/include/backward -I /Volumes/Samsung_T5/share/android-ndk-r16b/sources/cxx-stl/gnu-libstdc++/4.9/libs/arm64-v8a/include -D NDEBUG -D __ANDROID_API__=21 -isysroot /Volumes/Samsung_T5/share/android-ndk-r16b/sysroot -internal-isystem /Volumes/Samsung_T5/share/android-ndk-r16b/sysroot/usr/local/include -internal-isystem /Volumes/Samsung_T5/share/android-ndk-r16b/toolchains/llvm/prebuilt/darwin-x86_64/lib64/clang/5.0.300080/include -internal-externc-isystem /Volumes/Samsung_T5/share/android-ndk-r16b/sysroot/include -internal-externc-isystem /Volumes/Samsung_T5/share/android-ndk-r16b/sysroot/usr/include -Os -Wno-unused-value -std=c++98 -fdeprecated-macro -fdebug-compilation-dir {PROJECT}/Temp/StagingArea/assets/bin/Data/Managed -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -fvisibility-inlines-hidden -femulated-tls -fwrapv -fallow-half-arguments-and-returns -fno-rtti -fno-signed-char -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -vectorize-loops -vectorize-slp -o {PROJECT}/Library/il2cpp_android_arm64-v8a/il2cpp_cache/9B156A0E401CF3C2B107FC44A9AE730C.o -x c++ {PROJECT}/Temp/StagingArea/Il2Cpp/il2cppOutput/Il2CppAttributes.cpp
接下来是链接
/Applications/Unity/Unity.app/Contents/NetCore/Sdk/dotnet /Applications/Unity/Unity.app/Contents/il2cpp/build/il2cppcore/il2cppcore.dll --compile-cpp --libil2cpp-static --platform=Android --architecture=x86 --configuration=Release --outputpath={PROJECT}/Temp/StagingArea/assets/bin/Data/Native/x86/libil2cpp.so --cachedirectory={PROJECT}/Assets/../Library/il2cpp_android_x86/il2cpp_cache --additional-include-directories=/Applications/Unity/PlaybackEngines/AndroidPlayer/Tools/bdwgc/include --additional-include-directories=/Applications/Unity/PlaybackEngines/AndroidPlayer/Tools/libil2cpp/include --tool-chain-path=/Volumes/Samsung_T5/share/android-ndk-r16b --map-file-parser=/Applications/Unity/Unity.app/Contents/Tools/MapFileParser/MapFileParser --generatedcppdir={PROJECT}/Temp/StagingArea/Il2Cpp/il2cppOutput --dotnetprofile=unityaot --enable-debugger
链接的是libil2cpp.so。这样是以aot方式进行的。为每个architecture都要执行一遍
/Volumes/Samsung_T5/share/android-ndk-r16b/toolchains/x86-4.9/prebuilt/darwin-x86_64/lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin/ld.gold --sysroot=/Volumes/Samsung_T5/share/android-ndk-r16b/platforms/android-16/arch-x86 --eh-frame-hdr -m elf_i386 -shared -o Temp/StagingArea/libs/x86/libunity.so /Volumes/Samsung_T5/share/android-ndk-r16b/platforms/android-16/arch-x86/usr/lib/crtbegin_so.o -L/Volumes/Samsung_T5/share/android-ndk-r16b/sources/cxx-stl/gnu-libstdc++/4.9/libs/x86 -L/Volumes/Samsung_T5/share/android-ndk-r16b/toolchains/llvm/prebuilt/darwin-x86_64/lib64/clang/5.0.300080/lib/linux/i386 -L/Volumes/Samsung_T5/share/android-ndk-r16b/toolchains/x86-4.9/prebuilt/darwin-x86_64/lib/gcc/i686-linux-android/4.9.x -L/Volumes/Samsung_T5/share/android-ndk-r16b/toolchains/x86-4.9/prebuilt/darwin-x86_64/lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/lib -L/Volumes/Samsung_T5/share/android-ndk-r16b/platforms/android-16/arch-x86/usr/lib Temp/StagingArea/strip/x86/UnityICallRegistration.o Temp/StagingArea/strip/x86/UnityClassRegistration.o /Applications/Unity/PlaybackEngines/AndroidPlayer/Variations/il2cpp/Development/StaticLibs/x86/libunityruntime.a /Applications/Unity/PlaybackEngines/AndroidPlayer/Variations/il2cpp/Common/StaticLibs/x86/libunityexternal.a -soname libunity.so --no-undefined --build-id -z noexecstack --gc-sections --wrap abort /Applications/Unity/PlaybackEngines/AndroidPlayer/Variations/il2cpp/Development/Libs/x86/libmain.so --exclude-libs libunityexternal.a -u JNI_OnLoad -u JNI_OnUnload -u UnitySendMessage --version-script=/Applications/Unity/PlaybackEngines/AndroidPlayer/Variations/il2cpp/Common/StaticLibs/x86/../libunity.map -lc -lm -lgnustl_static -landroid -ldl -llog -lGLESv2 -lstdc++ -lz -lEGL -latomic -lstdc++ -lm -lgcc -ldl -lc -lgcc -ldl /Volumes/Samsung_T5/share/android-ndk-r16b/platforms/android-16/arch-x86/usr/lib/crtend_so.o
上面这个链接的是libunity.so
有点看不出如下这个干嘛的。也不知道tmpjBUypf.tmp文件是何时何地产生的。但末尾的use-ld=gold指代的应该是上面的ld.gold。应该是个链接调用中间层
/Volumes/Samsung_T5/share/android-ndk-r16b/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ @/var/folders/tf/zykybtgx4sv9z9q0sxy494ch0000gn/T/tmpjBUypf.tmp -o /Volumes/Samsung_T5/devops/workspace/ttest/Library/il2cpp_android_x86/il2cpp_cache/linkresult_22EC8261860FE97DBD61E73D67774863/libil2cpp.so -shared -Wl,-soname,libil2cpp.so -Wl,--no-undefined -Wl,-z,noexecstack -Wl,--gc-sections -Wl,--build-id --sysroot /Volumes/Samsung_T5/share/android-ndk-r16b/platforms/android-16/arch-x86 -gcc-toolchain /Volumes/Samsung_T5/share/android-ndk-r16b/toolchains/x86-4.9/prebuilt/darwin-x86_64 -target i686-none-linux-android -Wl,--wrap,sigaction -L /Volumes/Samsung_T5/share/android-ndk-r16b/sources/cxx-stl/gnu-libstdc++/4.9/libs/x86 -lgnustl_static -llog -rdynamic -fuse-ld=gold
如下是代码裁剪
/Volumes/Samsung_T5/share/android-ndk-r16b/toolchains/x86-4.9/prebuilt/darwin-x86_64/bin/i686-linux-android-strip --strip-debug Temp/StagingArea/libs/x86/libunity.so
iOS
除了上面的着色器编译和Roslyn编译器一致以外,就只有转换为cpp代码功能了,因为生成的工程包括资源和转化后的cpp代码需要用xcode继续编译。
/Applications/Unity/Unity.app/Contents/NetCore/Sdk/dotnet /Applications/Unity/Unity.app/Contents/il2cpp/build/il2cppcore/il2cppcore.dll --convert-to-cpp --emit-null-checks --enable-array-bounds-check --dotnetprofile=unityaot --enable-debugger --map-file-parser=/Applications/Unity/Unity.app/Contents/Tools/MapFileParser/MapFileParser --directory=/Volumes/Samsung_T5/devops/workspace/ttest/Temp/StagingArea/Data/Managed --generatedcppdir=/Volumes/Samsung_T5/devops/workspace/ttest/Temp/il2cppOutput/il2cppOutput
如下用于裁剪
/Applications/Unity/Unity.app/Contents/MonoBleedingEdge/bin/mono /Applications/Unity/Unity.app/Contents/il2cpp/build/UnityLinker.exe -out=/Volumes/Samsung_T5/devops/workspace/ttest/Temp/StagingArea/Data/Managed/tempStrip -x=/Applications/Unity/PlaybackEngines/iOSSupport/Whitelists/Core.xml -x /Volumes/Samsung_T5/devops/workspace/ttest/Temp/StagingArea/Data/Managed/../platform_native_link.xml -d /Volumes/Samsung_T5/devops/workspace/ttest/Temp/StagingArea/Data/Managed --include-unity-root-assembly=/Volumes/Samsung_T5/devops/workspace/ttest/Temp/StagingArea/Data/Managed/Assembly-CSharp.dll --dotnetruntime=il2cpp --dotnetprofile=unityaot --use-editor-options --include-directory=/Volumes/Samsung_T5/devops/workspace/ttest/Temp/StagingArea/Data/Managed --editor-settings-flag=AllowDebugging --editor-settings-flag=Development --rule-set=Conservative