I have a project which won't Archive-build correctly in Xcode 4. It appears to me that the "Build For Archiving" and "Archive" commands build differently, and I cannot determine any reason why!
Details:
The workspace contains two projects: an app and a static library; the projects are arranged as peers.
"Build" and "Run" both work correctly; app executes in iOS simulator and on device.
"Build for Running", "Build for Testing", "Build for Profiling", and "Build for Archiving" all work correctly also.
Build for Running is debug, Build for Profiling is release, so both configuration have been tested.
"Archive" fails!
Failure 1 (Library):
When I try to execute the "Archive" command on the library, a custom resource script fails. The script is reading from the resources directory ($RESOURCES_DIR)
For release builds, this maps to:
...DerivedData/App-uniquecrap/Build/Products/Release-iphoneos/Resources/LibraryName
For the archive, this maps to:
...DerivedData/App-uniquecrap/ArchiveIntermediates/Build Frameworks/BuildProductsPath/Release-iphoneos/Resources/LibraryName
Except Resources is missing in the ArchiveIntermediates tree!
UPDATE: The first part of the problem is caused by poor quoting in the script file. Xcode4's paths now include a folder with an embedded space (imagine that!) and improperly quotes paths don't work as well as we would like. That fixed, I still have the problem that the resource files copied by the Gather Resources build phase are not going to the correct location; the script expects them in $(RESOURCE_DIR), but I can't seem to find the correct setting in Gather Resources to send them there. Suggestions?
Failure 2 (App):
When I have managed to kludge my way part the first failure (typically by copying files and bypassing the script), I run into another error building the App. "Archive" complains that it can't find imported files when building the precompiled headers.
Nothing unusual here either; headers are imported in pch file in the typical manner:
#import <LibraryName/Library.h>
As before, "Build", "Build for Archiving", etcetera succeed without problem. "Archive" fails. Either the include paths are set up correctly and "Archive" is ignoring them; or the include paths are set up incorrectly and Xcode is auto-magically fixing them in the other builds. (Either way, I'm very frustrated).
How can I (A) make Archive builds work; or (B) figure out what is going on, so I can accomplish (A)?
Thanks.
Related
I have an error 'Lexical or Preprocessor Issue Group' with building xcode project after have built from Unity.
'UnityFramework/UnityFramework-Swift.h file not found'
I have Nice Vibration asset and FB SDK in my project. So I tried to follow this instructions in 'Building for iOS' section, but have no result https://nice-vibrations-docs.moremountains.com/platform-specifics.html#building-for-ios
I makes it with .xcworkspace, not .xcodeproj file. I have read it's right way because of FB SDK needs CocoaPods build pipeline and I should use .xcworkspace. And it's happens in XCode 12, if it matters.
What could be wrong? I spent a few hours and so still there, where I have been :(
I also ran into this issue today (although because of the Firebase SDK, not FB).
The problems seems to be with the post-build processor, which modifies the output XCode project. The NiceVibrations implementation currently only copies a single file (module.modulemap) to the build directory. Instead, we need the entire NiceVibrations/Common/Plugins/iOS/Swift directory to be copied over.
While I can't publish the entire file, I will share my modifications with you for automating this process.
Open the following file:
NiceVibrations/Common/Scripts/Editor/MMNVBuildPostProcessor.cs
Locate the WritePropertiesToFramework function and replace:
System.IO.File.Copy(privateModuleFilepath, destination);
With this:
DirectoryCopy(Path.GetDirectoryName(privateModuleFilepath), Path.GetDirectoryName(destination), true);
You can find the source code for the DirectoryCopy function from the Microsoft dotnet docs here
Edit: You will have to change the second argument of file.CopyTo to true to allow for subsequent rebuilding atop the same directory to avoid runtime errors
Additionally, I have increased the callbackOrder to 60 to ensure that this hook runs last.
I am personally using .xcodeproj instead of workspaces, but it should work fine with workspaces as well. (Firebase uses something called External dependency manager which allows you to configure your project generation preference)
After making these changes, trigger a build from unity and "replace" the target folder to update your XCode files!
I have a module/framework written in Swift, intended to be used on iOS. When I try to include the framework in my app, I first notice some red "not found" hints in the build phases:
But, the project builds fine - the target dependency is found, so there are no compilation issues. It's just the resulting built framework - and sure enough, upon launching, I have a linker error, it can't find the image. Looking at the build log, it's looking here:
/Users/Craig/Projects/Fluffy/build/Debug-iphoneos/
Which makes sense - that's what is defined in the Build Settings for my framework:
But the copy fails, as the source framework doesn't exist:
PBXCp /Users/Craig/projects/Fluffy/build/Debug-iphoneos/Fluffy_iOS.framework /Users/Craig/Library/Developer/Xcode/DerivedData/MyApp-dcjfhcnyzkwzxiejuuxqlsgajreb/Build/Products/Debug-iphoneos/MyApp/Frameworks/Fluffy_iOS.framework
...
error: /Users/Craig/projects/Fluffy/build/Debug-iphoneos/Fluffy_iOS.framework: No such file or directory
However, looking at the build log for my framework, I see that it's actually ending up here:
/Users/Craig/Library/Developer/Xcode/DerivedData/Fluffy-fuuewsvogdkycegheyrsabkiicxc/Build/Products/Debug-iphonesimulator/Fluffy_iOS.framework
I suppose that makes sense - DerivedData has for a while now been the default location for any built products.
And when I take a look at the expected build folder, there's not much, a lot of it is old, and none of it relates to the Debug configuration:
So my questions are: Why is my framework being placed in the DerivedData folder, when it seems to be asking in the Build Settings to be placed in the build folder relative to the project? Are these parameters (per-configuration build products path, etc.) consulted at all?
And, what should I do to reconcile this? How can my application know to look in the right DerivedData folder for the framework, for the right configuration (debug vs. release) in a way that is extensible and will work without me having to manually specify the absolute path to it?
Okay, so I figured out how to work around this. This assumes you have workspace and you have included the framework as a project in the workspace and you are trying to build a product from another project in the workspace which includes the framework.
What you need to do is find out where the framework is being built. It's usually some crazy directory under the DeriveData directory. Go to the Finder and find it for the configuration you just tried to build.
In the product target's General settings, under Embedded Binaries, drag that file into it. This should now place it in the Project Navigator. You should also see it in the Linked Frameworks and Libraries which was underneath Embedded Binaries.
Go to the Project Navigator and select the file and view it under the File Inspector. There, change the Location to Relative to Build Products.
In the target's Build Settings, for Framework Search Paths, add $(BUILT_PRODUCTS_DIR) and make that recursive. Delete the entry that was automatically added when you added the framework. It will be an explicit path which has the DerivedData path in it.
Do a deep clean and delete the DerivedData directory for good measure.
Build.
You should now see the framework turn black and it should work properly.
These are slightly modified steps provided by #Mobile Ben
Assume, you have the following Xcode project structure
-YourWorkspace
--YourFramework project
--YourApp project
step 1. Clear all the targets with Cmd+Shift+K and Cmd+Option+Shift+K (by choosing each of them in the Scheme selector and pressing the hotkey combination)
step 2. Select YourFramework project.
step 3. Choose a simulator and build (Cmd+B) YourFramework framework target
step 4: Choose Generic iOS Device and build (Cmd+B) YourFramework framework target
step 5: Select YourApp project. Press + in Embedded Binaries and choose the framework under YourFramework project
step 6: now locate the just added framework in Project Navigator (on the left). In File Inspector (on the right) select location Relative to build product.
NOTE: I believe the step 6 is required b/c of some bug in Xcode. But, though, not selecting Relative to build product by default might be a deliberate act
UPD#1: Since Xcode 8.0 (8A218a), step 6 is not needed anymore - the IDE sets Relative to Build Products automatically.
In addition to the above answer which works perfectly on Simulator. On device you will get dyld library not found error and a crash.
Here is the solution for that:
In the project that depends on this framework:
Under the build settings: Add a copy files phase and add this framework to the 'Frameworks' folder in copy file phase.
I have a workspace, Application.xcworkspace, that builds two frameworks and an executable that uses those frameworks. Here is roughly how they are laid out:
Framework_1 - Built and output to ugly DerivedData path.
Framework_2 - Depends on Framework_1, which is included in the Frameworks area of the project and specified in the "Link Binary with Libraries" Build Phase, and output to ugly DerivedData path.
Application - Depends on Framework_1 and Framework_2, which are included in the Frameworks area of the project and specified in the "Link Binary with Libraries" Build Phase. Output directory is again that ugly DerivedData path.
The problem I have is that the paths in the project file for the referenced frameworks are the DerivedData ugly path - they are like ../../Library/Developer/XCode/DerivedData/Application-longuglyuniquestring/Build/Products/Release/Framework_1.framework.
If I copy the source to another directory, or check it into version control and check it out to another machine, then those framework paths are no longer valid. They get re-generated. The referenced frameworks show up as red in the project.
So far, when I want to build the workspace in another folder, the way I have fixed the problem is to:
Build the workspace - Framework_1 builds.
Go to the "Products" node for that framework and show it in Finder.
Copy the new ugly path.
Open the project files for Framework_2 and Application and correct the path for Framework_1 and Framework_2.
All the red items should be resolved and everything should build.
That process is tedious and I am lucky the project file can be edited. It is worse for colleagues that do not understand the little I know about the project files, and just want to check the code out and have it build.
Is there something I need to do to the Build Output Directory for the frameworks? I have been leery of changing it since the ugly path is recommended. Is there a copy files option I can use to put those frameworks in some predictable location relative to my workspace?
Any help would be appreciated. I am sure I am missing something simple - it makes no sense that code checked out of source control or copied to another directory would not just build.
Looks like there is a way to set the DerivedData directory on a per-workspace basis - Xcode 4 - build output directory
I just set DerivedData to be relative to my workspace, then edited the project files accordingly. The only down-side is if I were to use one of those projects in another workspace that was using the default DerivedData path, I would have to change them back.
Many thanks to user DaGaMs - he got an upvote.
I am still seeing bad behavior from XCode 5: I got the project working on my machine. Copied it to another, lower, directory and verified it still worked. Exited XCode and copied the containing directory to a network drive, and from there onto another Mac. When I opened it on the other Mac it was like I never made some of the changes. Even worse, as I worked to fix it, XCode went nuts and added 6 extra '\' characters to each end of my FRAMEWORK_SEARCH_PATHS paths!
Part of the problem stems from the subproject directories in my app being absolute rather than relative. The projects in the top of the workspace are "Relative to Group", so I changed the subprojects to have the same attribute. That seems to have solved the problem, though for some reason when I copy all the files to another machine, the Derived Data redirection does not go with it.
I'm using Xcode 4.3.3. My project has 2 targets and they are very similar (one was a duplicate of the other). The only thing is they have different names and there is a small amount of #ifdef going on. One project compiles a few more files and copies a few more bundle resources than the other. Other than that they ought to be the same. It's like having Pro and Lite app versions.
I seem to have a few issues (building for one of the targets is absolutely fine, so all these issues relate to the 'other' target)...
When building the 'other' target it gives me the warning "Multiple build commands for output file...". It is referring to 'icon-72.png'. However, I've not only removed the second reference to that file (still got the warning), but I have also removed that file entirely and removed all references I could find for it, including deleting the icon from the Target Summary, ensuring the file doesn't exist in any project folder in Finder for this project, and also ensuring it's not listed in 'Copy Bundle Resources' in 'Build Phases'. The warning still appears.
When building the 'other' target it doesn't give me the usual warnings. These warnings should exist in both builds at this time. I have checked what is being compiled and the files that should generate these warnings are included in both 'Compile Sources' in both targets' 'Build Phases'.
Building the 'other' target gives me 'Failed'. However, in the Issue Navigator there is no explanation as to why it failed.
Incidentally, the 'other' target was the original one, not the new one.
Also, I have tried cleaning before each build attempt and have also restarted Xcode. I have recently restarted the computer too.
Any help or general pointing in the right direction would be greatly appreciated.
Atb.
EDIT....
I updated the project settings as prompted in the Issue Navigator to use LLDB. Now I don't get any warnings for either target, but the 'other' target still fails to build without reason.
Right. Well, it turns out that this was mostly the answer (check the last comment). I closed the actual Xcode window with my project in (cmd-W), then I went to File > Open and opened the project file from there (as opposed to opening it from the splash window or the recents list).
Now I can see the warnings and tell why the build is failing too. Phew!!
I've got a relatively large Xcode project that produces a single app. However, I have many clients/customers who require deep customization and branding of said app. These configurations include different graphics, a few different interfaces and implementations, and, perhaps most importantly, .xcconfig files.
My Xcode project has a dedicated group that points to a particular client's customization folder on disk, so by opening the Xcode project and building, you get a build of the single app with the current client's customizations. To switch to another client, I change where that group points to on disk. (I also change and switch-back the xcconfig "Based On" settings in the project's Info pane to reload the full xcconfig inheritance; Simply changing the group containing one or more xcconfig files doesn't reload this!) This has worked great for 100+ clients. It's a little tedious to switch this folder every time you need to build the app for a different client and ensure the xcconfig is correct, but it works.
Now I'm in the process of automating builds via the command line, and running into troubles. The quick and dirty solution to pointing the aforementioned Xcode group at a different customization folder was to copy the ProjectName.xcodeproj/project.pbxproj file to ProjectName.xcodeproj/project-template.pbxproj and put placeholders inside this file that can be grepped and replaced with the name and path of the desired customization folder. Then, temporarily overwrite project.pbxproj with the modified project-template.pbxproj, and build to get the correct app.
As you've probably observed, the project.pbxproj was duplicated and modified, and will therefore get out of sync as developers modify the original and forget to also update the template. And besides, I shouldn't really be messing with pbxproj files in this fashion anyway -- that's Xcode's private stuff.
So, is there a better way to tell Xcode about a folder full of resources, code, and config files perhaps during the Build Phase with a script or environment variable, rather than at the project group level? The most complicated bit seems to be the xcconfig chain, since each client has their own xcconfig file that inherits from the single app's Debug, Development, and Distribution xcconfig files.
Sorry for the long-windedness of this question, but it's a little complicated! Any suggestions would be greatly appreciated!
I think you would way better off using the targets feature in Xcode. Have one project and the resources of every clients in that project.
You can then duplicate the target you already have (right-click on your target, by selecting the project file in Xcode's Project Navigator).
All your targets will be compiled with the same code. You just need to change the resources in Build Phases > Copy Bundle Resources to have different app created for each target. No need to look at Xcode's internal files.
You can even change the code in your source files by adding a preprocessor macro in your build options (something like FIRST_CLIENT=1) and then look for these definition in your file with #if FIRST_CLIENT.
I have a project set-up like this and it works pretty well :