Search Unity

  1. Calling all beginners! Join the FPS Beginners Mods Challenge until December 13.
    Dismiss Notice
  2. It's Cyber Week at the Asset Store!
    Dismiss Notice

BuildUtilities.RegisterShouldIncludeInBuildCallback unclear

Discussion in 'Package Manager' started by GammaPs, May 8, 2019.

  1. GammaPs

    GammaPs

    Joined:
    May 21, 2013
    Posts:
    9
    Dear Community,

    PackageManager Api docs specify 2 options to include or exclude package content from a Project / Build.

    BuildUtilities.RegisterShouldIncludeInBuildCallback https://docs.unity3d.com/ScriptRefe...ies.RegisterShouldIncludeInBuildCallback.html
    IShouldIncludeInBuildCallback https://docs.unity3d.com/ScriptReference/PackageManager.IShouldIncludeInBuildCallback.html

    I wanted to see if this is allowing us to include or exclude packages from a Build based on some custom configurations we create. Thats at least what I expected is possible reading the documentation.
    Now all my tries to get this configuration somehow going are miserably failing. The ShouldIncludeInBuild Method is never invoked.

    Here is a quick and ugly implementation that should register an instance of PackageManagerBuildConfiguration per package and should be invoked at some point of project or build creation.

    Now Listing of Packages works.
    PackageName getter is called 3 times per package.
    ShouldIncludeInBuild is never invoked. Any ideas?

    We do have a project that is configured and compiled slightly different to multiple platforms.
    So we would for example love to add the AR Foundation package in one case, but not the other.
    With assemblys and scripting define symbol restriction for assemblies we can handle our code and inclusion pretty well.
    But what is the way to go with the package manager?
    How do we include / exclude packages by scripting or by scripting define symbols?

    Any help appreciated, thank you.


    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using UnityEditor.PackageManager;
    4.  
    5. public class PackageManagerBuildConfiguration : IShouldIncludeInBuildCallback
    6. {
    7.     private static UnityEditor.PackageManager.Requests.ListRequest request;
    8.  
    9.     [MenuItem("Tools/PackageManager/HookIntoBuild")][InitializeOnLoadMethod]
    10.     public static void HoockIntoPackageManager()
    11.     {
    12.         Debug.Log("PackageManagerBuildConfiguration -- Scripting Environment launched");
    13.  
    14.         request = Client.List(false);
    15.  
    16.         EditorApplication.update += Update;
    17.     }
    18.  
    19.     static void Update()
    20.     {
    21.         if (request == null)
    22.             return;
    23.  
    24.  
    25.         if(request.IsCompleted)
    26.         {
    27.             using (System.IO.StringWriter writer = new System.IO.StringWriter())
    28.             {
    29.                 foreach (UnityEditor.PackageManager.PackageInfo r in request.Result)
    30.                 {
    31.                     writer.WriteLine(string.Format(
    32.                         "packageId: {0}, " +
    33.                         "status: {1}, " +
    34.                         "version: {2}, " +
    35.                         "assetPath: {3}, " +
    36.                         "author_ {4}, " +
    37.                         "category: {5}, " +
    38.                         "description: {6}, " +
    39.                         "name: {7}",
    40.                         r.packageId,
    41.                         r.status,
    42.                         r.assetPath,
    43.                         r.author,
    44.                         r.category,
    45.                         r.description,
    46.                         r.version,
    47.                         r.name));
    48.  
    49.  
    50.                     writer.WriteLine("\n");
    51.  
    52.                     BuildUtilities.RegisterShouldIncludeInBuildCallback(new PackageManagerBuildConfiguration(r.name));
    53.                 }
    54.  
    55.                 Debug.Log(writer);
    56.             }
    57.  
    58.             request = null;
    59.             EditorApplication.update -= Update;
    60.         }
    61.     }
    62.  
    63.     public string PackageName
    64.     {
    65.         get
    66.         {
    67.  
    68.             Debug.Log(_packageName);
    69.  
    70.             return _packageName;
    71.         }
    72.     }
    73.  
    74.     private string _packageName;
    75.  
    76.     public PackageManagerBuildConfiguration(string packageName)
    77.     {
    78.         _packageName = packageName;
    79.     }
    80.  
    81.     public bool ShouldIncludeInBuild(string path)
    82.     {
    83.         Debug.Log("ShouldIncludeInBuild: " + path);
    84.  
    85.         return false;
    86.     }
    87. }
     
    Last edited: May 8, 2019
  2. maximeb_unity

    maximeb_unity

    Unity Technologies

    Joined:
    Mar 20, 2018
    Posts:
    144
    Hi @GammaPs,

    This callback is invoked only when you create a build (File -> Build & Run or File -> Build Settings -> Build), not during project import or script compilation.

    There seems to be an error in the documentation which states that it applies to any asset, but that's inaccurate, it only applies to DLL plugins. I notified the team in charge to update the documentation accordingly.

    I tried your code snippet (thanks for providing it!) in a blank project, and I confirm seeing log entries prefixed with "
    ShouldIncludeInBuild:" for all DLL files in packages - but no other asset type. So this feature works, but it's a lot more limited than what you expected.

    If you need to exclude a package's code from a build, it's usually sufficient not to reference any of it in your own code, nor any other package that would reference it. You can also use the UnityEditor.PackageManager.Client C# APIs to programmatically add or remove packages, though I don't recommend doing that when you create a build or switch Playmode, for instance, because adding/updating/removing packages with code will lead to recompilation and domain reloads, which could break your own Editor script.
     
  3. GammaPs

    GammaPs

    Joined:
    May 21, 2013
    Posts:
    9
    Thank you for clarifying this with the *.dll
    I actually expected it to be triggered at Build time, but didn't get anything since I didn't have any dll packages included, so I was not sure anymore.

    Thing with not linked packages is, that C# is stripped is true, except for native plugins.
    Native Plugins are also exported even if the C# wrapper linking it is not referenced. So using ARFoundation in our case would bring stuff from ARKit and ARCore along with it. Bloating our non AR version of the App.

    Question to adding and removing packages is then, How do I know which packages are imported or not?
    In the List Request I only see the status : Available, but there is no imported/included whatsoever state indicating that a package is included in the Project.
    Do I just trigger a best guess add or remove and if its included it wont be added again, or removal would fail?

    PS:
    For Recompilation, I'm already past this barrier, I'm writing a lockflag to tmp/ then changing ScriptingDefineSymbols and other PlayerSettings that come with a recompile. Then recover at [InitializeOnLoadAttribute] from the lockflag. So package changes is a doable.
     
  4. maximeb_unity

    maximeb_unity

    Unity Technologies

    Joined:
    Mar 20, 2018
    Posts:
    144
    Ah, I understand how that can be undesirable. Unfortunately I have no guidance to offer right now, but I'll try to find a better answer since this question would be of interest to anyone writing custom packages.

    Any package included in the List request is included in the project. That is what the request is for. If you set the includeIndirectDependencies parameter to true, the result will include all the packages, including those present in the project as indirect dependencies of other packages.

    Actually, to be perfectly accurate, if a status is not "Available", it means that the package or one of its dependency is not present - but in practice, this should not happen, unless some error prevented the package or its dependency from being downloaded at all.