Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
4
Question by Simurr · Sep 30, 2015 at 08:33 PM · buildxcodeapicloudmanipulation

Is it possible to use the Xcode Manipulation API to add files to the Embedded Binaries build step?

I need to add a framework to the Embed Binaries build step in Xcode. I've asked this before but I think maybe my question was badly phrased or incomplete.

If this is easy, ignore the detailed description below. Thank you!

Within Xcode this is as simple as dragging your framework into the Embedded Binaries area in the targets General page.

embedded frameworks

This creates a build phase called Embed Frameworks

build step for embedding frameworks added

The project.pbxproj file changes are...

PBXBuildFile section reference added

         C5E4C9731BBC78F4007C4CD8 /* MyEmbedded.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C8FC40EFB7EB18859284D579 /* MyEmbedded.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
 

PBXCopyFilesBuildPhase section added

 C5E4C9741BBC78F4007C4CD8 /* Embed Frameworks */ = {
             isa = PBXCopyFilesBuildPhase;
             buildActionMask = 2147483647;
             dstPath = "";
             dstSubfolderSpec = 10;
             files = (
                 C5E4C9731BBC78F4007C4CD8 /* MyEmbedded.framework in Embed Frameworks */,
             );
             name = "Embed Frameworks";
             runOnlyForDeploymentPostprocessing = 0;
         };

PBXNativeTarget section changed to include Embed Frameworks phase

 1D6058900D05DD3D006BFB54 /* Unity-iPhone */ = {
             isa = PBXNativeTarget;
             buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Unity-iPhone" */;
             buildPhases = (
                 1D60588D0D05DD3D006BFB54 /* Resources */,
                 83D0C1FB0E6C8D5900EBCE5D /* ShellScript */,
                 83D0C1FD0E6C8D7700EBCE5D /* CopyFiles */,
                 1D60588E0D05DD3D006BFB54 /* Sources */,
                 1D60588F0D05DD3D006BFB54 /* Frameworks */,
                 033966F41B18B03000ECD701 /* ShellScript */,
                 C5E4C9741BBC78F4007C4CD8 /* Embed Frameworks */,
             );
             buildRules = (
             );
             dependencies = (
             );
             name = "Unity-iPhone";
             productName = "iPhone-target";
             productReference = 1D6058910D05DD3D006BFB54 /* awesumfree.app */;
             productType = "com.apple.product-type.application";
         };

Finally, and I'm not sure if this is required, XCBuildConfiguration section for all builds (Debug, Release etc.) sets this

 LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";

Hopefully this is detailed enough to get me an answer. I'd really love to be able to build this with Cloud Build but that will only work if I can set this stuff up in a PostProcessBuild function.

screen-shot-2015-09-30-at-31027-pm.png (279.1 kB)
screen-shot-2015-09-30-at-31059-pm.png (148.6 kB)
Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Simurr · Oct 06, 2015 at 04:29 PM 0
Share

Just adding a link to the forum thread. http://forum.unity3d.com/threads/is-it-possible-to-use-the-xcode-manipulation-api-to-add-files-to-the-embedded-binaries-build-step.358357/

8 Replies

· Add your reply
  • Sort: 
avatar image
3

Answer by mihakinova · Jul 07, 2017 at 09:54 AM

So after a lot of messing around I finally got this to work. This is basically what @tarasfromlviv wrote with a few modifications. Here's how to do it:

  1. Clone Unity's XcodeAPI: https://bitbucket.org/Unity-Technologies/xcodeapi (Note, it's a mercurial repository, not Git). I also changed the namespace of all the files to include my prefix, so I can distinguish it from the build in version, something like "Custom.UnityEditor.iOS.Xcode"

  2. To the PBXProject.cs file add the following method:

      public void AddDynamicFrameworkToProject(string targetGuid, string frameworkPathInProject)
         {
             var fileGuid = FindFileGuidByProjectPath(frameworkPathInProject);
             if (fileGuid == null)
             {
                 Debug.LogError("Framework not found: " + frameworkPathInProject);
                 return;
             }
             // add file reference as embed framework
             PBXBuildFileData embedFrameworkFileData = PBXBuildFileData.CreateFromFile(fileGuid, false, "");
             BuildFilesAdd(targetGuid, embedFrameworkFileData);
             // add "Embed Frameworks" section
             // TODO: check if exists
             PBXCopyFilesBuildPhaseData embedFrameworksSection = PBXCopyFilesBuildPhaseData.Create("Embed Frameworks", "", "10");
             embedFrameworksSection.files.AddGUID(embedFrameworkFileData.guid);
             m_Data.copyFiles.AddEntry(embedFrameworksSection);
             // add "Embed Frameworks" section to "Build phases"
             PBXNativeTargetData target = nativeTargets[targetGuid];
             target.phases.AddGUID(embedFrameworksSection.guid);
         }
    
  3. Add this to your build script:

        [PostProcessBuild]
        public static void OnPostProcessBuild(BuildTarget buildTarget, string path)
        {
            if (buildTarget == BuildTarget.iOS)
            {
                string projectPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj";
                     PBXProject pbxProject = new PBXProject();
                pbxProject.ReadFromFile(projectPath);
                     string target = pbxProject.TargetGuidByName("Unity-iPhone");
                // pbxProject.SetBuildProperty(target, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "YES");
                pbxProject.SetBuildProperty(target, "LD_RUNPATH_SEARCH_PATHS", "$(inherited) @executable_path/Frameworks");
     
                AddDynamicFrameworks(ref pbxProject, target);
     
                pbxProject.WriteToFile(projectPath);
     
                string contents = File.ReadAllText(projectPath);
     
                // Enable CodeSignOnCopy for the framework
                contents = Regex.Replace(contents,
                    "(?<=Embed Frameworks)(?:.*)(\\/\\* EXAMPLE\\.framework \\*\\/)(?=; };)",
                    m => m.Value.Replace("/* EXAMPLE.framework */",
                        "/* EXAMPLE.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }"));
     
                File.WriteAllText(projectPath, contents);
            }
        }
     
        static void AddDynamicFrameworks(ref PBXProject project, string target)
        {
            const string defaultLocationInProj = "Frameworks/Plugins/iOS";
            const string coreFrameworkName = "EXAMPLE.framework";
     
            string relativeCoreFrameworkPath = Path.Combine(defaultLocationInProj, coreFrameworkName);
            project.AddDynamicFrameworkToProject(target, relativeCoreFrameworkPath);
     
            Debug.Log("Dynamic Frameworks added to Embedded binaries.");
        }
    
    
  4. Replace "EXAMPLE" (and nothing else) in the code above to the name of your framework.

And voila, Unity will now add your framework to Embedded Binaries automatically!

I still, for the life of me, can't figure out why this is not natively supported...

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image dsarfati · Feb 01, 2018 at 10:56 PM 0
Share

Should "HondaProxy.framework" be "EXA$$anonymous$$PL$$anonymous$$framework"??

avatar image mihakinova · Feb 01, 2018 at 11:06 PM 0
Share

Correct, thanks, modified the example. Just a note, this is now mostly obsolete as Unity added a built-in way to add dynamic frameworks.

avatar image dsarfati mihakinova · Feb 02, 2018 at 04:25 AM 0
Share

I haven't found any other ways of doing CodeSignOnCopy, still using your regex above

avatar image mihakinova dsarfati · Feb 02, 2018 at 09:29 AM 0
Share

Hmm, CodeSignOnCopy should work automatically. If you check PBXProjectExtensions.AddFileToEmbedFrameworks you can see there's a codeSignOnCopy = true in there. There are a couple of other settings / properties I had to set to get it to work properly though. Here is an excerpt from my build script that adds the frameworks: https://pastebin.com/hqV$$anonymous$$SQgV

Btw, my frameworks are located in Assets/Plugins/iOS/EXA$$anonymous$$PL$$anonymous$$framework.

avatar image
1

Answer by tarasfromlviv · Jan 12, 2017 at 03:32 PM

So, clone Unity official XCode API and apply this modifications, this will basically add existing frameworks in your project to embedded binaries:

Inside PBXProject:

     public void AddDynamicFrameworkToProject(string targetGuid, string frameworkPathInProject)
     {
         var fileGuid = FindFileGuidByProjectPath(frameworkPathInProject);
         if (fileGuid == null)
         {
             Debug.LogError("GetSocial Framework not found: " + frameworkPathInProject);
             return;
         }
         // add file reference as embed framework
         PBXBuildFileData embedFrameworkFileData = PBXBuildFileData.CreateFromFramework(fileGuid);
         BuildFilesAdd(targetGuid, embedFrameworkFileData);

         // add "Embed Frameworks" section
         // TODO: check if exists
         PBXCopyFilesBuildPhaseData embedFrameworksSection = PBXCopyFilesBuildPhaseData.Create("Embed Frameworks", "10");
         embedFrameworksSection.files.AddGUID(embedFrameworkFileData.guid);
         m_Data.copyFiles.AddEntry(embedFrameworksSection);

         // add "Embed Frameworks" section to "Build phases"
         PBXNativeTargetData target = nativeTargets[targetGuid];
         target.phases.AddGUID(embedFrameworksSection.guid);
     }


Usage Example:

 static void AddDynamicFrameworks(PBXProject project, string target)
 {
     const string defaultLocationInProj = "Frameworks/Plugins/iOS";
     const string coreFrameworkName = "GetSocial/GetSocial.framework";
     const string uiFrameworkName = "GetSocialUI/GetSocialUI.framework";
     string relativeCoreFrameworkPath = Path.Combine(defaultLocationInProj, coreFrameworkName);
     string relativeUiFrameworkPath = Path.Combine(defaultLocationInProj, uiFrameworkName);
     project.AddDynamicFrameworkToProject(target, relativeCoreFrameworkPath);
     project.AddDynamicFrameworkToProject(target, relativeUiFrameworkPath);
     Debug.Log("GetSocial Dynamic Frameworks added to Embedded binaries.");
 }

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image dillon_yeti · Jan 27, 2017 at 07:17 PM 1
Share

Hey, that seems pretty helpful! Any chance of you submitting a pull request to the UnityTechnologies/Unity/XcodeAPI repo?

I tried adding your patch using the latest pull from their repo, but compiler complains that PBXBuildFileData. CreateFromFramework doesn't exist. Was that another method you added?

avatar image
1

Answer by zfavourite99 · Feb 08, 2018 at 08:10 AM

 #if UNITY_EDITOR_OSX
 
 using UnityEditor.iOS.Xcode;
 using UnityEditor.iOS.Xcode.Extensions;
 
 #endif
 
 public class TestBuildPostprocessor {
     [PostProcessBuildAttribute(1)]
     public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) {
         
         if (target != BuildTarget.iOS) {
             UnityEngine.Debug.LogWarning ("Target is not iPhone. XCodePostProcess will not run");
             return;
         }
 #if UNITY_EDITOR_OSX
         //EmbedFrameworks
         string projPath = PBXProject.GetPBXProjectPath(pathToBuiltProject);
         PBXProject proj = new PBXProject();
         proj.ReadFromString(File.ReadAllText(projPath));
         string targetGuid = proj.TargetGuidByName("Unity-iPhone");
         const string defaultLocationInProj = "Plugins/iOS";
         const string coreFrameworkName = "test.framework";
         string framework = Path.Combine(defaultLocationInProj, coreFrameworkName);
         string fileGuid = proj.AddFile(framework, "Frameworks/" + framework, PBXSourceTree.Sdk);
         PBXProjectExtensions.AddFileToEmbedFrameworks(proj, targetGuid, fileGuid);
         proj.SetBuildProperty(targetGuid, "LD_RUNPATH_SEARCH_PATHS", "$(inherited) @executable_path/Frameworks");
         proj.WriteToFile (projPath);
         //EmbedFrameworks end
 #endif
     }
 }

this code work for me!

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image mihakinova · Feb 08, 2018 at 01:10 PM 0
Share

Just an FYI, you don't need #if UNITY_EDITOR_OSX to use the Xcode manipulation framework. You can use it on windows just fine, and unity will be able to generate the Xcode project (afaik), you just won't be able to build it to an IPA file.

avatar image
-1

Answer by unity_GYs5GCE8dSeS8A · Jun 15, 2019 at 07:02 AM

@mihakinova

I use your file for adding Embedded Binaries file. But recently I have a framework which used alias files. When xcodeproj got ready I see just one alias file on my framework folder. The framework which I tried to add is Pushwoosh. Do you have any idea how should I do it?

Thanks for your consideration

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by David-Berger · Oct 06, 2015 at 03:56 PM

It does not look like this is possible yet via XCode Manipulation API, but it could be added as it's open source.

Edit: The forum thread is here: http://forum.unity3d.com/threads/is-it-possible-to-use-the-xcode-manipulation-api-to-add-files-to-the-embedded-binaries-build-step.358357/

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
  • 1
  • 2
  • ›

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

13 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Bluetooth Description in Xcode 0 Answers

Distribute terrain in zones 3 Answers

Is the Cloud Build API key machine specific? 0 Answers

unity is not creating build on .NET 2.0 SUBNET and getting ArgumentException. 1 Answer

Xcode build & run "innocent" (?) problem 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges