Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

2020.3.1 unable to compile Mac Xcode IL2CPP, GameAssembly 'Run Script' build phase errors

Discussion in 'macOS' started by jason_yak, Mar 29, 2021.

  1. jason_yak

    jason_yak

    Joined:
    Aug 25, 2016
    Posts:
    514
    Hi there,

    It is currentlty impossible to compile a mac build when using the xcode option with IL2CPP without modifications to the generated xcode project. I'm using an Intel mac on Big Sur, Xcode 12.4 using 2020.3.1.

    The errors come from the 'Run Script' build phase for the GameAssembly target in xcode. We have two major issues, I've been able to workaround the first by changing the build system value for the xcode project to the 'new build system' (Note: Xcode projects created are set to use the now deprecated 'legacy build system'). But then we are then stuck on another issue that we can not find a workaround for, native plugin scripts are not compiling and causing another error when the GameAssembly build script runs.

    I've just submitted a bug report with a simple repro project for this: 1325183

    copied from the bug report:

    How can we reproduce it using the example you attached
    - Create a new empty Unity project
    - Change the build target to Standalone Mac, I have both arm64 and intel selected for archiectures but I don't think this will affect the outcome, also select the 'create xcode project' option, and ensure that IL2CPP is used for the scripting backend
    - Without any other changes to the project Build out and then try to compile using Product > Archive in Xcode 12.4, this error is thrown:

    Code (CSharp):
    1. chown: /Users/jason/Library/Developer/Xcode/DerivedData/cccc-abeivixjugkzhzdhevhxbdwolfni/Build/Intermediates.noindex/ArchiveIntermediates/MacXcode2020-3/InstallationBuildProductsLocation/usr/local/lib/GameAssembly.dylib: No such file or directory
    2. Command /usr/sbin/chown failed with exit code 1
    - the workaround we've found for this first issue is to change the xcode build system to 'new build system'. Please note that I've included an editor script called PostProcess.cs that demonstates how to change the build system setting as a post process. Once this is done the chown error no longer occurs.

    - at this point we're wanting to include our own native plugin scripts, in the submitted repro project we have two files TestNativePlugin.h + TestNativePlugin.mm. The import settings for these files are set to support Mac any cpu. When building out of Unity they are correctly included in the generated xcode project and found at the location you would expect: [BuildOutputFolder]/Il2CppOutputProject/Source/CppPlugins/, however when trying to compile in xcode we get errors that symbols are not defined for these scripts:

    Code (CSharp):
    1. Undefined symbols for architecture x86_64:
    2. "_OBJC_CLASS_$_NSScreen", referenced from:
    3. objc-class-ref in 31C81447C8E506814A74AE208FD057EB.o
    4. ld: symbol(s) not found for architecture x86_64
    5. clang: error: linker command failed with exit code 1 (use -v to see invocation)
    Expected result:
    To be able to compile an xcode project without needing to modify the build system setting, and to also be able to compile native plugin scripts like iOS and tvOS.


    We have exhauted options trying to get the app to compile when using native plugin scripts. This is what we have tried:
    • The native plugin script we've added uses the AppKit framework, we've tried adding AppKit framework to the main build target but this didn't help
    • We noticed that despite the *.h and *.mm files being included in the project they are not added to any 'Compile Sources' build phase like they are for IL2CPP iOS xcode projects, so we tried to add them to the main build target but this also didn't help
    • We then tried to add a 'Link frameworks' build phase to the GameAssembly target, made sure the AppKit framework was enabled for both the main target and the GameAssembly targets, and we tried adding the native scripts in a 'Compile Sources' build phase on GameAssembly instead of the main target seeing as it's the one complaining of the missing symbols, but none of this helped either.

    The included native scripts are not doing much, just a token addition to try and prove they can be used, will be happy to know what we're missing in order to stop the GameAssembly build script from throwing errors:

    Assets/Plugins/TestNativePlugin.h
    Code (CSharp):
    1.  
    2. #import <Foundation/Foundation.h>
    3. #import <AppKit/AppKit.h>
    4.  
    Assets/Plugins/TestNativePlugin.mm
    Code (CSharp):
    1.  
    2. #import "TestNativePlugin.h"
    3.  
    4. extern "C" {
    5.     float GetScreenScaleFactor () {
    6.         return [[NSScreen mainScreen] backingScaleFactor];
    7.     }
    8. }
    9.  
     
  2. jason_yak

    jason_yak

    Joined:
    Aug 25, 2016
    Posts:
    514
    and if anyones interested this is the post process script to change the build system:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using System.IO;
    4. using UnityEngine;
    5. using UnityEditor;
    6. using UnityEditor.Callbacks;
    7. using UnityEditor.iOS.Xcode;
    8.  
    9. public class PostProcess {
    10.  
    11.     [PostProcessBuildAttribute( 1 )]
    12.     public static void ChangeBuildManifest ( BuildTarget buildTarget, string pathToBuiltProject ) {
    13.         #if UNITY_STANDALONE_OSX
    14.         // paths
    15.         var buildFolderName = pathToBuiltProject.Substring( pathToBuiltProject.LastIndexOf( "/" ) );
    16.         var xCodeProjFolderPath = $"{pathToBuiltProject}/{buildFolderName}.xcodeproj";
    17.         var xcSettingsPath = $"{xCodeProjFolderPath}/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings";
    18.         Debug.Log($"xCodeProjFolderPath: {xCodeProjFolderPath}");
    19.         Debug.Log($"xcSettingsPath: {xcSettingsPath}");
    20.         // change the xcode project to use the new build system, without doing this can not compile and get an error in xcode, plus the legacy build system is now deprecated
    21.         var xcSettingsDoc = new PlistDocument();
    22.         xcSettingsDoc.ReadFromString( File.ReadAllText( xcSettingsPath ) );
    23.         var xcSettingsDict = xcSettingsDoc.root;
    24.         var xcSettingsValues = xcSettingsDict.values;
    25.         var buildSystemTypeKey = "BuildSystemType";
    26.         if ( xcSettingsValues.ContainsKey( buildSystemTypeKey ) ) {
    27.             xcSettingsValues.Remove( buildSystemTypeKey ); // the removal of this key/value pair <key>BuildSystemType</key><string>Original</string> allows xcode to use the default new build system setting
    28.         }
    29.         File.WriteAllText( xcSettingsPath, xcSettingsDoc.WriteToString() );
    30.         #endif
    31.     }
    32. }
     
  3. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,628
    Thanks for the report, we'll take a look.
     
  4. jason_yak

    jason_yak

    Joined:
    Aug 25, 2016
    Posts:
    514
    Thanks
     
  5. jason_yak

    jason_yak

    Joined:
    Aug 25, 2016
    Posts:
    514
  6. UDN_1d6073f0-17dc-4ebc-a226-cbad814aa912

    UDN_1d6073f0-17dc-4ebc-a226-cbad814aa912

    Joined:
    May 17, 2017
    Posts:
    1
    I'm having the same issue #2 here, but with CloudKit. Looks like there's no way to get the GameAssembly build step to reference additional frameworks?
     
  7. jason_yak

    jason_yak

    Joined:
    Aug 25, 2016
    Posts:
    514
    A workaround is to use plugin bundles which is a bit more mucking around, so if you create a new Xcode project choosing macOS > bundle and set this up with the iCloud framework I can confirm it works. It's the same kind of workflow that is required if you need to embed plugins in a Mono based project where you build directly to a mac.app file. But yes, it would be much simpler to be able to use native plugin scripts with IL2CPP xcode projects and should be doable.
     
  8. HWIvan

    HWIvan

    Joined:
    Jan 21, 2019
    Posts:
    12
    Yes this is really annoying. In my case I need to add a reference to AppKit.

    To do that we need to pass this to il2cpp:
    --linker-flags="-framework AppKit"
    .

    I tried using "PlayerSettings.SetAdditionalIl2CppArgs", but unfortunately that didn't carry across to the generated xcode project. Not sure if this is a bug or not.

    What we need to do is modify the IL2CPP script phase in the xcode project to add the extra args we need. Unfortunately "UnityEditor.iOS.Xcode.PBXProject" is too limited to do what we want, so I had to patch the xcode project manually. In a post-build step, before running "xcodebuild" I added this:

    Code (CSharp):
    1.  
    2. private static void PostProcessBuildMacosHaxPbxProj(string pathToPbxProjFile)
    3. {
    4.    const string LineFind = "\t\t\tshellScript = ";
    5.    const string FindValue = "--profiler-report";
    6.    const string ReplaceValue = FindValue
    7.        + " --linker-flags=\\\"-framework AppKit\\\"";
    8.  
    9.    var pbxLines = File.ReadAllLines(pathToPbxProjFile);
    10.    for (var i = 0; i < pbxLines.Length; ++i)
    11.    {
    12.        var shellLine = pbxLines[i];
    13.        if (shellLine.StartsWith(LineFind, StringComparison.InvariantCulture) && !shellLine.Contains(ReplaceValue))
    14.        {
    15.            shellLine = shellLine.Replace(FindValue, ReplaceValue);
    16.            pbxLines[i] = shellLine;
    17.            File.WriteAllLines(pathToPbxProjFile, pbxLines);
    18.            return;
    19.        }
    20.    }
    21. }
     
    Last edited: Sep 17, 2021
  9. andresprog

    andresprog

    Joined:
    May 21, 2017
    Posts:
    2
    It works for me, thank you!!
    I had to change the string {buildFolderName} by Unity-iPhone.
     
  10. HWIvan

    HWIvan

    Joined:
    Jan 21, 2019
    Posts:
    12
    Happy to report that in Unity 2021, doing something like
    Code (CSharp):
    1. PlayerSettings.SetAdditionalIl2CppArgs("--linker-flags=\"-framework AppKit\"")
    now works and carries across to the generated xcode project.
     
  11. kafloreshernandez

    kafloreshernandez

    Joined:
    Jul 31, 2023
    Posts:
    2
    Where are we supposed to write this on?
     
    sd_trent and Nightshade6 like this.
  12. Nightshade6

    Nightshade6

    Joined:
    Oct 5, 2021
    Posts:
    1
    Did you find this solution?
     
    sd_trent likes this.