Static libraries in Xcode 4
Asked Answered
N

6

41

(My question has been asked here before but with no working answers that I can see. E.g. Xcode4 Workspace with Static library project & application project)

I'm trying to use a library provided by a 3rd party. They provide the XCode project which builds a libLibraryName.a file. They recommend adding the project as a subproject to my own, then adding the product libLibraryName.a file to the set of libraries described in my project settings "Link Binary with Libraries".

The library does build correctly: the .a file is generated. But the project shows a red libLibraryName.a file under the Products group. I can't get it to turn black. And the parent project says it cant find LibraryName for linking.

As a test I created a new static library project using the XCode 4 static-library template. This project exhibits the same behavior - the product never shows up 'black' even though the .a file is built. (Edit: it does turn black if you build for device, not simulator).

I know that XCode 4 places intermediate and product files in a shared location by default. I've tried this setting, and I've changed the setting to place the product files in the folders described in the build settings. Neither setting works.

Folks have also suggested building for a device rather than simulator. I've tried this to no avail.

What gives? How do I get a static library project to recognize where it built the product, and subsequently reference this product in another project?

Narva answered 20/5, 2011 at 15:59 Comment(3)
God I hate the editing feature on SO. It's great when someone who's English isn't up to par writes something nonsensical yet someone takes the time to parse it out. But then you get people who want to "improve" your question when in fact they don't. @zoul - Changing the title of my post didn't improve it since in fact my question is more generic than simply "building static library in Xcode4." If you read the question you'd see that was part of it, but the primary issue is getting XCode to FIND AND USE a library which I've already successfully built.Narva
you always have the option to roll back the changes if you feel like it. I changed the title once more, hope this version is fine with you.Afflux
@Afflux - thanks. Sorry for the vent.Narva
N
55

Lots of hoop jumping, but here are my notes now that it I got it working.

  • If you create a new stock XCode4 iOS "Cocoa Touch Static Library" project (and add some code to it) the project will build fine out of the box. But the Product file libLibraryName.a only turns black (from red, denoting the file doesn't exist) when you do a device build. A simulator build does not show that the target was built when in fact it was.

  • In the project target build-settings, the "Per-Configuration Build Products Path" defaults to $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) If you change this to something else (or if you upgraded the project from XCode3.x which used $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)$(IPHONEOS_DEPLOYMENT_TARGET) as the default, I believe), then the Product file libLibraryName.a wont ever turn black. To me this says there's a bug in XCode somewhere.

  • I can live without the Product file turning black after a build (it is a nice indicator, but hey, whatever.) But I do need my consuming project to be able to find the correct build of the library, be it for simulator or device. In an ideal world there would be a single .a file with i386/arm6/arm7 bits in it, but again, this isn't my library / library project.

  • The XCode4 Transition Guide is what showed me the light. It prescribes creating a workspace that hosts both of the projects, and they will both build into the same shared build directory. I was not using a workspace previously, so I used the File/Save As Workspace command to create the new workspace file. Then, I added the library project, taking care to ensure it was placed as a peer to my primary project and not as a child.

  • I had to make sure the workspace was configured to place build output into a common folder. In the Workspace Settings dialog, set the Build Location setting to "Place Build Products in Derived Data Location"

  • I also had to make sure to check the "shared" checkbox for each project in the Manage Schemes dialog.

  • Finally, to specify the library dependency for my main project, I simply went to the target Build Phases tab, Link Binaries with Libraries section, and clicked the '+', then selected the libLibraryName.a file from beneath the Workspace folder. Note that I'd tried this before when there was no workspace and no common build dir, and the result was that XCode couldn't find the .a file during link.

All said and done, it works like a charm. I can't help but think it should be a lot easier - as I believe it was in XCode3.

I'd be happy to read about anyone else's experience with all this, or any feedback about other (simpler?) ways to make linking static libs work well.

Narva answered 20/5, 2011 at 19:59 Comment(4)
With all of the above in place there was still nothing available to add as a target dependency. I could 'build to run' but not 'build for archive' (getting the 'library not found' error). My fairly ugly solution was to locate the offending library in the build directory and drag it into my app project (without copying). Xcode is now aware of its location and everything builds as it should. This might save someone else a bit of hair loss. Thanks for the rest of it @NarvaPym
Note: the "shared" checkbox in the Manage Schemes dialog has no bearing on correctly using a static library. The "shared" checkbox only determines if the scheme is visible to other users.Froma
This is working great for me, except that if I change anything in the library, building the project that uses it doesn't cause the library to be rebuilt. I have to manually build the library, or clean/build the project that uses it. Any tips on getting Xcode to build the library as needed?Delacourt
I was doing these steps to include "Facebook-iOS-SDK.xcodeproj" into my project, but after even adding the Header Search Path, it still says "Facebook.h": No such file or directory.. Facebook and Apple is driving me crazy!!!Disenable
P
6

Check out my answer here and see if it helps you:

Linking a static library to an iOS project in XCode 4

These are based on my instructions for my own library. I think the missing step in your original process is that you don't add the static library to your app project as a target dependency (step 3 in my instructions) at the same time that you link it in "Link Binary with Libraries". You also might need to do step #5 depending on how the headers are linked by the static library project.

When I do this process with my own apps that have cross-project references to static library projects, it actually has one step less than the equivalent process in Xcode 3.

Parette answered 25/5, 2011 at 19:42 Comment(0)
N
3

Take a look of my solution note and Open Radar entry.

The red colored product node is a bug of Xcode. You can make it work by changing SDKROOT on Project build setting. Target build settings won't work for IDE display & support.

Edit

For later reference.

Currently, my opinion is changed to the Xcode project is not completely able to deal with multiple platforms. Though it can display multiple platforms but only one platform can be chosen at one time to screen display by the SDKROOT setting. If you select iOS, it will use something like Debug-iphoneos for build product path. So all Mac OS X targets will be missing. If you choose Mac OS X, it will use something like Debug. So all iOS targets' products will be missing.

I think Xcode still have internal bug related this. It's long time to go to make Xcode to be stabilized.

Nilsanilsen answered 19/6, 2011 at 6:7 Comment(0)
G
2

I had the same issue with my team. One of the developers was suffering with this issue, however my xcode was able to compile and found the header properly. BTW: all "build Settings" were properly configured (always search user paths, user header paths, etc).

I realized that his project was in a directory with spaces in its path (../my project/blah.xcodeproj). Changing that, Xcode was able to find the headers from the static library within the same workspace.

Just be aware of directory names. My two cents

Greet answered 14/11, 2011 at 15:9 Comment(0)
L
1

One clarifying detail (after digging through build output until I started to go cross-eyed): if you are finding your library headers are being exported to Build/Products/Debug and your parent project is looking in Build/Products/Debug-iphonesimulator, your library is being built for OS X, not iOS. You can change this in the "Supported Platforms" setting in the "Architectures" section of the project settings. OS X appears to be the default setting if you create a vanilla C++ static lib project, so this situation is easy enough to encounter.

Lectureship answered 11/3, 2013 at 20:47 Comment(0)
M
-1

I was having this issue with one of my libraries. I actually have 4 other libraries I build that are included that look fine, appear black, but one that did not. My red library was solved by changing the Base SDK in the Build Settings of the library project. Since the library could build for Mac OS X and iOS it was set to the Mac OS X setting. The iOS target library still built but never turned black. Once I changed the Base SDK build setting to be latest iOS my library turned to black.

Mande answered 7/3, 2013 at 0:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.