IL2CPP fails when compiling F# library for iOS and WebGL targets

I’ve included a DLL built using F# in my project. When I try to build the WebGL target from Unity, I get the following errors in the log:

Invoking il2cpp with arguments: --convert-to-cpp --extra-types.file="C:\Program Files\Unity\Editor\Data\il2cpp\il2cpp_default_extra_types.txt"  --assembly="C:\Users\unind\Desktop\Roll-a-Ball\Temp\StagingArea\Data\Managed\UnityEngine.UI.dll" --assembly="C:\Users\unind\Desktop\Roll-a-Ball\Temp\StagingArea\Data\Managed\Assembly-FSharp.dll" --assembly="C:\Users\unind\Desktop\Roll-a-Ball\Temp\StagingArea\Data\Managed\UnityEngine.dll" --generatedcppdir="C:\Users\unind\Desktop\Roll-a-Ball\Temp\StagingArea\Data\il2cppOutput" 
C:\Program Files\Unity\Editor\Data\il2cpp/build/il2cpp.exe exited after 33683 ms.
Failed running "C:\Program Files\Unity\Editor\Data\PlaybackEngines\WebGLSupport/BuildTools/Emscripten_Win/python/2.7.5.3_64bit/python.exe" "C:\Program Files\Unity\Editor\Data\PlaybackEngines\WebGLSupport/BuildTools/Emscripten/emcc" -Oz -std=c++11 -Wno-unused-value -Wno-invalid-offsetof -I-I"C:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\Libraries\bdwgc/include" -I"C:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\Libraries\libil2cpp/include" -I"C:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\il2cppOutput"  -nostdinc -c @"C:\Users\unind\AppData\Local\Temp	mp62b29697.tmp"

WARNING: sanity check failed to run [Errno 13] Permission denied: 'C:\\Program Files\\Unity\\Editor\\Data\\PlaybackEngines\\WebGLSupport/BuildTools/emscripten.config_sanity'WARNING  root: did not see a source tree above or next to the LLVM root directory (guessing based on directory of C:\Program Files\Unity\Editor\Data\PlaybackEngines\WebGLSupport/BuildTools/Emscripten_FastComp_Win\llc), could not verify version numbers match
INFO     root: (Emscripten: Running sanity checks)
WARNING  root: java does not seem to exist, required for closure compiler, which is optional (define JAVA in ~/.emscripten if you want it)
WARNING  root: -I or -L of an absolute path "-IC:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\Libraries\libil2cpp/include" encountered. If this is to a local system header/library, it may cause problems (local system files make sense for compiling natively on your system, but not necessarily to JavaScript). Pass '-Wno-warn-absolute-paths' to emcc to hide this warning.
C:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\il2cppOutput\Bulk_FSharp.Core_0.cpp:1542:11: error: cannot convert 'UIntPtr_t' to 'uintptr_t' (aka 'unsigned int') without a conversion operator
                if ((!(((uintptr_t)L_67) < ((uintptr_t)L_68))))
                        ^~~~~~~~~~~~~~~
C:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\il2cppOutput\Bulk_FSharp.Core_0.cpp:1542:31: error: cannot convert 'UIntPtr_t' to 'uintptr_t' (aka 'unsigned int') without a conversion operator
                if ((!(((uintptr_t)L_67) < ((uintptr_t)L_68))))
                                            ^~~~~~~~~~~~~~~
C:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\il2cppOutput\Bulk_FSharp.Core_0.cpp:1555:15: error: cannot convert 'UIntPtr_t' to 'uintptr_t' (aka 'unsigned int') without a conversion operator
                return ((!(((uintptr_t)L_69) <= ((uintptr_t)L_70)))? 1 : 0);
                            ^~~~~~~~~~~~~~~
C:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\il2cppOutput\Bulk_FSharp.Core_0.cpp:1555:36: error: cannot convert 'UIntPtr_t' to 'uintptr_t' (aka 'unsigned int') without a conversion operator
                return ((!(((uintptr_t)L_69) <= ((uintptr_t)L_70)))? 1 : 0);
                                                 ^~~~~~~~~~~~~~~
C:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\il2cppOutput\Bulk_FSharp.Core_0.cpp:1667:9: error: cannot convert 'IntPtr_t' to 'intptr_t' (aka 'int') without a conversion operator
                if ((((intptr_t)L_93) >= ((intptr_t)L_94)))
                      ^~~~~~~~~~~~~~
C:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\il2cppOutput\Bulk_FSharp.Core_0.cpp:1667:29: error: cannot convert 'IntPtr_t' to 'intptr_t' (aka 'int') without a conversion operator
                if ((((intptr_t)L_93) >= ((intptr_t)L_94)))
                                          ^~~~~~~~~~~~~~
C:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\il2cppOutput\Bulk_FSharp.Core_0.cpp:1680:13: error: cannot convert 'IntPtr_t' to 'intptr_t' (aka 'int') without a conversion operator
                return ((((intptr_t)L_95) > ((intptr_t)L_96))? 1 : 0);
                          ^~~~~~~~~~~~~~
C:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\il2cppOutput\Bulk_FSharp.Core_0.cpp:1680:32: error: cannot convert 'IntPtr_t' to 'intptr_t' (aka 'int') without a conversion operator
                return ((((intptr_t)L_95) > ((intptr_t)L_96))? 1 : 0);
                                             ^~~~~~~~~~~~~~
C:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\il2cppOutput\Bulk_FSharp.Core_0.cpp:11557:9: error: cannot convert 'IntPtr_t' to 'intptr_t' (aka 'int') without a conversion operator
                if ((((intptr_t)L_0) >= ((intptr_t)L_1)))
                      ^~~~~~~~~~~~~
C:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\il2cppOutput\Bulk_FSharp.Core_0.cpp:11557:28: error: cannot convert 'IntPtr_t' to 'intptr_t' (aka 'int') without a conversion operator
                if ((((intptr_t)L_0) >= ((intptr_t)L_1)))
                                         ^~~~~~~~~~~~~
C:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\il2cppOutput\Bulk_FSharp.Core_0.cpp:11570:13: error: cannot convert 'IntPtr_t' to 'intptr_t' (aka 'int') without a conversion operator
                return ((((intptr_t)L_2) > ((intptr_t)L_3))? 1 : 0);
                          ^~~~~~~~~~~~~
C:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\il2cppOutput\Bulk_FSharp.Core_0.cpp:11570:31: error: cannot convert 'IntPtr_t' to 'intptr_t' (aka 'int') without a conversion operator
                return ((((intptr_t)L_2) > ((intptr_t)L_3))? 1 : 0);
                                            ^~~~~~~~~~~~~
C:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\il2cppOutput\Bulk_FSharp.Core_0.cpp:11734:11: error: cannot convert 'UIntPtr_t' to 'uintptr_t' (aka 'unsigned int') without a conversion operator
                if ((!(((uintptr_t)L_0) < ((uintptr_t)L_1))))
                        ^~~~~~~~~~~~~~
C:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\il2cppOutput\Bulk_FSharp.Core_0.cpp:11734:30: error: cannot convert 'UIntPtr_t' to 'uintptr_t' (aka 'unsigned int') without a conversion operator
                if ((!(((uintptr_t)L_0) < ((uintptr_t)L_1))))
                                           ^~~~~~~~~~~~~~
C:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\il2cppOutput\Bulk_FSharp.Core_0.cpp:11747:15: error: cannot convert 'UIntPtr_t' to 'uintptr_t' (aka 'unsigned int') without a conversion operator
                return ((!(((uintptr_t)L_2) <= ((uintptr_t)L_3)))? 1 : 0);
                            ^~~~~~~~~~~~~~
C:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\il2cppOutput\Bulk_FSharp.Core_0.cpp:11747:35: error: cannot convert 'UIntPtr_t' to 'uintptr_t' (aka 'unsigned int') without a conversion operator
                return ((!(((uintptr_t)L_2) <= ((uintptr_t)L_3)))? 1 : 0);
                                                ^~~~~~~~~~~~~~
16 errors generated.
ERROR    root: compiler frontend failed to generate LLVM bitcode, halting
UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
UnityEngine.Logger:Log(LogType, Object)
UnityEngine.Debug:LogError(Object)
NativeCompiler:RunProgram(ProcessStartInfo) (at C:\buildslave\unity\build\Editor\Mono\BuildPipeline\Il2Cpp\NativeCompiler.cs:60)
NativeCompiler:Execute(String, String) (at C:\buildslave\unity\build\Editor\Mono\BuildPipeline\Il2Cpp\NativeCompiler.cs:26)
UnityEditor.WebGL.Il2Cpp.<StartObjectCompilerThreads>c__AnonStorey1:<>m__13() (at /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/Il2Cpp/EmscriptenCompiler.cs:67)
 
(Filename: /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/Il2Cpp/EmscriptenCompiler.cs Line: 67)

Failed running "C:\Program Files\Unity\Editor\Data\PlaybackEngines\WebGLSupport/BuildTools/Emscripten_Win/python/2.7.5.3_64bit/python.exe" "C:\Program Files\Unity\Editor\Data\PlaybackEngines\WebGLSupport/BuildTools/Emscripten/emcc" -Oz -s NO_EXIT_RUNTIME=1 -o "C:/Users/unind/Desktop/Roll-a-Ball/Assets/../Temp/StagingArea/Data\Native\UserAssembly.bc" @"C:\Users\unind\AppData\Local\Temp	mp5fa9c58d.tmp"

WARNING: sanity check failed to run [Errno 13] Permission denied: 'C:\\Program Files\\Unity\\Editor\\Data\\PlaybackEngines\\WebGLSupport/BuildTools/emscripten.config_sanity'WARNING  root: did not see a source tree above or next to the LLVM root directory (guessing based on directory of C:\Program Files\Unity\Editor\Data\PlaybackEngines\WebGLSupport/BuildTools/Emscripten_FastComp_Win\llc), could not verify version numbers match
INFO     root: (Emscripten: Running sanity checks)
WARNING  root: java does not seem to exist, required for closure compiler, which is optional (define JAVA in ~/.emscripten if you want it)
ERROR    root: C:\Users\unind\Desktop\Roll-a-Ball\Temp\EmscriptenWork\Bulk_FSharp.Core_0.o: No such file or directory ("C:\Users\unind\Desktop\Roll-a-Ball\Temp\EmscriptenWork\Bulk_FSharp.Core_0.o" was expected to be an input file, based on the commandline arguments provided)
UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
UnityEngine.Logger:Log(LogType, Object)
UnityEngine.Debug:LogError(Object)
NativeCompiler:RunProgram(ProcessStartInfo) (at C:\buildslave\unity\build\Editor\Mono\BuildPipeline\Il2Cpp\NativeCompiler.cs:60)
NativeCompiler:Execute(String, String) (at C:\buildslave\unity\build\Editor\Mono\BuildPipeline\Il2Cpp\NativeCompiler.cs:26)
UnityEditor.WebGL.Il2Cpp.EmscriptenCompiler:LinkObjects(IEnumerable`1, String) (at /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/Il2Cpp/EmscriptenCompiler.cs:57)
UnityEditor.WebGL.Il2Cpp.EmscriptenCompiler:MultiThreadedCompile(String, IEnumerable`1, IEnumerable`1, Boolean) (at /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/Il2Cpp/EmscriptenCompiler.cs:44)
UnityEditor.WebGL.Il2Cpp.EmscriptenCompiler:CompileDynamicLibrary(String, IEnumerable`1, IEnumerable`1, IEnumerable`1, IEnumerable`1) (at /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/Il2Cpp/EmscriptenCompiler.cs:21)
UnityEditorInternal.IL2CPPBuilder:Run() (at C:\buildslave\unity\build\Editor\Mono\BuildPipeline\Il2Cpp\IL2CPPUtils.cs:218)
UnityEditorInternal.IL2CPPUtils:RunIl2Cpp(String, IIl2CppPlatformProvider, Action`1, RuntimeClassRegistry, Boolean) (at C:\buildslave\unity\build\Editor\Mono\BuildPipeline\Il2Cpp\IL2CPPUtils.cs:135)
UnityEditor.WebGL.WebGlBuildPostprocessor:PostProcess(BuildPostProcessArgs) (at /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/BuildPostprocessor.cs:301)
UnityEditor.PostprocessBuildPlayer:Postprocess(BuildTarget, String, String, String, Int32, Int32, String, String, BuildOptions, RuntimeClassRegistry) (at C:\buildslave\unity\build\Editor\Mono\BuildPipeline\PostprocessBuildPlayer.cs:316)
UnityEditor.BuildPipeline:BuildPlayerInternalNoCheck(String[], String, BuildTarget, BuildOptions, Boolean, UInt32&)
UnityEditor.BuildPipeline:BuildPlayerInternal(String[], String, BuildTarget, BuildOptions, UInt32&) (at C:\buildslave\unity\build\artifacts\generated\common\editor\BuildPipelineBindings.gen.cs:212)
UnityEditor.BuildPipeline:BuildPlayer(String[], String, BuildTarget, BuildOptions) (at C:\buildslave\unity\build\artifacts\generated\common\editor\BuildPipelineBindings.gen.cs:152)
AutoBuilder:PerformBuild(String, BuildTarget, BuildOptions) (at Assets\Editor\AutoBuilder.cs:77)
AutoBuilder:PerformWebGLBuild() (at Assets\Editor\AutoBuilder.cs:64)
 
(Filename: /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/Il2Cpp/EmscriptenCompiler.cs Line: 57)

Exception: IL2CPP compile failed.
  at NativeCompiler.RunProgram (System.Diagnostics.ProcessStartInfo startInfo) [0x000dc] in C:\buildslave\unity\build\Editor\Mono\BuildPipeline\Il2Cpp\NativeCompiler.cs:62 
  at NativeCompiler.Execute (System.String arguments, System.String compilerPath) [0x0000f] in C:\buildslave\unity\build\Editor\Mono\BuildPipeline\Il2Cpp\NativeCompiler.cs:26 
  at UnityEditor.WebGL.Il2Cpp.EmscriptenCompiler.LinkObjects (IEnumerable`1 sources, System.String outfile) [0x00083] in /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/Il2Cpp/EmscriptenCompiler.cs:57 
  at UnityEditor.WebGL.Il2Cpp.EmscriptenCompiler.MultiThreadedCompile (System.String outfile, IEnumerable`1 sources, IEnumerable`1 includePaths, Boolean exceptionSupport) [0x00035] in /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/Il2Cpp/EmscriptenCompiler.cs:44 
  at UnityEditor.WebGL.Il2Cpp.EmscriptenCompiler.CompileDynamicLibrary (System.String outFile, IEnumerable`1 sources, IEnumerable`1 includePaths, IEnumerable`1 libraries, IEnumerable`1 libraryPaths) [0x0005c] in /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/Il2Cpp/EmscriptenCompiler.cs:21 
  at UnityEditorInternal.IL2CPPBuilder.Run () [0x000f0] in C:\buildslave\unity\build\Editor\Mono\BuildPipeline\Il2Cpp\IL2CPPUtils.cs:218 
  at UnityEditorInternal.IL2CPPUtils.RunIl2Cpp (System.String stagingAreaData, IIl2CppPlatformProvider platformProvider, System.Action`1 modifyOutputBeforeCompile, UnityEditor.RuntimeClassRegistry runtimeClassRegistry, Boolean developmentBuild) [0x0000d] in C:\buildslave\unity\build\Editor\Mono\BuildPipeline\Il2Cpp\IL2CPPUtils.cs:135 
  at UnityEditor.WebGL.WebGlBuildPostprocessor.PostProcess (BuildPostProcessArgs args) [0x00156] in /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/BuildPostprocessor.cs:301 
  at UnityEditor.PostprocessBuildPlayer.Postprocess (BuildTarget target, System.String installPath, System.String companyName, System.String productName, Int32 width, Int32 height, System.String downloadWebplayerUrl, System.String manualDownloadWebplayerUrl, BuildOptions options, UnityEditor.RuntimeClassRegistry usedClassRegistry) [0x000c5] in C:\buildslave\unity\build\Editor\Mono\BuildPipeline\PostprocessBuildPlayer.cs:316 
UnityEditor.BuildPipeline:BuildPlayerInternalNoCheck(String[], String, BuildTarget, BuildOptions, Boolean, UInt32&)
UnityEditor.BuildPipeline:BuildPlayerInternal(String[], String, BuildTarget, BuildOptions, UInt32&) (at C:\buildslave\unity\build\artifacts\generated\common\editor\BuildPipelineBindings.gen.cs:212)
UnityEditor.BuildPipeline:BuildPlayer(String[], String, BuildTarget, BuildOptions) (at C:\buildslave\unity\build\artifacts\generated\common\editor\BuildPipelineBindings.gen.cs:152)
AutoBuilder:PerformBuild(String, BuildTarget, BuildOptions) (at Assets\Editor\AutoBuilder.cs:77)
AutoBuilder:PerformWebGLBuild() (at Assets\Editor\AutoBuilder.cs:64)
 
(Filename: /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/Il2Cpp/EmscriptenCompiler.cs Line: 57)

DisplayProgressNotification: Build Failed
Error building Player: Exception: IL2CPP compile failed.

A similar thing happens in Xcode when trying to build the project generated by Unity.

Anything I can do to solve this?

There is not much you can do about this now. IL2CPP does not officially support F#, so these errors are expected. We’ve done some internal work on making more of the IL code generated by the F# compiler work recently (one of our team members enjoys F#), so this specific issue might be corrected in the latest version of Unity.

However, I would recommend looking for a similar library that is not written in F#, as we won’t guarantee that we can fix F# bugs.

More generally, we don’t have a good way to represent tail calls in C++ code now, so F# is probably not a good choice with IL2CPP.