Reputation: 1846
I am having a problem with the "Link Binary with Libraries" and "Copy Files" paths in my workspace when I try to build for different configurations - "Debug" and "Release" Those paths are stored in the pbxproj file of the xcodeproj package and do not vary with build configuration.
I have a workspace, Application.xcworkspace, that builds two frameworks and an executable that uses those frameworks. My Derived Data Location is set to "Workspace-relative" Here is roughly how they are laid out:
Framework_1 - Built and output to the Derived Data 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 Derived Data 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 the Derived Data path.
The paths in the project file for the referenced frameworks are the Derived Data path - they are like
Workspace Path/DerivedData/Workspace Name/Build/Products/Debug/Framework_1.framework
That path is the same regardless of what I build for - running (debug), testing (debug) or profiling (release).
My problem is when I build for profiling (release), the paths to the frameworks are still the debug paths, and thus the release version of the app links to debug frameworks and the debug frameworks get bundled into app->Contents->Frameworks (via a Copy Files build phase). Even worse, if I do a Clean, or delete the Derived Data directory, and try to build for profiling (release), it will not build or run because the referenced files (debug) do not exist.
I know one way to do make this work is to have two workspaces - one for debug and the other for release. That would be a big hassle.
Would another way to do it be to have another target?
What is the correct way to resolve this issue? Any help appreciated.
Upvotes: 0
Views: 3305
Reputation: 417
I made a script via your idea. You even don't need to change DerivedData location( set to Default Location ).
Paste command below
if [ -n "${SRCROOT}" ] && [ -n "${FULL_PRODUCT_NAME}" ] && [ -d "${SRCROOT}/../Frameworks/${FULL_PRODUCT_NAME}" ]; then rm -rf "${SRCROOT}/../Frameworks/${FULL_PRODUCT_NAME}"; fi
if [ -n "${BUILT_PRODUCTS_DIR}" ] && [ -n "${SRCROOT}" ] && [ -n "${FULL_PRODUCT_NAME}" ]; then cp -aR "${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}" "${SRCROOT}/../Frameworks/"; fi
close & enjoy
Upvotes: 2
Reputation: 1846
I think I figured out a fairly clean way to get this problem solved.
My first stab at it was two targets - one set up to link to and copy the debug framework, the other to do the same with the release framework. Very much a hack and the output from the second target had a different name, and each of the targets still had the original problem. However, I could get the same app functionality with a separate configuration build of the framework (Debug with Debug, Release with Release).
I then stepped back to think about the problem, and realized I just needed a single directory to house the link-to and copy-file version of the framework, but I needed to populate it differently depending on configuration. That made me think of scripts, and that worked out. I ended up adding a pre-action Run Script Build Phase to clean away any old copies of the framework and copy in the correct one. Here is the script for a framework called Simple.framework where the DerivedData location is Workspace-relative:
rm -R "${SRCROOT}/../Frameworks/Simple.framework"
cp -R "${SRCROOT}/../DerivedData/TestTarget/Build/Products/${CONFIGURATION}/Simple.framework" "${SRCROOT}/../Frameworks/Simple.framework"
So, for my project outlined above, I would put a phase like that for each of the frameworks in the app Build Phases.
Upvotes: 2