iPhone xcode search path for device vs simulator? - iphone

I am confused at this setting (Project -> Edit Active Target).
The Search Paths can differ based on the SDK setting (simulator vs device).
But if I provide both simulator and device paths, for lets say the Frameworks path, then i get linker errors. But it seems if I only provide the proper path for whichever SDK i have selected, then it builds fine!
How can I keep both path settings? Currently Im having to cut and paste the appropriate path based on the SDK i have selected to build.
Thanks!

Which kind of search path are you talking about? The system search paths are automatically handled for you, so I assume that your problem is some custom library.
There are two solutions. You can use conditional settings, or you can use universal libraries. I've grown to love universal libraries, but haven't had time to write up full instructions yet. The way they work is to build a static library for the simulator and for the device, and then use lipo to glue them together. You can then use the same library for both platforms. I really need to write up full instructions for this because it's very useful.
There are two more approaches. First you can use conditional settings. In xcconfig files (see my talk on why to use xcconfig files), you put something like this:
LD_FLAGS[sdk=iphonesimulator*] = -lsasl2
That links sasl2 just for the simulator. Set whatever you flag you need. Another solution is variable substitution:
HEADER_SEARCH_PATHS = "$(SRCROOT)/MyPackage/build/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/include"
This assumes that MyPackage is in a subdirectory of your project and it was built into the build directory. It'll look in, for example, Debug-iphoneos for its variables.
You can also do both of the above in the build pane, but I really recommend folks get away from the build pane for any serious project. Variable substitution works identically in the build pane, and conditional settings are accessible from right-clicking on a setting.

You should have two separate build target profiles set up, one for sim and one for device, rather than constantly editing the same one. That's kind of the point of targets.

If you're only using
project headers
SDK framework headers
sqlite3 headers
then your Header Search Paths should be empty. Xcode provides search paths for your project headers, SDK frameworks, and /usr/include/*.h automatically, and adjusts those for the framework in use.
The only reasons to have custom Header Search Paths is when you have references to headers that are not in the SDK, are in "deep" locations in the SDK (such as in subdirectories of /usr/include or in buried frameworks), or are in other targets or projects your project cross-references.

Rob already hinted at this, but to clarify, here's how you'd set it using the build window.
In the build settings window, select the setting you want to modify (like "Framework search paths"). Then click the gear in the lower left, and select "Add Build Setting Condition." Then you can add a value that applies only to iOS Simulator builds, and a second build setting condition to apply only to device builds.

Related

Why are there Code Signing Build settings for the project and the target and which takes preference?

Why are there Code Signing Build settings for the project and the target and which takes preference?
I have 2 targets - one for Lite and one for Premium version. When creating ad hoc builds I am confused as to why one can edit code signing build setting in 2 places and which takes preference?
Target build settings, if defined, always override Project settings. You can tell if these are defined because they are bold.
Depending on the purpose of your different Targets, they may need a few different settings, or many. To create an extreme example, imagine you have Mac OS-based editor for your iOS game in the same Project. The two Targets would have different architectures, SDKs, search paths, memory management, etc.
Or, if your Targets are Lite and Premium versions of the same app, almost nothing should change between them.
If you find yourself changing a setting in all your Targets, you should change that setting in the Project instead. You can cancel an override in the Target by selecting one of those bold Build Settings and pressing the delete key. This can't be undone, so make sure you know what the setting was if you need to delete it.
In the case of code signing, have the code signing in the Project alone.
If you ended up licensing a custom version of your app to a different company, you would need to have a new Target with different code signing, so it's nice that XCode can do this if you need it.
The target takes preference i believe. If you change from Combined view to Levels view in build settings it highlights which one is being used which helps a lot.

how do I reference a separate project in xcode 4?

How do I reference another project which has code I wish to leverage in XCode 4. In particular I'm trying to make use of the NSDate extensions from here.
Some notes:
I was assuming I should probably reference rather than trying build a framework
I tried copying the existing "Hello World" xcode project file across into my project, however this didn't seem to work
Do I need to create a new "Target" based on "coco touch static library" option?
Then would I need to Edit the current Product Scheme so that when I build the new target would build
What do I need to do on my project side exactly - should going Add Files, and choosing the extensions Xcode Project File be enough?
thanks
I was assuming I should probably reference rather than trying build a framework
yes, reference and link with it, unless you need only a bit of it. at this stage, separating the bits you want may be an advanced topic (depends on the lib's layout/depends as well). you should prefer to reference and link because it will normally minimize your maintenance time, especially if you use it in multiple projects.
I tried copying the existing "Hello World" xcode project file across into my project, however this didn't seem to work
you don't create a project, you add the library's xcode project to your app or library, set the lib as a dependency, add the library to your search paths if needed, then link with the library.
Do I need to create a new "Target" based on "coco touch static library" option?
no
Then would I need to Edit the current Product Scheme so that when I build the new target would build
no. you configure it as a dependency. you may need to alter the lib's build settings if there is a major conflict, which the linker or compiler would point out.
What do I need to do on my project side exactly - should going Add Files, and choosing the extensions Xcode Project File be enough?
start with the process outlined above.
There is no reason to bring in an actually project. Either you can bring in the source files themselves and you could even use the same exact files instead of copying them if you want. However, if you have more than just a few files, and you don't think you will be changing the code much, then creating a static library would probably be the best option.

two projects in xcode4 workspaces (#import failure)

I'm really struggling to get this to work in xcode 4.
I have one project that I will reuse in many applications (networking) so I create a workspace and add my two projects. So far so good....
This is where it fails..
#import "JSONRequest.h"
For no apparent reason. It auto completes the file name of the header file. I thought this had something to do with the "scheme" (also new in xcode 4) so I've tried to add my networking target in the build phase. Changing order of them... set "Shared" under Manage schemes.. I've tried so many different combinations of the settings without any success.. And the error message is get is:
JSONRequest.h: No such file or directory
If you have a clue, please let me know.
You can add the header or source folder of your project you're referencing to your Header Search Paths.
Click on the target that's importing JSONRequest.h.
Click on Build Settings.
Enter "Header Search Paths" into the search box.
Double click on the value cell.
Click the + sign.
Set the path to the project you're referring. Let's say it's called JSONlib. The path is relative to the root of the referring project (the project that's using JSONlib). For example: ../JSONlib/src/headers/ or wherever it is that the .h file lives.
Click done.
Clean and then build.
You'll find more info about this problem in the apple developer forums. Best of luck.
What are you really trying to do?
If you have an entire Xcode project you intend to share between different products that usually suggests your project builds one or more targets (such as a framework, etc.). Therefore, your "shared" project should be able to build the framework on its own, irrespective of the workspace it's contained in, right?
Let's assume it's a framework. In most cases, Xcode can figure out the dependency by simply adding the framework product to the Link build phase of the (assumed) app using the framework. Done. Xcode should know to build the framework project's target first, since it's linked against when building the app project's target.
So your problem is likely just a matter of knowing where Xcode is looking to find files. Since projects within workspaces share that workspace's build folder, they can all "see" each other. But in the case of a framework, A simple import by file name won't cut it. You'd need:
#import <MyNetworkingFramework/MyNetworkingFramework.h>
Since you're including a specific header (JSONRequest.h) (which must be one of the public headers in the framework target's copy headers build phase), you'd need:
#import <MyNetworkingFramework/JSONRequest.h>
If your "shared" project is not a framework, you'll need to amend your question to include a more thorough description of your two projects and their targets.
This worked for me,
In build settings --> Header Search Path --> Add below entry
$(SRCROOT) and mark it as recursive. If above not worked you can also try following way, <path-of-other-project> and mark it as recursive. Hope this helps to you ! (You may require to clean or restart the workspace)

What exactly is an Target in Xcode?

I was always wondering what's up with those Targets? What is it all about? What's the point of that? I never had to fiddle around with them, but obviously I can. Why should I want that, and what can I do with them? What's their purpose?
Each project can build multiple executables or libraries or call out to a makefile or shell script to build "stuff". Each one of these is a Target.
One iPhone project I have includes a separate target for each static library in my home grown SDK and a shell script target to build the Doxygen docs. Another project includes two targets, one for the app as used by general users, one for an administration & management edition.
In the first example, I need to build each library then link all the static libraries into an SDK test application, so my SDK Test App depends on all the library targets (but not the docs, since I don't need to constantly regen them.)
In the second example, the management and the general versions of the app share a considerable amount of code and resources. When I change one, I want to change them both.
The target is something like a "blueprint". It includes rules that tell the compiler what to do, which sources should be compiled, which files should be copied into the application bundle, which libraries should be linked.
If you want to make a Free-Version of your app one way to do so is to add a new target.
Of course you could just duplicate the whole project but then you had to keep those in sync if you change some code. Using a different targets makes this a lot easier.

Automate the XCode build settings

I've developed a static library that I'd like to share between XCode projects. I did some reading to learn exactly how to include this library as a binary dependency so that it runs on both the device and the simulator and that lead to a couple of manual steps which I'd now like to automate. Overall I'd like to be able to release new versions of my library and have a simple upgrade process for any project using the older version. Currently that process consists of deleting and/or copying the new binary files over the original location, deleting copying over new header files. The initial install consists of the same two steps along with additional project/target level configuration to set conditional linker flags based on the target SDK. Is there a way this could be automated? I mean I know I could do something like write an Applescript to do the heavy lifting but how? Has anyone ever automated xcode build settings via applescript? How would I call into XCode via Applescript? Are there any other alternatives? Is there a better way to maintain binary level dependencies?
Update
I'm looking to maintain a binary level dependency where project A depends on a static library created by project B. Something similar to a framework that can be included into an XCode iPhone project easily. After building "B" I want something that can practically be dropped into and project including A. While I am becoming aware of all the procedures around leveraging such a dependency I am looking for some solutions to soften up all of the rough edges.
Add a custom build script through Xcode:
select your target under the Targets group on the left
select Add -> New Build Phase -> New Run Script Build Phase
double click on the new Run Script item underneath your target
this allows you to write a shell script, accessing most of the Xcode environment variables related to the current build, e.g. $BUILT_PRODUCTS_DIR
if you check the "Show environment variables in build log" and view the detailed build output you can see all the variables available.
Have a Google search and you'll find lots of examples, e.g. section 20.3 here etc.
If you are using Subversion I believe you can use SVN externals to specify which particular version of your library to use.
You just have to drag & drop your library project in your project. xCode will dot the rest...
Regards,
Thierry