Xcode Static libraries building in wrong folder - xcode

I've setup cocoapods for my project and I've been doing development for quite some time without any issues. Recently I added a new Configuration for it called "Beta", duplicating the "Release" configuration. At the same time, I added a Scheme that would build targets using this configuration.
This new scheme would build everything without issues, but linking would fail with the (quite known it seems) message:
ld: library not found for -lPods
I know that issues that makes this error message come up have been discussed widely around the web, with different causes and conditions:
library not found for -lPods
https://github.com/CocoaPods/CocoaPods/issues/155
None of these fixes seem to apply here. What I can see by looking into the workspace folder, is that Cocoapods build products are put in Build/Products/Release-iphonesimulator instead of in Build/Products/Beta-iphonesimulator, even though the app itself is built rightly so into the latter. Moving all the *.a files into Build/Products/Beta-iphonesimulator makes running in the simulator work properly, but the next build is still put in the wrong location.
Edit
After some further investigations, the environment variable $BUILT_PRODUCTS_DIR is set correctly in the build phase for the app itself, but not when building cocoapods products.
What causes this and how can I fix this?
Ruled out issues
pod install has been run, multiple times
I'm working in the workspace, not in the project
The cocoapods configuration file in the new configuration is properly set
Build locations in the preferences seem fine

For the record, the issue has been solved. So, as I said, I use cocoapods, but my current setup is that a single podfile, and workspace is used for 3 projects that share some common libraries. As explained in this issue, cocoapods will only consider one project out of all those that are specified in the podfile, and it turns the one project (out of three) that it was using, didn't have the beta configuration, so it didn't feel the need to prepare for it. So when it was time to build the project with the beta configuration, cocoapods would be built for the release configuration, and put in some folder specific to release, so the beta project wouldn't be able to find it.
Fixing was a matter of creating the beta configuration for all projects present in the workspace, forcing cocoapods to prepare accordingly. Then, Xcode would be able to wire up everything appropriately.

Related

Flutter version information not used by Xcode

In my iOS project, I have the following settings in the Runner -> General tab, under the Identity section:
Version: $(FLUTTER_BUILD_NAME)
Build: $(FLUTTER_BUILD_NUMBER)
which is the same as when creating a brand new Flutter project. However, when I was going to create an Archive for releasing my app, Xcode complained that those fields were missing or incorrect (I don't remember the exact error message).
The only way I could build the release app was to change them to hardcoded strings - i.e. 1.0.0 and 1 respectively. What could be causing this issue? It would be a nuisance to have to remember to update those for every release, and I shouldn't have to, right?
If you created this project with an older Flutter version
several files created in the ios/ and android/ sub-directories might be outdated.
Newer Flutter versions might generate these files a bit differently and projects created with older Flutter versions might cause issues.
Ways to fix
Delete the ios/ and android/ directories and run flutter create . to re-generate these directories.
HINT
Custom changes will be lost and need to be re-applied. This is easiest if the project is committed to a version control system like Git.

Checked Out New Project in XCode 6.1 but XCTest and other libraries are missing

Today I checked out a new copy of stable project from gitHub to my home computer using Xcode 6.1. After doing so, I see that many of the frameworks and libraries, including XCTest, are missing (shown in red). I have added Framework and Header Search Paths, but they are still not found.
To make things stranger, I can build the project to a simulator or device, but when I try to run an individual test, I get clang or missing file error for the libraries/frameworks shown in red.
As it turns out, the reason for my errors was that I had not run "Build for Testing" before trying to run the individual Unit Tests. As such, the proper library dependencies had not been generated.

Integrating Cocoapods with large existing Xcode Workspace

I have recently been working with Cocoapods on my own projects, and would like to incorporate a couple of pods into a project at work. The problem is that our code consists of close to 20 projects stored inside a large workspace, sorted into folders. The structure of the projects is
Workspace
Apps (Folder)
Project 1
Project 2
etc...
Modules
More Projects
etc
Base Components
Even More Projects
etc
I am unsure how to write a podfile that would link a pod (RETableView in this case) against an app without disturbing the existing structure of the workspace? Is this even possible? If it isn't possible to incorporate cocoapods without changing the existing workspace, is it possible to set up cocoapods to compile pods as standalone libraries that I could incorporate into our project?
With CocoaPods 1.x you can use :integrate_targets => false in your Podfile like this:
install! :integrate_targets => false
You can find the documentation for this here
Previously (for older CocoaPods versions):
After creating your Podfile use pod install --no-integrate documented here. This will create the Pods project that you can then include in your workspace. Please make sure everything in your project is checked into your version control system first just in case anything goes wrong.

Jenkins + Cmake + JIRA = CI of multiple interdependent projects?

We have a number of small projects within our system running on Linux (Slackware 7-11, slowly migrating to RHEL 6.0). Around 50-100 applications and 15-20 libraries. Almost all our applications use one or more of our libraries. Our source tree looks something like this:
/app1
/app2
/app3
/include
/foo/app4
/foo/app5
/foo/app6
/foo/lib1
/foo/lib2
/lib/lib3
/lib/lib4
/lib/include
Now, I've done some work creating some CMakeLists.txt files and built most of the libs and some of the apps. I'm fairly comfortable with using cmake to build. I did this with v2.6, and I recently (an hour ago) upgraded to 2.8. Each of the above projects have their own CMakeLists.txt file specific to the project to do building and installation (no packaging, yet).
I have a requirement to make use of and enforce continuous integration. I've installed and played around with Jenkins, and from what I've seen I'm very impressed. I'm also evaluating JIRA to do our issue tracking.
Just to get things up and going, I've done a cmake install on all the libs, so the apps can find them in the filesystem. Headers are installed to /usr/local/include and libs to /usr/local/lib. Is this a bad thing to do? Would it be better to tell cmake to look for the lib's source directory, use the export interface or the recently introduced ExternalProject_Add?
Because I'm going to be using Jenkins, I cannot be guaranteed that cmake can find the source or build directory. Of course, I can tell Jenkins to build the projects in order (or at least, build the dependencies first). If an update to a library breaks the building of another project, then I guess it'll be up to someone with 3/4 of a wit to determine this.
Thank you in advance
Just to get things up and going, I've done a cmake install on all the libs, so the apps can find them in the filesystem. Headers are installed to /usr/local/include and libs to /usr/local/lib. Is this a bad thing to do?
No it is not a bad thing to do, but your build should reproduce resources from scratch. Things like portability and fixing build bugs will become an issue if things need to be pre-installed in the system outside of the build process. If you are able to do it other ways as you mentioned I would suggest that way, but if its going to make your build that much longer, its something you need to feel out. My ideology is everything should be movable to a new Jenkins machine with a fresh install at the drop of a hat, again this always isn't achievable, but something to strive for.
Because I'm going to be using Jenkins, I cannot be guaranteed that
cmake can find the source or build directory. Of course, I can tell
Jenkins to build the projects in order (or at least, build the
dependencies first). If an update to a library breaks the building of
another project, then I guess it'll be up to someone with 3/4 of a wit
to determine this.
Well one of the things I do in interdependent jobs is that on the successful building of one jobs triggers the job that depends on it. So for example if A depends on B, and A fail, B will never be run and whoever created the issue in build A is responsible for it and so on. This prevents a cascading affect of broken build that all were caused by a broken dependency. I would suggest that you keep files in a particular build in its job folder and specify to the dependency the location of the required files. Again keep your builds separate and clean.
I'm also evaluating JIRA to do our issue tracking.
I highly recommend JIRA as an issue tracking system for company; You might want to look at this Jenkins plugin for integration. If your using git, and you dont mind hosting your code off site, I would GitHub issues a shot as well.
Goodluck you seem to be on the right track.

How should I manage dependencies across projects in an Xcode workspace?

I'm working on an iOS app project, and add the json-framework project to the workspace. The project navigator on the left shows both projects, and the build scheme selector shows the schemes from both projects too. Now I want to add the libjson.a target from the json-framework project as a dependency on the iOS app target in the other project. The expected result is that whenever the app target is built, it builds (if necessary) the library target and links the app target against it. Here are the ways I've tried to do this:
Build both as part of the same scheme. The way I try this is to edit the scheme for my app, adding 'libjson.a' to the 'Build' portion of the scheme, and by the way "Find Implicit Dependencies" is checked. Then I go to the target editor for my app target, and in "Build Phases"->"Link Binary With Libraries", I choose 'libjson.a' from the list of workspace libraries.
When I subsequently try to build the scheme, I see it build the library target, but building the app target fails with linker error "Library not found for -ljson" - suggesting that it hasn't actually discovered that the library has been built. Indeed in the project navigator, the entry under the app project for the library is still red indicating that the file doesn't exist.
Add the json target as an explicit dependency. To try this, I don't modify the build scheme, but go to the target editor for my app target and click the add button under 'Target Dependencies'. No targets from other projects in the workspace show up, so this is a non-starter.
Drag the JSON project into the other project, then add the target as a dependency. This is what I would have done in Xcode 3. In the project navigator, I grab the library project and drag it over the app project. This brings up the usual 'add files' pane, which I just dismiss by clicking 'Finish'.
There are now two entries for the library project in the project navigator: one at the top level, and one under the app project. I can now add the library target as a dependency of the app target using the target editor, and can link against it without error in the link libraries phase. But it looks broken: there are multiple entries for the same project in the navigator. Is there a different way to do this?
What should be considered the "Xcode 4-ish" way of connecting these targets in different projects in the same workspace? It would seem lacking if multiple projects in the same workspace can't actually interact with each other.
Thanks,
Graham.
I’ve just set a test project up, pretty much as you describe in version 3, by creating a new workspace and dragging the two Xcode project into it, nested as shown.
You can delete the sibling project if you have it already.
Hitting build on this and it just works, as far as I can see.
I imagine there is internal path-confusion if you have two projects, and I’d be inclined to fiddle with location settings in "View"->"Utilities"->"File Inspector" and see what effect that has.
Another thing to try is to set your paths up in Xcode "Preferences…"->"Source Trees" and refer to them that way, as described here: Easy, Modular Code Sharing Across iPhone Apps: Static Libraries and Cross-Project References
HTH. Andy W.
I managed to get dependencies between projects in a workspace to work as I described here: http://blog.carbonfive.com/2011/04/04/using-open-source-static-libraries-in-xcode-4/.
Unfortunately I can't find a way to get Xcode to discover implicit dependencies or index everything in the build as advertised. I found workaround to both but I'm hoping that less manual configuration will be needed as Xcode 4 matures.
I was going to ask the same question, thinking that my own solution couldn't be right. But I don't see it mentioned here, and it does seem to work. Clearly XCode 4 is a work in progress. :)
I have a workspace with two projects: a static library and an app which uses the library. The projects are siblings. Each project has its own scheme, and each scheme is set to only build one target. In other words, I added two projects to the workspace and that's it.
To add the static library as a dependency of the app, I just drag the libsomething.a product from the library project (Project Navigator) into the "Link Binary with Libraries" list for the app target. That's it. Now when I build the app the library project is built first and then linked. Interestingly, when I modify the app's scheme to use a different configuration (eg, Release instead of Debug), the library is built using the same configuration.
So it works, and there is clearly some automatic dependency checking going on here. But it feels wrong. Then again, so does the modal scheme editor/manager and lack of a workspace object in the project navigator... I never thought I'd say it, but the Visual Studio UI (bleh) is a lot clearer.
My bullet-proof solution to do this :
Create "Per Debug-Release / Per Architecture" settings in Build Settings in the Main project (not the lib), to include either
../MyLibProject/build/Debug-iphoneos
or
../MyLibProject/build/Release-iphonesimulator
or
etc..
depending on the configuration (you can create those kind of configuration by clicking on the + next to Debug or Release and choose either "Any iOS Simulator SDK" or "any iOS SDK".
You need to do that for both "Header Search Path" (in case your library copy some headers files, which is more than likely) AND for "Library Search Paths". Which means that for each setting, you'll probably end-up with 4 different paths (debug sim , debug ios, release sim, release ios).
That would make sure the configuration of both projects match.
Now, to auto-compile the lib, that is to create the dependency, you can use the "Build Phase -> Link to Binary With Libraries -> + -> select the .a file" advice given above.
That's the only way I managed to have something that builds and link correctly for every environment on xcode 4.5
Note : I even added the -lmyLib flag in "other linker flags", but i'm not sure that's really necessary
I've had some success with creating framework-like static libraries, though it's not a perfect solution.
I see the next variants:
Explicit dependency in a project[About]
Implicit dependency in a workspace[About]
See the Xcode user guide: Xcode Concepts -> Xcode workspace under 'Projects in a Workspace Share a Build Directory'.
All projects in a single workspace share a build directory. Dependencies are discovered automatically and build if needed:
"Xcode examines the files in the build directory to discover implicit dependencies. For example, if one project included in a workspace builds a library that is linked against by another project in the same workspace, Xcode automatically builds the library before building the other project, even if the build configuration does not make this dependency explicit. You can override such implicit dependencies with explicit build settings if necessary. For explicit dependencies, you must create project references."

Resources