[UPDATE 03/04/2015]
The question is now 4 years old, and applies to a specific version of XCode which I have now specified in the subject.
I have searched a lot for this argument, but I couldn't find a solution, I even post on stackoverflow, but I soon deleted the question becuase of very little access.
Now I am trying again.
I have a workspace with two distinct projects A and B.
B has two targets, one that build a static library Blib.a, and one that build a bundle B.bundle. All of them get built in the derived directory.
In project A I can easily add the static library from the build phases. However I cannot find a way to include the bundle. B.bundle is not visible from "copy resource" tab in A.
Therefore I need to add manually, with all that implies.
I also thought about using a script, but I would like to use this as a very last option.
Has someone a solution for this ? Did I miss something ?
thanks
After long investigation, it came up there's no easy way of doing this. The B.bundle is never visible to A project, and there's no settings in workspace to change that.
At this point there are three solutions:
Include the bundle manually from "copy resources->other", I started with this, but everytime there's a change you have to drop and include the bundle again
Create a script to be run in build phase, if everything is built into the PRODUCTS dir you can find the bundle easily and having copied automatically into the app.bundle. This is not a bad solution. If you are using svn the script got included in project, and users have it for free without additional work.
As suggested by Apple tech support, use folder references.Build bundle B into a folder and add such folder to project A using the "Create Folder References for any added folders" option. Xcode 4 will update your bundle into that folder every time you built it.
The added folder will appear as blue once included in your project A.
Thats's it, I personally use the script, because this solution is path independent if you use standard xcode reference variable such as BUILT_PRODUCTS_DIR and so on, and the shell script is just a cp -r-f
[UPDATE 03/04/2015]
I would like to point out that the question is now 4 years old. At that time there weren't many "official" options available. I even spoke with Apple Tech Support, which proposed solution 3 as the only available solution. It is of course very likely that things are now changed, and there is a much better solution. Just to speak, I also like to add that the three above are not "hacks" but "solutions", maybe technically outdated, but they can still be used nowadays. I intend a "hack" as a..."hack", which means it probably not going to work in future software release.
Here is how I did it.
Drag and drop B.bundle from Project B → Products → B.bundle into the Copy Bundle Resources build phase of your app in Project A (select the Create groups options when asked). This will add B.bundle at the root of your Project A outline. You can move it into the Frameworks directory near Blib.a if it you prefer.
Select B.bundle and check its Location in the Identity and Type right panel (Utilities area). By default, Xcode chooses Relative to Project. This is wrong, select Relative to Build Products instead.
The path to B.bundle will now look something like ../../../../../../../../Projects/MyApp/B.bundle. This is not what you want, but you can easily fix it. Open ProjectA.xcodeproj/project.pbxproj in a text editor, search for this path and delete everything in it except for B.bundle. Your project.pbxproj should look like this:
explicitFileType = wrapper.cfbundle; name = B.bundle; path = "B.bundle"; sourceTree = BUILT_PRODUCTS_DIR; };
Save your project.pbxproj file. Xcode will automatically reload your project and your app should build just fine.
After searching for a long time and failing many times, I found this resource that has been an absolutely great tutorial to create Static Libraries and include bundles in your main project or even for distribution to 3rd party developers that may consume your library.
Absolutely recommended:
https://github.com/jverkoey/iOS-Framework
In project A, is the product of project B a dependency in your scheme's Build action? I think you might have to set up this dependency (sometimes disabling the automatic dependency discovery option is best) for it to show up and be available for copying into another target. I believe this is because it doesn't really exist (like an image resource file) until it's built and Xcode needs to ensure it's built before working with it from another target.
As of Xcode 5.1.1 I was able to drag and drop B.bundle from the Project Navigator to the Copy Bundle Resources list of project A Build Phases. I assume creating B.bundle target is not an issue.
Switch build to Generic iOS Device. This step is needed to create a non-simulator reference.
Drag the .bundle to the other project's Copy Bundle Resources.
Select the .bundle in the Project navigator of the other project, and change its Location to Relative to Build Products
Make sure your .bundle in added to Target Dependencies of your static library
Related
Like many people, I would love to have Xcode use a folder structure that mirrors the folder-structure on disk. However, I cannot get the code in "folder references" (the cyan folders) to show up in my project targets under "Compile Sources." Is there any way to do this?
I have managed to even add a cyan folder to the "Compile Sources" build phase, but that does not result in the contents of that folder being added.
How can I use folder references for code?
The simple (and very unfortunate) answer is that Folder References under Xcode remain broken and buggy, they don't work. Tested 04-Mar-2017 in Xcode 8.2.1
Below is an example exploration so you do not have to waste your time replicating the Xcode failure.
(incidentally buggy Xcode crashed twice while I was producing this example)
Per the question, the overall desire is to use a folder reference in Xcode so Xcode picks up all the files in the folder and includes them in the project, and by proxy will update automatically based upon any Finder or Xcode changes of the folder. In this way 50 projects all leveraging the same set of common source code files do not have to be individually updated when those folders get changed. Below explores how this is broken in Xcode (tested in 8.2.1)
The example: ViewController.m includes NSError+Core.h so we want everything from the folder "NSError+Core" to be added to the project.
NSError+Core.h is in this centrally located development folder
Drag the source folder from the Finder into the Project under the "Support" group (nothing up my sleeves, simple drag)
Xcode dutifully offers to add the drag to the target, note the "Create folder references" is selected, not "Create group references". Note also it is clear that Xcode is offering and is told to add this folder and files to the targets.
Although everything looks like it should work, the compiler does not pick up the header file and a recompile yields the same results... can't find header. Ditching the DerivedData does not help either.
So doing a double check, we check the "Compile Sources" under the project and sure enough, the source file is not there either. Remember, Xcode 'added' it to the target...
So what if we drag it from the folder into the "Support" group...
It offers to add them to the project again?! Note that the settings are identical to the first time they were drug in by virtue of the parent folder drag instead of files...
And now the source file shows up in the "Compile Sources" list. Note the bizarre double listing of the files in the project.
(Xcode crashed shortly after snapping this screen shot)
And of course the compiler can now find the header file and the error clears on the import as it should have the first time we drug it in...
Did it just need a little help to "find" the file? If so, the "Create folder references" does exactly what?
So we try and tidy up and drag the files back from the parent "Supporting Files" group to their rightful folder. Without any confirmation, indication, notification, the files just vanish from the group and nothing happens in the NSError+Core folder.
Oh by the way, it really did delete them from the project too... The Compile Sources no longer has the NSError+Core.m reference.
SO to sum up, "Folder references" as implemented thus far do not seem to have any useful purpose... It would appear to be a 6+ year old dunsel on the USS Xcode.
Kevin - linked source folders, folder references, etc, are super useful for when you have a common code base shared across different IDEs, like I do for my games that I compile on Windows, Mac, iOS, Android, Linux, etc. I have 3 different IDEs all building the same shared codebase, so it's very helpful when one automatically picks up on a new file and adds it right into the project after I merely run svn update, and I svn commit from one IDE (say XCode) and my Eclipse in Windows project picks up the change. I have a different project for each because each IDE likes the project files in a certain configuration so it's easier for me to have multiple SVN directories (base-project, project-ios, project-android) that all share code in base-project than to have one mega project directory with the different IDE bits unhappily all shoved into subdirectories (which is what I tried the first time around).
Furthermore - it used to work fine in XCode 3. They seemed to not like that useful of a feature so it is no longer working in XCode 4 as I've just found out.
I just tried doing this to share code across multiple Xcode projects, and our team came to the conclusion that it's better to create an Xcode project that contains all of your shared classes, compiles them into a static/dynamic library, and then add that as a subproject to those that need the shared code. Then you can set up target dependencies and link your shared library. This will get you the "automatic updating" every time you add a new class to the shared library project.
This approach also works well with submodules or even cocoapods/carthage.
You can't. Why are you even trying? A folder reference's job is to embody a folder, without having entries for all the individual files in the folder. It's primary use is for copying an entire folder of resources verbatim into a project. If you want to compile the sources though, then those sources must be referenced in the Compile Sources build phase of the target, which requires having individual entries for each file.
Depending on what's in the folder, it might make more sense to have a Makefile or some other external build process that builds the content in the folder into a static library. This way you can invoke that build process from a Shell Script Phase, and then just link in the resulting static library. Alternatively if you're using this folder as a way to have a shared bit of code (e.g. an svn:externals or git submodule), you could give that folder its own Xcode project and then embed that project into any of your other projects which share this folder.
Many people including me trying to make a kind of Static Library framework for iOS to archive some kind of modularity. Framework is best way to do this, but it doesn't provided by Apple, and workarounds don't work well.
https://github.com/kstenerud/iOS-Universal-Framework/tree/master/Fake%20Framework/Templates
Fake framework cannot be referenced from linking tab in Build Phases.
Real framework needs modification of system setting. And still not work smoothly on every parts.
Problem is static library need header files, and it's impossible to reference header files on project at another location on different project without some script. And script breaks IDE's file management abstraction.
How can I use static library project like a convenient module manner? (just dragging project into another project to complete embedding)
I've since updated the template to do away with the script target. It now builds the universal framework from your regular target, so you can include it in workspaces or as a project dependency.
With a real framework target, you can just add it to "Link Binary With Libraries", and it will show up fine.
With a fake framework, Xcode doesn't recognize the target type, so you need to add the link command manually. For example, assuming your framework is called Foo:
Expand the "Products" group of your framework project, then drag "Foo.framework" into the "Link Binary With Libraries" build phase of your app target.
In your app target, edit "Other Linker Flags" in the build settings and add: "-framework Foo"
Framework template link for anyone not sure what we're talking about: https://github.com/kstenerud/iOS-Universal-Framework
Solution.
Goto Project or Target's Build Settings.
Find Public Headers Folder Path. (definition name = PUBLIC_HEADERS_FOLDER_PATH)
Set it as YourLibrary.framework/Headers. I have used ${PRODUCT_NAME}.framework/Headers for automatic syncing with project name.
Goto Build Phases and find Copy Headers step.
Move all required headers to Public pane.
Now all header files will be formed like Framework and copied with product binary. IDE will copy all of them as a unit into some temporary folder like app's build folder. So referencing app project can use the headers automatically.
This is a trick. The created directory structure is not real framework. Because it doesn't contain any binary. However we don't need real framework to archive just this functionality. IDE works with frameworks without any binary. And I don't want to hack IDE without documentation about internal structure.
This works well, however you'll experience some problem when you Archive. This happens because Xcode4 behaves specially when Archiving. Here's workaround.
For each embedded library project, SKIP_INSTALL = YES in target build settings.
For final product project, FRAMEWORK_SEARCH_PATHS = "${OBJROOT}/UninstalledProducts". Take care about this setting should be set only for Release build mode.
Now it'll be archived well.
At the case of cross platform library, there can be many projects for many platforms. But sometime Xcode will show some product as red color even it compiled successfully.
This is a bug of Xcode. IDE display depends SDKROOT of Project build setting. So if you set the SDKROOT differently on Target, it won't work. You can check the the product will become black color after changing the SDKROOT of the Project build setting. See this Open Radar entry for details.
http://openradar.appspot.com/9636211
If you wish to fix this bug, please report this to Apple's Radar. Duplicated bugs will make attention of Apple. Just copy & paste my report :)
I found this : http://db-in.com/blog/2011/05/creating-universal-framework-to-iphone-ios/
It seems to work.
I'm having a myriad of problems with Xcode 4 and nested projects that worked just well under Xcode 3.2. Here's a very basic one I cannot solve:
I'm building a cocoa framework that requires another cocoa framework for which I have the source. So I perform the usual steps:
Drag the .xcodeproj file of the required framework into my main framework project
In my main framework under TARGETS > MyFramework > Build Phases > Target Dependencies: Add the nested project's target
Make sure the header files of the nested framework are public
In Xcode Settings > Locations > Build Location I have it set to Place build products in derived data location (recommended)
Build products path of both targets are set to ${BUILT_PRODUCTS_DIR} and tell me they are at the DerivedData/Debug (or Release) location
Architecture settings for both targets are identical
Then I hit [CMD] + B to build and it tells me that it doesn't find the header files of the nested framework. When I check the settings, User Header Search Paths contain the path to DerivedData/Debug, and inside there is the nested framework target with the header files in Versions/A/Headers.
I'm sitting here, anybody an idea what I'm doing wrong?
The issue goes away when building for Debug when I change the User header search paths to ${BUILT_PRODUCTS_DIR}/MyFramework.framework/Headers. However this doesn't work when building for Distribution as the frameworks then use their Release settings, which ends up in a different subdirectory...
My temporary solution is to also define a Distribution configuration for the nested projects. This way the headers are found and the linker can link successfully.
Here's my synthesized knowledge so far:
Forget the whole public header thing with Xcode, it's a PITA and doesn't work correctly when archiving your app. Instead, have all static library header files on the project level and tell your app where to find it.
Ease your pain by making sure all targets have the same name for the build configuration (i.e. add an "AdHoc" and "Deployment" configuration to the static libraries).
In build settings, point the Header Search Paths (if you use #include <file.h>) or User Header Search Paths (if you use #include "file.h") to the directory of the static library project. If the static library project is inside your app directory, use this:
"$(PROJECT_DIR)" (recursive enabled)
If you have a directory which contains a) the static library project and b) your app, then this should work:
"$(PROJECT_DIR)/.." (recursive enabled)
If the submodule contains compiled libraries, set your Library Search Paths to:
"$(TARGET_BUILD_DIR)"
Make sure all the static library projects that you use have Skip Install set to YES.
Again, no public header files (Build Phases » Copy Headers) in any of the static libraries, otherwise Xcode will not be able to archive an app.
Make sure to tell Xcode when to build the static libraries, as shown in this Tech Doc from Apple.
Old Answer:
I still haven't found a real solution to this problem with static libraries. What works for me is:
Create an "AdHoc" Configuration for the static library
Add $(BUILT_PRODUCTS_DIR) to User Header Search paths for the application (with recursive checked) -> this is used when running the app
In the Xcode menu, select Product > Build For > Build For Archiving
This works, the app finds the header files and builds itself, it ends up in DerivedData//Build/Products/AdHoc-iphoneos/ as an App bundle. Following these simple instructions (dead link) from TestFlightApp.com I can pack this App into an IPA and send it around. Simply selecting to Archive the app from Xcode does again not find the headers, even if they truly are in the AdHoc-iphoneos build directory.
(As of Xcode 5.1)
When the subproject is built by XCode, the subproject header files are copied into the build directory. When archiving, it seems that this copy destination directory is not added to the header/include search path. You'll want to go to your Build Settings and add
$(BUILD_ROOT)/../IntermediateBuildFilesPath/UninstalledProducts/include
to the "Header Search Paths" for the scheme that you use for archiving.
If you're not sure which scheme is used for archiving, go to Product -> Scheme -> Edit Schemes and look for Archive in the left column.
Make sure your third party framework is added as «group» to your main project, so you can see it in your project's hierarchy...
I had the same problem here and I could solve the problem by setting "Build Location" to Place build products in locations specified by targets"
I had this problem: I could build both Debug and App Store configurations, but not Ad Hoc. Building Ad Hoc gave me errors because it couldn't find .h files needed by nested projects.
Turned out I had an expired provisioning lingering in my Release configuration. I updated that provisioning link and now I can both build Ad Hoc and use the Archive feature to package it.
Took me hours to figure it out! My mind just didn't jump from missing .h files to provisioning errors just by itself. =) There might have been an error or warning complaining about the missing provisioning, but if so it was well buried among the hundreds of .h related errors.
I was having the same issue with a Configuration named "Ad Hoc" (as per TestFlight recommendation at http://help.testflightapp.com/customer/portal/articles/402782-how-to-create-an-ipa-xcode-4) and the main project could not find some of the headers from the nested projects. I renamed the project to "AdHoc" (no spaces) and the problem went away; seems like spaces can mess up header search paths in some cases, although I haven't figured out the specifics of when that might happen and why.
I was having this issue with a nested project that built a static library. I found this doc on apples site that completely saved my life.
http://developer.apple.com/library/ios/#DOCUMENTATION/Xcode/Conceptual/ios_development_workflow/AA-Developing_a_Static_Library_and_Incorporating_It_in_Your_Application/archiving_an_application_that_uses_a_static_library.html
I'm so glad I didn't have to muck around with the derived data paths.
For me, this happened after a GIT merge, which created many conflicts, one of them related to the project file. After the merge, I'm sure the structure of the project file changed.
What I ended up doing was going into the project "Build Settings", then looking for "Always Search User Paths" and turning it to Yes.
I guess the merge turned this boolean to No, therefore the project wasn't looking in the right places for the header files.
With the revamp of XCode I am having a lot of trouble working out how to add make one xcodeproj dependent on another. It was hard enough to work out before but now I am just stuck.
If I drag lib.xcodeproj into app.xcodeproj it just shows up as an item in the project tree and I can't expand it or see build products for linking.
Can someone give me the correct sequence for adding lib.xcodeproj as a dependency to app.xcodeproj (ie it will build if necessary and link to app)
Ahhh just worked out that the reason the lib project was being added as a useless non-expanding item was because I had the lib project open in another window. XCode gave me no indication that this was what the problem was, so I was lucky to stumble across it.
Once I had closed the other window I was able to add the lib project and it showed up correctly as an expandable subtree, as well as now being visible for selection in the app target dependencies.
The Xcode docs don't seem to be available online just now, so you'll have to search the documentation that came with Xcode for the following references. However, you'll find the information you're looking for under the following headings in Xcode Project Management Guide:
Managing Targets (Adding a Target Dependency)
Referencing Other Projects
check out BuildKit project https://github.com/davidmorford/BuildKit .
It damatically reduce project dependency management effort.
Dont forget to add the path to Classes of the lib project to tell your project where to find Header find
Go to build settings, find "Header Search Path", enter full path to the Classes folder
I'm an experienced VS.NET user and trying to get up and running on Xcode 3.1.1.
Here's what I'm trying to accomplish:
I'd like a static library ("Lib") to have its own xcodeproj file. I'd an executable application ("App") that makes use of Lib to reference Lib's xcodeproj file so that changes to Lib cause App to relink. Ideally, I'd like to be able to edit Lib's source files inside App's Xcode workspace so I don't have to task around all the time to make changes.
I figured out from the online help that I can simply drag the static lib xcodeproj in to my app's project and it gets the reference. I see that once my static lib xcodeproj is in my app's project, I can simply drag it to the App's target and it understands that App depends on Lib. This seems like the right path, but things aren't quite working the way I'd like yet.
Here are my questions:
It seems that simply having App depend on Lib doesn't cause App to link with Lib. It seems that I have to explicitly drag libLib.a from the Lib folder into App's "Link Binary With Libraries" build stage. In VS.NET, simply specifying the project as a solution dependency adds it to the link line. I just want to make sure I'm not missing anything.
When I have App open in Xcode and I drag Lib.xcodeproj into it, I don't get any of Lib's source files there. I only get libLib.a under the "Lib.xcodeproj" folder. In VS.NET, I can edit Lib's source files right there and rebuild it, etc... but with this approach in Xcode, changes to Lib.cpp don't cause Lib to rebuild when I rebuild App. Ideally, I'd get all of Lib's source files and targets to show up when I drag Lib.xcodeproj into App. Is there any way of doing this?
Thanks in advance for any responses!
You're correct that making target A depend upon target B (whether within the same project or across projects) does not cause target A to link against target B. You need to specify them distinctly; this is because they're separate concepts, and you might have dependencies between targets that you don't want to link to each other — for example, a command-line tool that gets built by target C and is used as part of the build process for target A.
Also, you're correct that referencing project B from within project A will not let you see project B's source code in project A's window. That's because Xcode does not have the same "workspace" model that Visual Studio and Eclipse do; you above alluded to the existence of "a workspace containing project A" but Xcode doesn't really have any such thing, just a window representing project A.
Open the App project. Right-click on the App target and choose "Get Info." Then go to the "General Tab" and find "Direct Dependencies." Click the ( + ) (plus sign) button to add a direct dependency. The Lib.xcodeproj should appear among a list of possibilities for you. Choose the Lib target from that list.
That should accomplish that the Lib project must build (or rebuild) when you build the App target.
(Editing my own post now. I realize I said nothing about point number 2 in the question. I am actually still thinking about number 2. I am not sure if that is possible or not.)
I'm also novice to Xcode 3.1, just played with mentioned by you issues and found that there is no problem regarding to your second question. Whatever application you use to edit the dependence library source code, your main project will rebuild the dependence target. I checked it by:
edited the source file, of the library your app depend on, by notepad application.
Selected dependence library project reference, mouse right-click, and select 'Open With Finder', then selected wanted source file and edited it.
Everything working well.
I am also a fairly new user of Xcode. Most of what I know I learned from an Xcode book by James Bucanek (ISBN 047175479x). It is an older book that was written for/with Xcode 2.2, but I find that pretty much all of it still applies for me today, and I currently use Xcode 3.1
You can probably find a cheap used copy if you are interested.