Example #1
0
        public static void Create(List <BuildTask> tasks, Abi abi, Target target, string ifile)
        {
            var arch  = abi.AsArchString();
            var ext   = target.App.FastDev ? ".dylib" : ".o";
            var ofile = Path.Combine(target.App.Cache.Location, "lib" + Path.GetFileNameWithoutExtension(ifile) + "." + arch + ext);

            if (!Application.IsUptodate(ifile, ofile))
            {
                var task = new PinvokesTask()
                {
                    Target        = target,
                    Abi           = abi,
                    InputFile     = ifile,
                    OutputFile    = ofile,
                    SharedLibrary = target.App.FastDev,
                    Language      = "objective-c++",
                };
                if (target.App.FastDev)
                {
                    task.InstallName = "lib" + Path.GetFileNameWithoutExtension(ifile) + ext;
                    task.CompilerFlags.AddFramework("Foundation");
                    task.CompilerFlags.LinkWithXamarin();
                }
                tasks.Add(task);
            }
            else
            {
                Driver.Log(3, "Target '{0}' is up-to-date.", ofile);
            }

            target.LinkWith(ofile);
            target.LinkWithAndShip(ofile);
        }
Example #2
0
        public void ProcessAssemblies()
        {
            //
            // * Linking
            //   Copy assemblies to LinkDirectory
            //   Link and save to PreBuildDirectory
            //   If marshalling native exceptions:
            //     * Generate/calculate P/Invoke wrappers and save to PreBuildDirectory
            //   [AOT assemblies in BuildDirectory]
            //   Strip managed code save to TargetDirectory (or just copy the file if stripping is disabled).
            //
            // * No linking
            //   If marshalling native exceptions:
            //     Generate/calculate P/Invoke wrappers and save to PreBuildDirectory.
            //   If not marshalling native exceptions:
            //     Copy assemblies to PreBuildDirectory
            //     Copy unmodified assemblies to BuildDirectory
            //   [AOT assemblies in BuildDirectory]
            //   Strip managed code save to TargetDirectory (or just copy the file if stripping is disabled).
            //
            // Note that we end up copying assemblies around quite much,
            // this is because we we're comparing contents instead of
            // filestamps, so we need the previous file around to be
            // able to do the actual comparison. For instance: in the
            // 'No linking' case above, we copy the assembly to PreBuild
            // before removing the resources and saving that result to Build.
            // The copy in PreBuild is required for the next build iteration,
            // to see if the original assembly has been modified or not (the
            // file in the Build directory might be different due to resource
            // removal even if the original assembly didn't change).
            //
            // This can probably be improved by storing digests/hashes instead
            // of the entire files, but this turned out a bit messy when
            // trying to make it work with the linker, so I decided to go for
            // simple file copying for now.
            //

            //
            // Other notes:
            //
            // * We need all assemblies in the same directory when doing AOT-compilation.
            // * We cannot overwrite in-place, because it will mess up dependency tracking
            //   and besides if we overwrite in place we might not be able to ignore
            //   insignificant changes (such as only a GUID change - the code is identical,
            //   but we still need the original assembly since the AOT-ed image also stores
            //   the GUID, and we fail at runtime if the GUIDs in the assembly and the AOT-ed
            //   image don't match - if we overwrite in-place we lose the original assembly and
            //   its GUID).
            //

            LinkDirectory = Path.Combine(ArchDirectory, "Link");
            if (!Directory.Exists(LinkDirectory))
            {
                Directory.CreateDirectory(LinkDirectory);
            }

            PreBuildDirectory = Path.Combine(ArchDirectory, "PreBuild");
            if (!Directory.Exists(PreBuildDirectory))
            {
                Directory.CreateDirectory(PreBuildDirectory);
            }

            BuildDirectory = Path.Combine(ArchDirectory, "Build");
            if (!Directory.Exists(BuildDirectory))
            {
                Directory.CreateDirectory(BuildDirectory);
            }

            if (!Directory.Exists(TargetDirectory))
            {
                Directory.CreateDirectory(TargetDirectory);
            }

            ManagedLink();

            if (App.RequiresPInvokeWrappers)
            {
                // Write P/Invokes
                var state = MarshalNativeExceptionsState;
                if (state.Started)
                {
                    // The generator is 'started' by the linker, which means it may not
                    // be started if the linker was not executed due to re-using cached results.
                    state.End();
                }

                PinvokesTask.Create(compile_tasks, Abis, this, state.SourcePath);

                if (App.FastDev)
                {
                    // In this case assemblies must link with the resulting dylib,
                    // so we can't compile the pinvoke dylib in parallel with later
                    // stuff.
                    compile_tasks.ExecuteInParallel();
                }
            }

            // Now the assemblies are in PreBuildDirectory.

            foreach (var a in Assemblies)
            {
                var target = Path.Combine(BuildDirectory, a.FileName);
                if (!a.CopyAssembly(a.FullPath, target))
                {
                    Driver.Log(3, "Target '{0}' is up-to-date.", target);
                }
                a.FullPath = target;
            }

            Driver.GatherFrameworks(this, Frameworks, WeakFrameworks);

            // Make sure there are no duplicates between frameworks and weak frameworks.
            // Keep the weak ones.
            Frameworks.ExceptWith(WeakFrameworks);
        }