Search Unity

Question Force code recompiling after scripting define symbols changed

Discussion in 'Testing & Automation' started by aurelien-morel-ubiant, Apr 5, 2019.

  1. aurelien-morel-ubiant

    aurelien-morel-ubiant

    Joined:
    Sep 27, 2017
    Posts:
    275
    Hello,
    I would to know if there is a way to pre-compile scripts during a build process.
    Because in our custom builder we implemented something like this :

    Code (CSharp):
    1. private bool PreBuildCustomMethod()
    2.         {
    3.             if (IsBuilding() && m_bBuildAbort)
    4.                 return NextBuildMethod(PreBuildCustomMethod);
    5.  
    6.             DebugBuilderGlobalDefines( "PreBuildCustomMethod" );
    7.  
    8.             Type preBuildCustomType = null;
    9.             string[] allAsmDef = Directory.GetFiles(Application.dataPath + "/", "*.asmdef", SearchOption.AllDirectories);
    10.             int nBuildMethodsFound = 0;
    11.             int nAssemblyCount = allAsmDef.Length;
    12.             if (allAsmDef.Length == 0)
    13.             {
    14.                 preBuildCustomType = Type.GetType("BuildMethod,Assembly-CSharp-Editor");
    15.                 if (preBuildCustomType != null)
    16.                 {
    17.                     MethodInfo methodInfo = preBuildCustomType.GetMethod("PreBuild");
    18.                     if (methodInfo != null)
    19.                         methodInfo.Invoke(null, null);
    20.                     nBuildMethodsFound++;
    21.                     nAssemblyCount++;
    22.                 }
    23.             }
    24.             else
    25.             {
    26.                 foreach (string singleAsmDef in allAsmDef)
    27.                 {
    28.                     string sAssemblyName = Path.GetFileNameWithoutExtension(singleAsmDef);
    29.                     preBuildCustomType = Type.GetType("BuildMethod," + sAssemblyName);
    30.                     if (preBuildCustomType != null)
    31.                     {
    32.                         nBuildMethodsFound++;
    33.                         MethodInfo methodInfo = preBuildCustomType.GetMethod("PreBuild");
    34.                         if (methodInfo != null)
    35.                             methodInfo.Invoke(null, null);
    36.                     }
    37.                 }
    38.             }
    39.  
    40.             return NextBuildMethod(PreBuildCustomMethod, nBuildMethodsFound.ToString() + " build methods found in the " + nAssemblyCount.ToString() + " assemblies");
    41.         }
    This allow us to do special stuff that must be done before or after the real pipeline build. But in a recent project, we have something like this :

    Code (CSharp):
    1. public static class BuildMethod
    2. {
    3.     public static void PreBuild()
    4.     {
    5.         string pathUISkin = UISkinManager.GetTargetUISkinModelPath();
    6.         Debug.LogWarning("pathUISkin : " + pathUISkin);
    7.         if (!AssetDatabase.CopyAsset( pathUISkin, "Assets/Resources/UISkins/UISkin.asset" ))
    8.         {
    9.             Debug.LogWarning("Copy the asset but remvoe before : " + pathUISkin);
    10.             AssetDatabase.MoveAssetToTrash( "Assets/Resources/UISkins/UISkin.asset" );
    11.             AssetDatabase.CopyAsset( pathUISkin, "Assets/Resources/UISkins/UISkin.asset" );
    12.         }
    13.     }
    14.  
    15.     public static void PostBuild()
    16.     {
    17.         Debug.LogWarning("Remove the asset copied earlier ");
    18.         AssetDatabase.MoveAssetToTrash( "Assets/Resources/UISkins/UISkin.asset" );
    19.     }
    20. }
    21.  
    22. public static string GetTargetUISkinModelPath()
    23.     {
    24.         string path = string.Empty;
    25.  
    26. #if USE_VERTUOZ
    27.         path = "Assets/Assets_MyHemis/AppData/UISkins/UISkin_Vertuoz.asset";
    28.         Debug.LogWarning("USE VERTUOZ");
    29. #elif USE_FLEXOM
    30.         path = "Assets/Assets_MyHemis/AppData/UISkins/UISkin_Flexom.asset";
    31.         Debug.LogWarning("USE FLEXOM");
    32. #elif USE_UBIANT
    33.         path = "Assets/Assets_MyHemis/AppData/UISkins/UISkin_Ubiant.asset";
    34.         Debug.LogWarning( "USE UBIANT" );
    35. #endif
    36.  
    37.         if (path == string.Empty)
    38.             Debug.LogError("[UISkinManager] The path of the target UISkin is unknowed");
    39.  
    40.         return path;
    41.     }
    42.  
    Before the PreBuildCustomMethod process, we have a method to define the new global define based on your
    Code (CSharp):
    1. PlayerSettings.SetScriptingDefineSymbolsForGroup( targetGroup, sData );
    .

    But sadly due to the fact that we changed the global define here and before the BuildPlayer, they are ignored by all the methods between them.

    So currently in our gitlab-ci process, I have to do this :


    Code (CSharp):
    1. if [[ "$RECOMPILE_ONLY" = "false" ]]; then
    2.                     "${UNITY_EXECUATBLE}" -batchmode -nographics -buildTarget "$PLATFORM" -logFile "${UNITY_LOGS_PATH}" -projectpath "${CI_PROJECT_DIR}/UnityProject" -executeMethod Ubiant.Editor.Builder.BuilderModel.BatchBuild -RECOMPILE_ONLY="true" -BUILD_PROFILE="$PROFILE" -ANDROID_SDK_PATH="${ANDROID_SDK_PATH}" -ANDROID_NDK_PATH="${ANDROID_NDK_PATH}" -BUILD_PROJECT_VERSION="$VERSION_NUMBER" -BUILD_DESTINATION="${PATH_TO_PLATFORM_BUILD}" -HOCKEY_APP_TEAM="${TEAM_ID_BUILD}" -BUILD_HOCKEYAPP
    3.                 fi
    4.                 "${UNITY_EXECUATBLE}" -batchmode -nographics -buildTarget "$PLATFORM" -logFile "${UNITY_LOGS_PATH}" -projectpath "${CI_PROJECT_DIR}/UnityProject" -executeMethod Ubiant.Editor.Builder.BuilderModel.BatchBuild -RECOMPILE_ONLY="$RECOMPILE_ONLY" -BUILD_PROFILE="$PROFILE" -ANDROID_SDK_PATH="${ANDROID_SDK_PATH}" -ANDROID_NDK_PATH="${ANDROID_NDK_PATH}" -BUILD_PROJECT_VERSION="$VERSION_NUMBER" -BUILD_DESTINATION="${PATH_TO_PLATFORM_BUILD}" -HOCKEY_APP_TEAM="${TEAM_ID_BUILD}" -BUILD_HOCKEYAPP
    5.            
    In this way, the first batchmode allow us to only recompile our project to correctly setup the scripting symbols and only call after another batchmode that take the good defines set by the first batchmode.

    It's maybe something twisted but this could allow us to switch some resources based on a profile (each profile has its own scripting symbol)

    Thanks.
     
  2. aromerogenera

    aromerogenera

    Joined:
    May 23, 2018
    Posts:
    1
    I have a similar issue, in our ci system too, if I set scripting define symbols by code using this method

    Code (CSharp):
    1. PlayerSettings.SetScriptingDefineSymbolsForGroup( targetGroup, sData );
    The unity compiler behaviour is not the same as I set them by the Editor manually, it loooks like the changes doesn't take effect until I restart Unity.
     
  3. unity_T1WL1huamuCWSQ

    unity_T1WL1huamuCWSQ

    Joined:
    Jun 18, 2019
    Posts:
    10
    Any Solution until now? I am also stuck.
     
    tokar_dev likes this.
  4. eugene_unity205

    eugene_unity205

    Joined:
    Nov 21, 2019
    Posts:
    1
    Also waiting for the solution
     
    tokar_dev likes this.
  5. unity_T1WL1huamuCWSQ

    unity_T1WL1huamuCWSQ

    Joined:
    Jun 18, 2019
    Posts:
    10
    Simple Way around I found to make a batch file with two commands. One to set the symbol define and the other one to execute the build process. That way it was succeded.
     
  6. MinsukCha

    MinsukCha

    Joined:
    Jun 9, 2014
    Posts:
    13
    Use manual complie request

    CompilationPipeline.RequestScriptCompilation()
     
    vitaliano_fanatee likes this.