May I use a settings bundle in xcode which is not called Settings.bundle?
If I have multiple settings bundles (for multiple build targets), must I define these additional names anywhere? My application seems to always look for one called Settings.bundle.
For those of you who aren't good at shell scripts, here's a template version of what I used. In addition to a Debug and Release build, we also had a Debug-Special build with its own Info.plist in the build settings, and a different Settings.bundle/Root.plist file. I created copies of the Setting.bundle/ folder to Settings(original).bundle and Settings(special).bundle and added this script to the pre-build:
subdir="original" ; [[ $CONFIGURATION = "Debug-Special" ]] && subdir="special" ; cp "$SRCROOT/Settings($subdir).bundle/Root.plist" "$SRCROOT/Settings.bundle/"
Be sure to select your project to add the environment variables to the shell that runs the script.
I realize the thread is pretty old in code years but it is still relevant, and hopefully this will save the next person who finds it some time.
Solved this by adding a script in pre-build where the alternative bundle is renamed to Settings.bundle
Related
I'm working with some third party tools that generate xcode project files for a few subcomponents. Their tools generate the project files with Generate Position-Dependent Code set to YES (potentially because the tool generates project files for OS X builds too and the latest update has it confused).
While I could simply turn these flags off in the GUI, it's not as convenient as my build process is scripted to generate each project file, build it, move binaries around, lipo them together, etc.
I'm fairly sure these settings can be overridden on the command line, but I'm curious as to what the setting key actually is. For instance, I don't know if the setting=value means that the setting name is verbatim to how it displays in Xcode (Generate Position-Dependent Code), as there are spaces in it.
If anyone can provide a listing of all settings that can be passed to xcodebuild, that would be super.
The setting name is actually GCC_DYNAMIC_NO_PIC. "Generate Position-Dependent Code" is just the description.
For future reference, when I copy (Command+C) that setting when it is highlighted in project Build Settings...
...then paste into Text Edit I see the actual command line setting key.
//:configuration = Debug
//:configuration = Release
//:completeSettings = some
GCC_DYNAMIC_NO_PIC
That works for all build settings, too.
Xcode can't find my Storyboards and my Info.plist in my Copy Bundle Resources, So my App doesn't run. I tried to add the Existing files again but they always appear red highlighted. I'm pretty sure it must be a local problem because when i clone the latest update from my repository on my other mac its runs without any problems. I already tried to re-install Xcode, delete files from Xcode/DerivedData and i also deleted the com.apple.Xcode.plist.
Anyone any ideas?
Try to reset your Simulator and then clean your App Build Folder
My experience is that the proposed solution works, but cleaning and re-compiling the entire app whenever a resource has changed is very tedious, especially for larger projects.
Therefore I came up with this solution that forces fresh resources in the app on a per-directory basis, without having to clean or recompile:
Add a 'Run Script Build Phase' (Editor > Add Build Phase > Add Run Script Build Phase)
Copy/paste the following script into the build phase (don't forget to set the actual paths on line 1):
dirsToCopy=("path1/directory1","path2/directory2")
for INPATTERN in "${dirsToCopy[#]}"; do
INDIR=$PROJECT_DIR/$INPATTERN/*
OUTDIR=$TARGET_BUILD_DIR/$CONTENTS_FOLDER_PATH/$INPATTERN
cp -R $INDIR $OUTDIR
done
For those not used to working with shell scripts:
paths on line 1 of the script are relative to the project directory (where the .xcodeproj file resides)
you can add more (or less) paths to the array dirsToCopy if you want
you can change the pattern of files to copy where variable INDIR is defined
you can change how the copying is done (currently, recursive due to -R) by changing the flags to cp in the last line of script within the for block.
I have some large resources that I only need for my simulator runs—I'd like to have them automatically excluded from all device builds. Is there any way to do this with Xcode 4 short of custom build scripts that copy the resources?
I went with a Run Script phase with the following:
if [ ${PLATFORM_NAME} != "iphonesimulator" ]; then
echo "device build -- removing resources..."
rm "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/test_a.mp3"
rm "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/test_b.mp3"
# reveal the binary in the Finder
/usr/bin/open --reveal "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
else
echo "simulator build..."
fi
Targets dictate what's included in a product. Duplicate your target and create a scheme for it. Modify that target's membership.
Art's answer works well.
I'm adding this alternative answer because I have certain requirements and I found a solution that addresses those.
In my case, I need some large resources to be only in some test builds, but I don't want them to be included in the project or checked in with project. I also want to avoid Xcode pointlessly copying a large file from one folder to another during the build.
My solution is as follows:
Create a new folder on disk under your Resources/ folder, titled FolderLinkedResources.
Add a folder reference to this folder in the Xcode project.
This is a link to an actual folder on hard disk, rather than a project folder group. You do it via an option in the Add Files dialog:
Then at build time I have a custom build phase script (placed earlier than compilation) that hard-links the required resource file into the referenced folder on disk:
# COPY_SPECIAL_RESOURCES is only defined in schemas where I require the special resource(s).
# SpecialResources folder is a sibling folder alongside my entire Xcode project folder
if [ ${COPY_SPECIAL_RESOURCES} == "1" ]; then
ln ../SpecialResources/mySpecialResourceFile.bin Resources/FolderLinkedResources/
fi
Now the build will include your special resource.
Note that since the resource file is inside a folder reference in the project, the built app will actually contain the resource file in a folder, rather than at the top level. This means that the usual call to retrieve your resource will not work:
NSString *resourcePath = [[NSBundle mainBundle]
pathForResource:#"mySpecialResourceFile"
ofType:#"bin"];
To fix this, you need to also provide the folder name containing the resource:
NSString *resourcePath = [[NSBundle mainBundle]
pathForResource:#"mySpecialResourceFile"
ofType:#"bin"
inDirectory:#"FolderLinkedResources"];
Note: this technique also works well for when you don't actually know what the resources are until build time! As long as your script step hard-links in the files, they will make it into the build.
In the interests of tidyness and sanity, I include a run script build phase that happens after the compilation, which clears out the hard link:
if [ ${COPY_SPECIAL_RESOURCES} == "1" ]; then
rm -rf Resources/FolderLinkedResources/*.*
fi
Finally, in case anyone is interested in my actual use case for this: I have pre-recorded HTTP communications data for certain offline test builds of my app. This data is in no way a part of the core app, so I don't want it checked in with app itself, or part of the project by default.
Custom build scripts is your best friend in Xcode. Have the script delete the resource after the build and before the code sign.
I have a fairly complex (iPhone SDK) Xcode project, with many targets -- 4 static libs, unit tests, multiple sample apps, a BuildAll that runs a shell script, and a Package that runs another shell script. The "BuildAll" target creates a directory in the project with some subdirectories with contents ready for distribution.
When I click "Clean All," though, Xcode doesn't know to clean my Distribution directory. I'd like it to. I can't seem to find a way to do this -- does anybody know how?
It feels like Clean and Clean All should really just be targets in Xcode, and I should be able to add a "Run Script" phase. Not so, to my knowledge.
BTW, the "BuildAll" target does handle cleaning the Distribution directory, so this is not the end of the world to me. It's just irksome that "Clean All" doesn't actually clean all in my particular case.
You can try to Add > New Target… > Shell Script Target by control-clicking on a Targets node in the Groups & Files.
Then, after double-clicking on a Run Script node you setup any cleanup-scenario using $ACTION variable that can have values clean, install, etc.
And finally, newly created Shell Script Target should be added to the main target as dependency.
You can add an "External Target" that does the cleaning in an external script, and add that target as a dependency of one of your static library targets. Create the target, and drag it under one of your static library targets. Check for the action using the $ACTION environment variable in the script.
I have a bunch of content files for my iPhone app that I generate via shell script. It takes way too long to be a part of the Xcode build process, so I run it periodically.
I don't want to have to continually add these files to my Xcode project in order to get them included my app resources folder. Is there a way to get Xcode to copy the contents of a folder into the app resources at build time? (It'd be a bonus if I could specify other locations, such as the approot documents folder.)
I tried adding a new 'Copy Files Build Phase' to my target, but that didn't seem to work. This seems like a common problem, but I couldn't find anything about it here.
-- Edit (What I did)
Per Jasarien and cdespinosa's suggestions, I did the following in a build script. I decided not to copy to the destination, because that would only work when using the simulator, I don't think that'll work when deploying to a device.
cp -rf "$PROJECT_DIR/mystuff" "$CONFIGURATION_BUILD_DIR/$CONTENTS_FOLDER_PATH/"
-- Edit 2
This doesn't appear to get files onto my iPhone. Any ideas?
You can setup a Run Script build phase in your app's target. Write the script so that it copies the resources into the app bundle.
This is the path i use for output:
${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}
Just copy your files in that directory, it's the bundle (simulator or device).
You can also take a look at my answer here : how to set up a Xcode build rule with a variable output file list?