/// <summary>
 /// Prepares function <see cref="System.Func{ResultT}"/> with specified signature for execution in AOT compiled environment.
 /// </summary>
 /// <typeparam name="ResultT">Function result type.</typeparam>
 public static void RegisterFunc <ResultT>()
 {
     if (typeof(AotCompilation).Name == string.Empty)
     {
         // ReSharper disable once AssignNullToNotNullAttribute
         var fn = Expression.Lambda <Func <ResultT> >(default(Expression), default(ParameterExpression[])).CompileAot();
         fn.Invoke();
         fn.DynamicInvoke();
         AotCompiler.Prepare <ResultT>(default(Expression));
     }
 }
 /// <summary>
 /// Prepares function <see cref="System.Func{Arg1T,Arg2T,Arg3T,Arg4T,ResultT}"/> with specified signature for execution in AOT compiled environment.
 /// </summary>
 /// <typeparam name="Arg1T">Function's first argument.</typeparam>
 /// <typeparam name="Arg2T">Function's second argument.</typeparam>
 /// <typeparam name="Arg3T">Function's third argument.</typeparam>
 /// <typeparam name="Arg4T">Function's fourth argument.</typeparam>
 /// <typeparam name="ResultT">Function result type.</typeparam>
 public static void RegisterFunc <Arg1T, Arg2T, Arg3T, Arg4T, ResultT>()
 {
     if (typeof(AotCompilation).Name == string.Empty)
     {
         // ReSharper disable once AssignNullToNotNullAttribute
         var fn = Expression.Lambda <Func <Arg1T, Arg2T, Arg3T, Arg4T, ResultT> >(default(Expression), default(ParameterExpression[])).CompileAot();
         fn.Invoke(default(Arg1T), default(Arg2T), default(Arg3T), default(Arg4T));
         fn.DynamicInvoke(default(Arg1T), default(Arg2T), default(Arg3T), default(Arg4T));
         AotCompiler.Prepare <Arg1T, Arg2T, Arg3T, Arg4T, ResultT>(default(Expression), default(ReadOnlyCollection <ParameterExpression>));
     }
 }
        /// <summary>
        ///  Compiles specified expression into <see cref="Func{TArg1, TArg2, TResult}"/> delegate using AOT aware expression compiler.
        /// </summary>
        /// <typeparam name="TArg1">First argument type.</typeparam>
        /// <typeparam name="TArg2">Second argument type.</typeparam>
        /// <typeparam name="TResult">Result type.</typeparam>
        /// <param name="expression">An expression syntax tree. Not null.</param>
        /// <param name="forceAot">True to always use AOT compiler event if environment is JIT and supports dynamic code.</param>
        /// <returns>A compiled expression.</returns>
        public static Func <TArg1, TArg2, TResult> CompileAot <TArg1, TArg2, TResult>(this Expression <Func <TArg1, TArg2, TResult> > expression, bool forceAot = false)
        {
            if (expression == null)
            {
                throw new ArgumentNullException("expression");
            }

            AotCompilation.RegisterFunc <TArg1, TArg2, TResult>();

            if (AotCompilation.IsAotRuntime || forceAot)
            {
                return(AotCompiler.PrepareFunc <TArg1, TArg2, TResult>(expression.Body, expression.Parameters));
            }
            else
            {
                return(expression.Compile());
            }
        }
        /// <summary>
        /// Compiles specified expression into <see cref="Action"/> delegate using AOT aware expression compiler.
        /// </summary>
        /// <param name="expression">An expression syntax tree. Not null.</param>
        /// <param name="forceAot">True to always use AOT compiler event if environment is JIT and supports dynamic code.</param>
        /// <returns>A compiled expression.</returns>
        public static Action CompileAot(this Expression <Action> expression, bool forceAot = false)
        {
            if (expression == null)
            {
                throw new ArgumentNullException("expression");
            }

            AotCompilation.RegisterAction();

            if (AotCompilation.IsAotRuntime || forceAot)
            {
                return(AotCompiler.PrepareAction(expression.Body));
            }
            else
            {
                return(expression.Compile());
            }
        }
Exemplo n.º 5
0
    public override bool Execute()
    {
        Utils.Logger = Log;
        bool isDevice = Arch.Equals("arm64", StringComparison.InvariantCultureIgnoreCase);

        if (isDevice && string.IsNullOrEmpty(CrossCompiler))
        {
            throw new ArgumentException("arm64 arch requires CrossCompiler");
        }

        if (!File.Exists(Path.Combine(AppDir, MainLibraryFileName)))
        {
            throw new ArgumentException($"MainLibraryFileName='{MainLibraryFileName}' was not found in AppDir='{AppDir}'");
        }

        if (ProjectName.Contains(" "))
        {
            throw new ArgumentException($"ProjectName='{ProjectName}' should not contain spaces");
        }

        if (UseLlvm && string.IsNullOrEmpty(LlvmPath))
        {
            // otherwise we might accidentally use some random llc/opt from PATH (installed with clang)
            throw new ArgumentException($"LlvmPath shoun't be empty when UseLlvm is set");
        }

        string[] excludes = new string[0];
        if (ExcludeFromAppDir != null)
        {
            excludes = ExcludeFromAppDir
                       .Where(i => !string.IsNullOrEmpty(i.ItemSpec))
                       .Select(i => i.ItemSpec)
                       .ToArray();
        }
        string[] libsToAot = Directory.GetFiles(AppDir, "*.dll")
                             .Where(f => !excludes.Contains(Path.GetFileName(f)))
                             .ToArray();

        string binDir = Path.Combine(AppDir, $"bin-{ProjectName}-{Arch}");

        if (!string.IsNullOrEmpty(OutputDirectory))
        {
            binDir = OutputDirectory;
        }
        Directory.CreateDirectory(binDir);

        // run AOT compilation only for devices
        if (isDevice)
        {
            if (string.IsNullOrEmpty(CrossCompiler))
            {
                throw new InvalidOperationException("cross-compiler is not set");
            }

            AotCompiler.PrecompileLibraries(CrossCompiler, Arch, !DisableParallelAot, binDir, libsToAot,
                                            new Dictionary <string, string> {
                { "MONO_PATH", AppDir }
            },
                                            Optimized, UseLlvm, LlvmPath);
        }

        // generate modules.m
        AotCompiler.GenerateLinkAllFile(
            Directory.GetFiles(binDir, "*.dll.o"),
            Path.Combine(binDir, "modules.m"));

        if (GenerateXcodeProject)
        {
            XcodeProjectPath = Xcode.GenerateXCode(ProjectName, MainLibraryFileName,
                                                   AppDir, binDir, MonoRuntimeHeaders, !isDevice, UseConsoleUITemplate, NativeMainSource);

            if (BuildAppBundle)
            {
                if (isDevice && string.IsNullOrEmpty(DevTeamProvisioning))
                {
                    // DevTeamProvisioning shouldn't be empty for arm64 builds
                    Utils.LogInfo("DevTeamProvisioning is not set, BuildAppBundle step is skipped.");
                }
                else
                {
                    AppBundlePath = Xcode.BuildAppBundle(
                        Path.Combine(binDir, ProjectName, ProjectName + ".xcodeproj"),
                        Arch, Optimized, DevTeamProvisioning);
                }
            }
        }

        return(true);
    }