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); }
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); }