Copy files to bundle depending on active configuration
Asked Answered
S

5

35

is it possible to control which files are copied to the bundle depending on the active configuration? I don't want to add another target for this, so this not an option.

The real life example is a splash video which is in fact 8mb in size and is long. Every start of the app shows this video which is annoying. I don't want to break too much code so the solution is a very short splash video, which is the candidate to be copied to the bundle when the debug configuration is active.

Yes, I could make the debug video very small so it doesn't hurt if it is shipped with the release but for the sake of learning new things I need a way to control which file is copied depending on the configuration. I suppose a Run Script would do this, but maybe there is a simple solution which I don't see.

Thanks in advance!

Seethe answered 22/3, 2011 at 9:37 Comment(2)
A good question, and if I am asked, I would say no. I am just doing this for a customer and I'd like to protect my sanity from this video so there is no real choice :)Seethe
I understand your point, and it's nice question to find out. This should reduce the build time a lot after cleaning up the target too.Will
S
36

I didn't find any better solution than using a Run Script. Best reference is Copy file to the App Resources directory if debug configuration is selected.

I solved my problem with this run script:

RESOURCE_PATH=$SRCROOT/ResourcesCopiedByRunScript

FILENAME_IN_BUNDLE=splashVideo.mp4

BUILD_APP_DIR=${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}

if [ "$CONFIGURATION" == "Debug" ]; then
    cp "$RESOURCE_PATH/shortDebugSplashVideo.mp4" "$BUILD_APP_DIR/$FILENAME_IN_BUNDLE"
else
    cp "$RESOURCE_PATH/productionSplashVideo.mp4" "$BUILD_APP_DIR/$FILENAME_IN_BUNDLE"
fi
Seethe answered 24/4, 2011 at 13:10 Comment(4)
Does this then put the file in the "Copy Bundle Resources" place under Build Phases? I'm trying it out and not seeing my test file show up there.Lazurite
It's been a while since I answered myself, but I assume it is not placing the file in that particular list. It will copy the file directly to the bundle. Best explored with the simulator.Seethe
Right. I noticed the the files are indeed included in the bundle but do not show up in the "Copy Bundle Resources" place under Build Phases. Thanks for the solution though!Lazurite
My paths contained spaces, which made cp choke. Edited the code with a fix.Minatory
M
20

The best way to do it using Exclude Source File Names under Build Settings as it shown in the image.

enter image description here

Moria answered 7/11, 2018 at 7:15 Comment(2)
No need of scripts, build phase, Xcode default option.Lillia
Perfect, this was by far the easiest solution. No need for a script.Preconceive
H
4

If you can give the two different files the same name, you can put them in the build products folders for the appropriate configuration. Then add one of them to the project, and make it a reference relative to the build product.

If you want to have the files live elsewhere, you can put symbolic links in the build products folders. But I'm not sure if it would work if the files have different names but the symlinks have the same name.

I've done this trick on Mac projects, I'm assuming it would work for iOS too.

Edit: Here's an example of something I've done: I want the debug build of my app to link against the debug build of a certain library, and I want the release build of the app to link against the release build of the library. So I put the debug library (or a symlink to it) into the Debug subfolder of the app build folder, and I put the release library into the Release subfolder of the app build folder. Then, when I add the library to the project, I specify that the reference is "relative to build product".

Homophone answered 29/3, 2011 at 6:8 Comment(3)
I'm a bit uncertain how to do what you suggested. Can you give some kind of example?Seethe
What happens when you clean your build?Johnsen
@Justin: Good point, that wipes out the symlinks... actually, I have a script build phase that creates the symlinks.Homophone
B
0

You can replace one file to another using run script before compile step

RESOURCE_PATH=$SRCROOT/SampleProject/SupportingFiles/

LICENSE=license.txt
LICENSE_PROD=license_prod.txt

if [ "$CONFIGURATION" == "Release" ]; then
cp $RESOURCE_PATH/$LICENSE_PROD $RESOURCE_PATH/$LICENSE
fi
Bolo answered 3/11, 2018 at 9:25 Comment(0)
U
0

Some necro here, because I managed to do it without having to disable sandboxing on modern macOS versions. The use case is very basic, and I struggle to understand why it's got to be so hard to do, but anyways.

So I have a .metallib (Metal shader libraries) to include in my project, and it comes in Debug and Release forms, and I am loading the library from the bundle, so I need to copy the right one in the bundle depending on the configuration.

So what I did is add a Run Script build step BEFORE the Copy Bundle Resources step. The command:

cp $MYLIBRARY_DIRECTORY/bin/lib/ios/$CONFIGURATION/MyShaders.metallib $BUILD_DIR/

Note that $MYLIBRARY_DIRECTORY is a location (Xcode -> Preferences -> Locations -> Custom Paths).

For proper dependency resolution, you can add that in the Input File: $(MYLIBRARY_DIRECTORY)/bin/lib/ios/$(CONFIGURATION)/MyShaders.metallib (parentheses this time, but should not be in the build script).

And this in the output: $(BUILD_DIR)/MyShaders.metallib

Now you need to build once and find where that file was copied, from the build log. It will look like: /Users/<your user name>/Library/Developer/Xcode/DerivedData/<project name>-abunchofweirdcharacters/Build/Products/MyShaders.metallib

Locate it from the Finder (Cmd+Shift+G -> paste the path -> Enter). Drag and drop the file into your project. Select it and reveal the inspector on the right. From the Location drop down, select Relative to Build Products. The line below should now read `../MyShaders.metallib.

Now, you can open the Copy Bundle Resources step from the Project configuration -> Build Phases page. Click on the + button and add the file that you just added on the project (MyShaders.metallib). Launch a build, and it should work.

Inspector view when selecting the .metallib file Project configuration screen

Urushiol answered 22/7, 2024 at 3:14 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.