Static libraries in Xcode 4

2020-02-02 04:01发布

问题:

(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?

回答1:

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.



回答2:

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.



回答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.



回答4:

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



回答5:

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.



回答6:

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.