Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2005-402
$eventId
ID of event: wwdc2005
$eventContentId
ID of session without event part: 402
$eventShortId
Shortened ID of event: wwdc05
$year
Year of session: 2005
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC05 • Session 402

Adopting Xcode

Development Tools • 1:07:26

See how Xcode can improve your development process. Learn the basics of Xcode's impressive core feature set, time-saving tips for moving your codebase into Xcode, and strategies for managing C/C++ compiler differences. Bring your laptop to this session where you'll get hands-on experience migrating a project to Xcode.

Speaker: Chris Espinosa

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Good morning and welcome. This is the Adopting Xcode: A Hands-on Tour. How many of you were here for the 9:00 session this morning, the introduction to Xcode 2.1? Same seats and everything. Good. How many of you have not used Xcode before or have only used Xcode 1.5 or earlier? Good.

You're the right audience for this. This is going to be a little adventurous. This is the first hands-on session that we've done. This is not going to be me talking slides at you. This is not even going to be a demo. This will be a follow-me session. I see a lot of PowerBooks open.

That's great. I hope you have fully charged batteries for this one. And we want you to have Xcode 2.1 installed and the appearance sample upgrade project downloaded from ADC. How many of you are in that situation? Awesome! Okay, the rest of you, if you don't, you can either watch what we're doing on the screen or watch your neighbor's screen. We're going to try to take it milestone by milestone so that you can follow us and look at what we're doing. I'm Chris Espinosa, the manager of DT Productivity.

We're going to be introducing the Xcode development environment for you who haven't used it before. It's a full function development environment that integrates project management, a code editor, a build system, and a debugger. If you've used other IDEs like Code Warrior and Visual Studio, it's like that. The good news is that whatever you have used before, Xcode probably has something that does what you want. The bad news is that whatever you've used before, Xcode probably does it a little bit different.

So we're going to be doing a lot of orienteering in this session, helping you map what you understand from your current environment to what Xcode does. You're going to learn the basics of Xcode, and we're going to be talking about how to use it in a little bit different way.

We're going to be talking about how to use it in a little bit different way. Chris Espinosa You're going to learn the basics of Xcode, and we're going to be talking about how to use it in a little bit different way. Chris Espinosa You're going to learn the basics of working with Xcode, the similarities and differences between Xcode and the other IDEs that you may be familiar with, and do this mental mapping from Code Warrior or Visual Studio, or even make file concepts to Xcode.

[Transcript missing]

Bringing your project into Xcode, if you are coming from Code Warrior, the best thing to do is make sure that you've got a great Code Warrior Tiger application before you bring it into Xcode 2.1. The more work you do in an environment you are familiar with, the easier it will be to transition to the unfamiliar environment.

Chris Espinosa The biggest failures I've seen are people who have been using Code Warrior 8.3 or something like that, have never built for Tiger, have a CFM application that isn't up on Mako, they're not using Carbon Events, and they try to import their project into Xcode. Chris Espinosa And then they have to face the entire transition all at once in an unfamiliar environment. Try not to do that.

Needless to say, Xcode is an environment for Cocoa and Carbon applications. It won't build -- if you're starting with something that has not even been carbonized, you need to start somewhere else. Make the migration to MacO. CFM is not supported on Intel. It's not supported for PPC64. MacO is the native executable format on Mac OS X, and you need to have your code building for MacO in order to use Xcode successfully. And prepare your code for GCC 4.0. GCC 4.0 is the compiler for universal binaries.

There's a session later on this week about differences in GCC 4.0. It's a lot stricter on C++ compliance than earlier versions of GCC, and there are some things you need to know about its idiosyncrasies. So a lot of your coding work is going to be in just compiler-specific changes.

So we're going to start at milestone one. If you have opened up the appearance sample updated project, loaded milestone one, loaded that .Xcode project, we're going to talk about groups and files. If you're familiar with the Code Warrior project window, then Xcode has a project window that is remarkably similar to it. It lists the files in your applications organized into groups, and you use it to navigate your project.

If you're familiar with Visual Studio, you could set up the all-in-one layout in Xcode preferences, and you see your groups in your files, and your embedded editor window. Xcode has a mode that works like that as well. So if you're familiar with these environments, you can find your way around the groups and files. And to take you through exercise one, milestone one, here's Scott Tooker.

Scott Tooker: Hi. Scott Tooker: So just to give another quick overview here, there's actually going to be -- there are going to be at least five milestones today, and we're starting out with appearance sample one. And in this one, we're going to talk about the build. I'm just going to give a quick tour. This is going to be kind of simple. If you've used Xcode 1.5 before, some of this may be review, but it's good review.

So the first thing I've done here is I've opened up appearance sample one. And so you should have on your screen -- I'm using the default layout. So if you use the default layout, this is what it's going to look like. It's going to be a little different layout, but all the pieces are still there.

So the first thing I'm going to do is just build this project. And if you've never been to Xcode before, it can be kind of daunting because it's like, well, you know, I click build, but where's the build information? So if we go ahead here, let's go ahead, and I'm just going to do a clean.

Now I can click build here, but let me bring up the build results window because this is actually going to show all the information that goes on during build. Let's make that a little bit bigger. And then go ahead and click build. So what you'll notice here is we're going through and we're going through the various steps of building. Now there's a lot of different levels of disclosure here. Right now we're just looking at the warnings that are coming through, but there's a lot more to see. For example, if you click on the check mark here, you'll actually see every step.

And you can just toggle that to either show all the steps or just, in this case, if we have any warnings. You can also say, I don't want to see any warnings, I just want to see errors. And you do that by toggling this checkbox. And then finally, we also have the actual build transcript here.

And one of the nice things about the build transcript is that it's linked with the information above. So, for example, if I look at all the steps and click on one of these, click on one of the steps, you'll notice that I automatically go in the build transcript to that part of the log. This becomes very useful when you want to see exactly how something's being done or when you want to go look for an error. Or you want to see an exact error warning and see when it happened.

So, okay, if -- also I'd like to mention at this point, I'm purposely doing this on a PowerBook G4 because it seemed that doing it on a G5 was unfair. So I'm trying to pace this so people can keep up. This is a 1 GHz G4, so hopefully I won't get too far ahead.

So anyway, we've gone here, we've built. You'll notice that it succeeded. So if you go ahead and if you close the Build Results window, where does the product end up? Well by default, Xcode puts products in a group called Products down here. You can disclose it. And we actually have what's called a product reference. This is a reference to your product.

And you can actually, in 2.1, you can go through and you can actually disclose the contents and see exactly what's in there. So for example, if I double click on this Info.plist, you can double click on it. You'll see exactly what was produced. This is really nice sometimes when you have a complex setup and you have a bunch of files you're putting in. This gives you a quick way to look through and see exactly what was put into the product that Xcode built.

So speaking of the products group, we're just going to go through a quick kind of mini tutorial on how our files and groups work. Anyone who's coming from Code Warrior, this is going to be very similar. A lot of our files and groups layout was inspired by Code Warrior.

So for example, one of the things I want to do with Appearance Sample is I'd like to clean it up. Appearance Sample is a very old project. It started out as a Code Warrior project. It's moved into Project Builder, then Xcode, Xcode 2, Xcode 2.1. And so there's a little bit of cruft. One thing that's unfortunate is they have a sources folder, and I think, well, that's where all my sources are. But not really.

You'll notice if you disclose the mega-dialog, there are sources there, and there are sources under C/Dev. So just as a quick tutorial, we're going to clean this up a little bit. So the first thing I want to do is my sources folder is just kind of a mismatch.

If you actually open it up and look, you'll see there's a mismatch of different -- mishmash of different classes. And what I'd like to do is have some directories inside of here to provide a little bit more structure. So what I'm going to do is I'm going to go ahead, and I'm going to create a new group, and you can do this by going to File, New Group.

And I'm going to call this one Dialogues. Okay, well now what I want to do is pull everything out of sources that had to do with Dialogues. Well, one of the nice things I can do here is you'll notice I've select -- if you select the sources group that we show in the detail view all the files underneath sources, and then I can use the search field, if you click in the search field and type So I'm going to go ahead and if you select all those and drag them underneath dialogs, now they're located underneath dialogs. And I can do the same thing. Go ahead now, and you can also, we also have contextual menus, so I want to add another group, so I'm just going to go to the contextual menu and say new group.

Go ahead now, and you can also, we also have contextual menus, so I want to add another group, so I'm just going to go to the contextual menu and say new group. And the same kind of thing, just drag them over underneath Windows. And you can obviously have groups and other groups. So for example, what I'm going to do is I'm going to take the MegaDialog and drag it underneath Dialog. And then finally, we obviously support multiple selection, so I'm just going to take all of these source directories and drag them underneath sources. And there they all are.

Now, if you want to rename something, for example, this external framework's in-- wow, I have to extend it all the way out to here to read it. But all that's really in here, if we open it up, is the Carbon Framework. So I want to change this name. Renaming folder references and groups is very simple. You simply just-- you can either option click, or you can just select Rename and rename. It's very similar to Code Warrior in this respect.

And then finally, we have this supporting files group. Well, it has this readme. Well, it would be great if the readme was up top so when people first opened up this project, they could see exactly where it was. So what I'm going to go ahead and do is I'm just going to ungroup this.

And you can go ahead and do this by just using the context menu and selecting ungroup. Or you can just go to the file menu. Oh, sorry, sorry. Getting ahead of myself. Currently, this is only available in the context menu. So go to the context menu and say ungroup. And then we'll just drag this up top.

So now we've just done a few simple things, and none of this has affected any of our build process. This is all just managing your files and groups. It's completely divorced from what we've actually built, what the build products are. And in fact, what I can do is I can just go ahead and click Build again. And you'll notice nothing needed to be redone because it's all the same. And with that, I'll hand it back to Chris. Great.

How many people kept up? That's awesome. That's great. If you have -- pardon? I got a crash. Great! Click "Report to Apple." If you have not kept up, or if you've just gotten up to speed with Xcode 2.0 installed, you may now move to Milestone 2. Milestone 2 is the same project, but it's in the configuration that Scott ended at. And that's true for every milestone in this session. If you can't keep up, you can just close that milestone, open up the next milestone for the next segment.

[Transcript missing]

Clicker.

Now in Code Warrior, if you're used to targets being in a target pane, we move targets out into the regular groups and files tree so you can look at targets at the same time you're looking at files, and it makes it easier to drag and drop between the two because you're dragging and dropping in the same tree.

But the organizational concept is still the same. A target is a bucket into which you pour source files that you set settings on. You choose a target you're building now. When you build that target, it comes out with the build project, build product. The concept is the same in Xcode as it is in Code Warrior. If you're coming from Visual Studio, they use slightly different terminology. What we call a target is what they call a project, and what we call a project is what they call a solution.

So think of them as just being one time zone over. Just push it over a little bit, and the terminology maps. So if you're coming from Visual Studio, when I say project, I don't mean project in your sense. I mean solution. And when I say target, I mean project. You can do that mapping. You use Windows, you're accustomed to it.

If you're coming from the make file world, well, make files are a little different in that everything is a target. It's just a smooth transition of granularity from I build one.cp file and get one.o file to I have a make file that builds this entire executable with all of my steps. And every dependency where a source creates something is called a target. We work on a much coarser granularity. A target is a set of settings and a collection of sources that build a build product that's usually something that you debug or deploy.

So targets on a granular make file level, or can be really tiny things or really big things, we're only talking about the really big things here. So now to guide you through what's in the target, how to edit targets, how to use targets, we're going to do the milestone two, targets and files hands on.

Hi. So you'll notice that I've gone ahead, I've closed-- I've opened up the second milestone. This milestone, as Chris said, is going to be about targets. And what we're going to do in this case is a fairly simple operation. We're going to add a new target to this project.

So appearance sample. It's not a big project, but for the purposes, let's assume it's a huge project. And we want to actually factor out some of the code into a static library. So what I'm going to do now is I'm going to go to the targets. I'm going to go to project, go ahead to project new target, select that.

And you want to select the Carbon static library. You can call this whatever you want. I'm going to call it MegaDialog since what I'm going to do is pull in the MegaDialog code into this target. And so you notice what we do is we immediately bring up a target inspector or a get info window for the target. I'm going to go ahead and close that for right now, but we'll be coming back to it.

Now, what I want to do is if we go look in sources, if you disclose sources and disclose dialogues, select the mega dialogue group. You'll notice, okay, here is selection of files. I want to add all these to the target. Well, in 2.1, this is really simple. All I need to do is let me get information on that group, switch to the Targets tab, And then what you're going to do is just change the target membership. Just click on MegaDialog, unclick on Appearance Sample.

And so for example, and just to show you, if you go and disclose the target, now when we compile the sources, you can see all these sources are here. Now, there are a few other things I need to do here. Because I want Appearance Sample to use the MegaDialog product, I need to go ahead and also add the product. So you'll notice here I have this libMegaDialog.a. It's red because we show files in red when they don't exist. These products haven't been built yet.

So for example, I'm going to go ahead and bring up that same info window, this time for the library product. And I can use the same targets panel. I can just say, you know what, I want this to be included in my appearance sample target. Okay. Now there's one final thing.

We need to make sure that the MegaDialog gets built -- library gets built before we build AppearanceSample. And so all I need to do here is just take the MegaDialog target and drag it under the AppearanceSample target, and I've created a target dependency. So now, after doing these steps, if you go ahead and click build, and go to build and bring up the build results window. You notice that we're building the, even though the active target is appearance sample, you should be building the mega dialog target first.

is going to be talking about the Xcode 2.1 and then building the appearance sample target. And it's really that simple for factoring out your code. If you want to take commonly used code and put it into a library, it's really easy in Xcode 2.1 to move pieces of source around, create the target dependencies, make sure the proper things get included. The target pane, as Chris has said in earlier sessions, is something we added to 2.1 to make this just drop dead simple. And so with that, I hand it back over to Chris.

Great. Build succeeded. OK. How many of you got Build succeeded? A few. That's good. OK. More and more will drop off, we expect, by the end. Like I said, this is the first year for this format. We're still learning it. You can now, if you haven't gotten all the way through milestone two, you can either finish up while I'm talking, or you can proceed to milestone three, where we'll pick up So what's different about Targets and Files? Well, you set dependencies by dragging and dropping them, like you do in Code Warrior, except you drag and drop into the build phases under the targets rather than organizing them in the tree in the targets pane. It's still a drag and drop operation, and you still drag one thing to another, but you drag them in the Groups and Files tree right there in your front window rather than having to go to a separate target management pane.

If you want to set the link order-- and several people have asked us about this-- Code Warrior has a separate link order tab where you set link order. Well, in Xcode, if you want to change the link order of files, you rearrange them in the build phase under the target.

That's the link order. You just drag them up and down, your libraries and your source files, and that changes the link order. So same kind of operation, but you do it in a different place. Well, now let's talk about build configurations. There really isn't a peer for this in the Code Warrior environment, but there is in Visual Studio. If you are familiar with project configurations in Visual Studio, target configurations in Xcode are going to be very familiar to you.

Configurations are used instead of creating multiple parallel targets. If you are accustomed to the working style in Code Warrior of create a target, add your files, set the settings, build it, and then clone it to do a different flavor of it, that is something that you can stop doing when you're in Xcode. If you have two targets that are named the same or similar and create the same or similar things and only differ by settings, delete one, take the other one, add a configuration to it, and make the changes in that.

It's that simple. You will have fewer targets to manage, you will have fewer things to build if you move from targets to build configurations. It will make management a lot easier. Target build settings are set on a per configuration basis, so you can have your debug version and your release version of your application differ only by what the configuration setting is, not by what the source code, what the membership is.

And there's powerful searching and filtering inside the Target Inspector to help you find the settings. Instead of having to click through page after page after page of check boxes that are not described, even in tool tips, to figure out what they are, we have a lot of searching, filtering, and documentation built right into the Target Settings Inspector to show you what's what.

So if you're familiar with the target inspector in Code Warrior or the project inspector in Visual Studio, you should be able to find your way around the target inspector in Xcode. So let's do some configuration hands-on on milestone three. Okay. So you'll notice I brought up milestone three.

We're going to pick up the pace a little bit now. The first two milestones were just trying to get people kind of into how the general -- how Xcode works. Now we're going to work a little bit with configurations and also just clean up the target settings in this, to be honest, crusty project.

It has a lot of settings that probably don't apply anymore. They could be set at different levels to be more effective. But before we get to the actual targets, we want to set something at the project, something that's very important. So, you know, everyone's been asking, "Well, how do I build universal binaries?" Well, the first thing you need to do is go to the project.

Select -- you know, click on the info button to bring up the project inspector. And let's set that SDK. We really encourage people, you know, if you want to do universal development, you're going to need to remember to set this SDK for your projects. So go ahead and set that.

Then we're going to be dealing with configurations. And so one thing to make sure is-- If you go ahead and you go to -- sorry, if you go to the View Customized Toolbar, or you can Option-Command-click on the little toolbar widget to bring up the toolbar customization sheet, you're going to want to drag in the active build configuration. It's going to make some of this a little bit easier. So this allows me to see directly in this window exactly which configuration we're using.

So let's just do a quick recap. If I go ahead and look at, for example, the appearance sample target, And if you go to the Build tab, a little bit bigger to make it easier to see.

[Transcript missing]

And so what I really want to do here is take most of my debug settings and use them in a testing context.

Maybe I want to turn off zero link and fix and continue so I can hand it off to my testers. But pretty much it's going to look similar to debug. So let's just go ahead and you can click on the duplicate button and just type in the name testing.

Now, why did I do this? I want to really impress on people. There's nothing special about the names we assign these things. It used to be we had development deployment that caused confusion because people thought they were special in some way. They aren't. They are just the names we decided to go with. In fact, we improved the names, we feel, this time around, to debug and release.

But you can call them whatever you want. And you can have however many you want. One thing to note is that with configurations, they are the same across a project. But if you're going to be using multiple projects, it's up to you, the developer, to manage the configuration namespace across projects in Xcode 2.1.

So let's go ahead and close, let's go ahead actually and switch this over to build. So now we can look at the project and we can look at the target. And what I'm going to do is if you go to collection and select customize settings, you can see the settings that are actually set in this target. And wow, there's a lot of settings in the target. But there are a number of them here that are going to be the same across both appearance sample and mega dialogue. And it seems like a pain if I have to manage them, you know, individually.

So what I'm going to do now is I'm going to move a number of these settings. I'm going to cut them out of the target. We're going to cut them out of the target and we're going to move them over to the project. So, for example, the ones we're going to want to cut, let's take pre-binding. And you can just do discontinuous selection with command in this case. Let's say pre-binding, stripping debug symbols, precompiling prefix header, generating debug symbols, optimization level, generate position dependence. Fix and continue.

And also the warnings. Turns out that warnings tend to not be target specific and most warnings you set are pretty much not just across your project, but they're policies you set up across projects with your team. So they really don't need to be just in the target. They can be at a higher level. So go ahead and you can cut these.

And let's go over the project. And now let's go ahead and let's paste them in here. And let's go over the project. And now let's go ahead and let's paste them in here. In this case, a better word to use is "debug." You'll notice that it's automatically being inherited.

So at this point, now I'm going to leave a little of this up to the reader because the next part, you'll notice I've done this for one configuration. We can now go through and we can do this for each of the configurations. For example, I did it for the active configuration, but now I can, for example, go to my testing configuration.

And look at all my customized settings there. And you'll notice I have a few of them, but there's still a couple that I should probably move over, like the stripping the debug symbols. Let's say all of those. And so, for example, over here, I'll need to move these over also.

So we can just go ahead, pick the same set of settings.

[Transcript missing]

So as you can see here, the project level in this case provides us a nice way to kind of isolate a bunch of settings that we're probably only ever going to set once. And we're probably going to set it the same way for all the targets in this project. Now I've got them in one place.

If I ever have to edit them across all the targets, you can just go to the project inspector and set them there. While you still have things like the product name, the Info.plist file that's being used, a prefix header that are target-specific are placed in your target file. And so with that, I will hand it back to Chris.

Okay, so we have veered out of the familiar into some of the power of Xcode. If you've been using Code Warrior for years, copying and pasting settings from one target to another, not easy to do. You can do it in Xcode. Sorting your settings, searching your settings, finding out what's what.

A lot of power is in the Xcode target inspector. It is different. It's unfamiliar. It's organized in a different way. And the settings themselves, even if you're using the same linker or similar compiler, the settings have different names. But you can use the power of the inspector to find what you're looking for and to set it in a very versatile way. Chris Espinosa Pretty much everything is different.

You don't need to worry about keeping targets in sync with Xcode. We strongly recommend that you use configurations to make different settings. Chris Espinosa You can easily see what's unique and different from one setting to another one, one configuration to another, by choosing the customized settings pop-up in the inspector. It shows you only what's different between that target and the default or the project level.

Anything in boldface is a target-specific override of your project setting or of the default. And multiple targets can be set to the same level. Chris Espinosa So if you've got some policies or some standards, set them once, inherit them across all of your targets automatically. That really will save you in settings management.

We're going to be talking a little bit more about build settings. What are these settings? Scott probably ran you through a ton of settings, some of which were unfamiliar to you. Zero link is one that he's mentioned that is new to you if you have just come to Xcode. Zero link is a way to speed up your compile link debug cycle by eliminating the link part of it.

Chris Espinosa When you change one source file in your build and recompile that one source file, you can relaunch your application and it will dynamically bring in just the object from that source file rather than having to relink your entire application or tool. Chris Espinosa If you're working on an extremely large project where your link times are long, that's very helpful, but it's only good at debug time.

Chris Espinosa It is not useful for a distribution of your product because your build is going to be a lot more complex. Chris Espinosa It's not useful for a distribution of your product because your product doesn't have any of its object code in it. Chris Espinosa Some of those settings are unique to Xcode. You need to find your way around.

Chris Espinosa We do our settings in a different way. Rather than having just panel after panel of checkbox, we have a list of strings, booleans, numbers, checkbox values, things like that. Chris Espinosa You can sort the list, you can search the list, you can filter the list in different ways.

Chris Espinosa What these are is they set values that look kind of like a list. Chris Espinosa They're kind of like environment variables that are expanded at build time and are passed to the individual tools. Chris Espinosa So for each build setting that's in this inspector, there is a symbol that's usually in all caps and with underscores in it that exists inside Xcode, Chris Espinosa and that's expanded to its value when it's passed to the underlying build tool. Chris Espinosa This looks a lot more like what's going on in a make file than it does like what's going on in Code Warrior where all of those settings are Chris Espinosa completely internal.

Chris Espinosa So really you can think of the target editor as just a GUI editor for the settings in a make file. Chris Espinosa That really at the base level is what it's doing. Chris Espinosa And you can use that concept in a very powerful way because you can set the value of one setting to be based on the value of a different setting. Chris Espinosa And you can propagate things through your inheritance chain. Chris Espinosa It's harder to describe than it is to show, so move on to milestone. to milestone four, and we'll show you some of the power of build settings.

Thanks, Chris. So one of the interesting things is if, you know, we've set up these build configurations, they're built differently. Okay, so if I quickly go to give my test or something, how do I know what I've given him is the right build, that it doesn't have zero-length enabled, that it does have -- it has no optimization, et cetera? Well, unfortunately, at least right now, if we go ahead and look at the products, It just says AppearanceSample.app. And actually if you change the active build configuration, we will change to show what's building. You'll notice they all have the same name. That's not that useful for me.

So one thing I might want to do is I might want to have it so that each configuration builds with a different name. So let's go ahead and select the target Appearance Sample. And you can either double click on it, or you can just click the Info button. This will bring up the get info window.

And so we have this product name here. And so for example, you'll notice if you go to all configurations, it's set the same. So let's change that. Let's go to the debug configuration. Double-click on the value, and then let's just add debug. You'll notice automatically we notice that, and so now it's going to be called debug when we build it. And for testing, oh, let's just call it test.

So here now we have the test version of Appearance Sample. So for example, if I change here to the active configuration, it changes to test. And for debug, we have the debug version of Appearance Sample. And we'll leave release alone because this is what we're shipping to our customers. The name is enough. Well, this isn't quite all you'll have to do, but we're almost done. The one final thing you'll need to do is because this is an application, we need to change the Info.plist to automatically pick up the proper product name.

So go ahead and click on the properties tab here, and you'll see you get our simple -- you get our custom UI for editing Info.plist, but for this hands-on, go ahead and click the open Info.plist as file, because we're going to do some direct editing of the file.

So what this will do is open the Info.plist, close the get info window, and you'll notice here that there are a couple places where we have appearance sample, and some of these are valid. So we'll go ahead and click on the get info window, and you'll notice here that there are a couple places where we have appearance sample, and some of these are valid. If we go a little bit further down, there's what's called the bundle name.

Okay, well, it turns out the executable name, we actually should be using So, if you go ahead and just type in $_name, this will actually substitute in that build setting at build time. We've actually supported this since Xcode 2.0. You can put in any build setting, custom ones you define, anything that's listed in the build settings can be used and expanded in an Info.plist.

It's actually quite powerful. And then for the actual bundle name, Now, you may ask the question, well, why did I use a different product name and executable name? It turns out that Xcode can make a distinction. By default, the executable name is just equal to the product name.

But in some more complex projects, and especially in the future, it may be desirable to have your executable be different from the actual name the user sees. So what I'm going to do is I'm going to go ahead and save that. So let's go ahead and switch to the testing configuration and let's go ahead and bring up the build results window in build.

So as I said before, the InfoP list, it can take any build setting and put it in there. And also, I'm not showing this here in this milestone, but the next milestone will actually show you how to refer to one build setting and another. And it's very, very powerful. It provides you a lot of flexibility and kind of allows you to expand on the base build system we give you to kind of customize it to your needs.

So for example, now if I go and run this, you'll notice that now it shows a parent sample in the menu bar and when we have the various dynamically created menu items. And then if you go back to the project window and-- is actually right here, up here in sample test. So with that, back to Chris.

So this is something that is different in Xcode 2.1 from Xcode 2.0. And if you're coming from Code Warrior, this is going to be a lot more familiar. In Xcode 2.0 and earlier when we built different build styles of a product, they overwrote each other. And you couldn't have your debug version or your deployment version or your development version side by side in the file system. In Code Warrior, you're very used to having your debug and release version built independently and live separate lives.

Well, that's because they're separate targets, right? And separate targets are all built independently. In Xcode now, you have the best of both worlds. You can have one target so you don't have to manage the dependencies between two clones. But they can build in separate locations with separate names so you can have your release version and your debug version be separate.

You can see all the settings in one pane. You can use searching and filtering. I've talked about this before. You can base a build setting on the value of another setting with setting name. Scott's going to be doing that in the next milestone, actually. And you can even define custom settings of your own to pass to any tool or script. We'll be doing that one in the next one, too. And defining hierarchies of settings, rather than hard coding everything per project, is really useful. That gets us into customization.

Milestone number five, you can customize your code per configuration. Your code, your resources, your P lists, and even your shell script build phases can all be based off of your build configurations, the settings in your build configurations. This gives you a flexibility to configure large projects that you really don't have in other environments. And so now we're moving on to milestone five, customization.

So all the milestones have kind of led up to this. So what we wanted to do in this milestone was do something kind of cool with build settings, something that wasn't just really simple like changing the name of your application. What we're actually going to do here is we're going to conditionally load in different NIBs based on which configuration we build.

So what I've done is I've gone ahead and made a copy of the main appearance sample NIB and called it Appearance Sample Debug. So if you select Resources, then go to Project, Add to Project, Now, since you're all using 2.1, that means you're on Tiger. So that means we get to use-- and for example, this is an appearance sample 5, so I'll select this. And then I can just search for debug.

There it is. So let's just go ahead and add it. So this is -- and we're going to add this to the appearance sample target. There it is. So let's just go ahead and add it. So this is -- and we're going to add this to the appearance sample target.

Okay, well, this is great. I've added this debug name. But now I need to actually look at the code and see how it's actually calling this appearance sample. So what I'm going to do is go to the Find menu. If you select Find in Project, And let's just go ahead and search on the phrase "appearance sample," because I know that in this case it calls and loads it in programmatically. And so we want to make sure to look for it in the project, and we'll just do a find.

Okay, so we get some definitions. Well, you'll notice here that we get some cases where it's like this. Okay, so this looks like the right thing. We're actually -- it's a T window call. Okay, well, that's great. But then as we go down a little bit, if you'll scroll down, What you find out is they're passing around this appearance sample name to actually give the nib name in T window. It's used during the construction. So this is what I actually want to change. I want to find every place, but they don't define it in one place, which is a little bit unfortunate.

Now, I could do a bunch of if-def-ing around all these places, or we could just do a little bit of work to actually have this defined in one place. So let's actually take this CFStir, and you may wonder, well, if you haven't done core foundation before, well, what's CFStir? Just take a quick detour here and show you our documentation support. There are two things we can do here. One is that you can always control-click -- you can command-double-click on a symbol, and we'll take you to where that's defined.

And then also if you have documentation, you can option double-click something, and this will bring up the documentation window and actually do an API search to provide you documentation. And this is -- it's really nice. I use this all the time. And then once you're in this documentation window, it's, you know, just like you expect, you can click on a link and say, oh, a CFStringRef.

What's a CFStringRef? You can go and you can read it. So that's just a little aside about how to use some of our navigation features. But what we're going to do now is we're going to go ahead and select this whole section of text, the CFStir appearance sample.

Let's use this selection for the find. Mac OS X has a concept of a find pasteboard, and so we can actually paste it into the find pasteboard by using use selection for find. And so let's go ahead and let's find these. Okay, so now I have a much more manageable set. And you'll notice here, for example, what I was looking for earlier, now that I'm looking more specifically, I can see, oh, okay, here's where it creates the nib reference.

So looks like we've picked the right thing. So let's go ahead and let's just give this a name. So instead of putting all this in, we're just going to give it some sort of variable, like let's say app nib name. And then I'll go down here and I'll select everything and click replace. And just say, yes, you want to replace 12 out of 12.

And so now when we look at all these sites again, you can see they've all been changed. OK, so now we need to go define this somewhere. Well, where's a good place to define it? Well, T window, it seems to be always being called there. So maybe I want to go to T window.

Well, another navigation aid we have is Open Quickly. And those of you coming from Code Warrior, we got a lot of requests for this before we added it early in Xcode. And we made some improvements over the revisions. So what I'm going to do here is I'm just going to select T window. And then you can use Command Shift D to open Quickly. But you can also go under the File menu.

It automatically parses that, and if it just gets a class name, it will actually look for the header. But you can also, if I didn't select anything, for example, if you just have an insertion point, it will also do the same thing. So for example, here I'm hitting Shift, I'm using the key equivalent.

For example, if it doesn't have anything that it can actually parse, it just provides a little text dialogue that you can type into. So let's type twindow.h. Okay, so that's great. So we're in twindow.h. So it looks like right before the class, let's just go ahead. And put a definition in here.

Now, this is the hardest typing you're going to have to do, whole hands-on. What we're going to do is we're going to do a simple if-else clause. So we're going to say if use debug nib. Oops. We're not going to make typos. You're not going to make typos. I will, but you won't.

And then what I want to do is I want to declare -- : What was that again? Let's see. CFStringRef. So you notice here I've hit escape to bring up the code completion so that I can actually have it remind me what I was actually going to do. Nibname equals CFster. And so, for example, if we're using the debug nib, we want to say appearance sample debug. Otherwise, let's do the end if. You can just go ahead and you can copy this. And we'll just get rid of the debug.

[Transcript missing]

is we want to actually declare this. Because we're doing this in the header, sorry. I jumped ahead. So now what we've done is we've just defined this external constant CFStringRef called app-nibname. So let's go ahead and save that. Now to quickly get to the implementation file, if you go up here, there's this navigation bar where we show, you know, the number of files that may have been opened in this editor.

We show you the actual file. So, I want to give you a little bit of a quick overview of what we're doing here. So, I want to give you a little bit of a quick overview of what's going on here. So, we're going to start with the Xcode.

We're going to start with this Xcode. So, we're going to start with the Xcode. So, we're going to start with the Xcode. This part. So here what we're saying is if we're using the debug nib, then we're going to set this to CFStringRef. Otherwise, we're going to set it to AppearanceSample.

So now, we should have everything in place. We've actually added the nib file. We have changed the code so it's going to use this constcf string ref variable. And we even have a little ifdef in here. Wait. But there's -- and we have almost everything now. The last thing we need to do is actually set up the build settings.

So you'll remember that I created -- if we go back to the project window, And then for appearance sample, one thing you can do is if you always have one target you're editing a lot, we also have a shortcut, which is under the project menu. It's called Edit Active Target, and I'll give you the name of the target. It's Command-Option-E. So for example, in here, I want to add some settings so that this will work properly. So what I want to do is across all configurations, I actually wanted to find a custom build setting, which we're going to call Use Special Nib.

And in most cases, I actually want to show this debug nib, so let's set it to one. And it turns out the one case where I don't release, I can just go in and change that to zero. Now, that's great. So now I've got this custom build setting. How do I get that pushed down into my code? Well, we use our preprocessor macros build setting and the ability to put one build setting in another. So in this case, just switch over to all settings and type in macros.

So let's just choose the preprocessor macros. And this can actually be the same for all the configurations. So we're going to switch to all configurations, and we're just going to set in here Use debug nib equals, and this is the same, and then we're going to use the same syntax we used in the Info.plist.

We're just going to say use So what this says is that -- and let me make this a little -- and you might want to make it a little wider so you can see it. What it says here now, and if we -- it's a little bit clearer if you now jump to customize settings and clear out the search field, you'll see now we say, okay, we have some preprocessor macros we're going to pass down. Use debug nib is going to be equal to whatever my use special nib build setting was. This allows me across all the configurations to just have one setting that's generic.

And then I can use special build settings to differentiate it across each configuration. So at this point, I should have everything I need. So we're going to go ahead and try to build the test sample. Let's save all the files. If you want, we can go ahead and we can bring up the build results.

Now you notice in this case, we're only rebuilding appearance sample because it turns out that there was nothing we changed in MegaDialog at all. This is all just specific to appearance sample. So you'll notice now I have this little debug menu. If you've ever played with this, you'll know that they don't really have a debug menu. This doesn't do anything, but I kind of ran out of time. And then also in about-- change this to say debug.

But I mean, that's just the beginning. You can do whatever you want. This just shows you this is a really easy way to provide different resources and conditionally with configurations, make it a very simple structure so you can control via configurations which one you're using. And with that, I'll hand it over to Chris.

Okay, I was doing a little wandering around the audience and I saw a lot more closed PowerBooks and a lot more people reading their mail and things like that. This was probably the toughest section to get through and follow through. How many people actually tried to follow along? That's awesome.

Oh, I'm really impressed. Okay, well, the best part is coming up. Let's finish up with this. You saw some real versatile use of Xcode in that. You saw Scott using find and replace, saw him navigating around in documentation, navigating into source code, navigating into framework headers, saw him making changes and rebuilding, adding new files, setting up those files, and conditionally including a file based on a build configuration setting that was passed to the source code in a pre-processing session. Chris Espinosa Okay, well, the best part is coming up.

Let's finish up with this. You saw Scott using find and replace, saw him navigating around in documentation, navigating into source code, navigating into framework headers, setting up those files, and conditionally including a file based on a build configuration setting that was passed to the source code in a pre-processing session.

There really isn't an equivalent for this in Code Warrior. It's more like a GUI to make files, the ability to define a build setting in one place and pass it down into your sources. But now we get to the real interesting part. This is what you came for. If you haven't been following along, open that PowerBook back up, load Milestone 6. We're going to build Intel binaries right here, right now.

To build a universal binary of your application, it just takes two things. One is you need to build it against the SDK, and we set that up earlier. And second is you need to set the architecture, and you do that by a double-click. This is going to be the shortest part, but it's going to be the most valuable for you in the long run. Here's Scott.

So first off, there is no milestone six. There's milestone final. As you can imagine, given the secret nature of this until Monday, we really couldn't post up a milestone that said, look, here's how to build universal binaries. But luckily, this is probably the shortest of all the milestones. So as Chris said, the two things you need-- and let's go to the general pane here-- is you need to set an SDK.

We've already done that. It turns out that we want to do this across the project because both, you know, we're going to need both the parent sample and its static library to be built in Universal. So let's just go to the architectures. And there we go. Okay, so by default, we build for the native architecture. So that means if you're on a PowerPC box, PowerPC. If you're on an Intel box, Intel.

Now you can select this and either you can click on the edit button or you can double click the setting. I'll click the edit button. And you'll notice here, okay, I'm on, yes, we don't have Intel laptops yet, so I'm on PowerPC. But I can go ahead and I can click Intel.

And then I can go ahead and build. I'm sorry if I went through that too fast. But if you should, most of the time in this particular milestone is actually spent building. And so what we've done here is -- and this is actually code that has actually been through a lot.

It's a weird mix. Appearance sample has some new stuff, but it also has really old stuff, too. And it actually turns out that I can build this for Universal without making any code changes. If you're interested in some more of the details, you can go ahead and you can pop open the transcript window here.

And what you'll see is we actually are going through, for example, here we're doing the Intel build, and if I scroll down a little bit later, you'll notice that we're doing PowerPC builds later, if you go through and look. Let's see if I can find one of them.

For example, here, now we're doing the same stuff for PowerPC. And so now if I go out to... If we go to the projects folder again and we actually look at this, we reveal it in the finder, and we bring up a get info window, or even better yet, we just bring up the con... So now we actually have built Appearance Dev Sample and it should just launch. And here now you have a universal binary with two clicks and some build time. With that, Chris.

Now, there are a couple of things about that build you might have noticed if you were following along or saw it on the screen. One thing was that most of the things that we built, we built twice, and that is not unexpected. If you have a precompiled header, you need a different precompiled header for Intel than for PowerPC, because in the system headers, there are a lot of poundifs for Indian issues and things like that that are different. If you have different precompiled headers, you need two sets of precompiled headers, but did you have to set any of that up? No, it happened automatically.

You check the checkbox for two architectures, we built two precompiled headers. Every source file needed to be recompiled twice, compiled against the precompiled headers, against the system headers, to generate a different .o file. There were two sets of .o files, an Intel set, PowerPC set. At the end, each of them was linked into a separate executable, and then the executables were merged together. into one build product.

We didn't have to build our resources twice. We didn't have to copy our resources or build our nibs twice. Everything non-code happened once. Everything code happened twice. There's no separate configuration for PowerPC. It's just an iteration through all the compilation steps about code generation. You just check the checkbox, and the build system and the compiler take care of everything for you.

We're using this method to create a new version of the system. We're using the term Universal here. If you're coming from the old world, you're familiar with Universal interfaces. They're different. They have nothing to do with each other. Forget about Universal interfaces. Universal means using the 10.4 Universal SDK. And that's what it means. That is Universal PowerPC Intel.

It's really best not to use your system provided headers, because the headers on your system are not only for that OS, but they will be for that configuration of the OS, whatever machine you're running on. You can build native on Intel or PowerPC and you'll get an executable native for that machine. If you want to build universal for machines other than the one you're running on, you really, really, really need to build against the SDK. And that will also help you on cross operating system building in the future.

You'll also see one other detail. You notice he got 57 warnings there. And that's because he didn't change to the release build. He was still building his debug build. That debug build still by default uses ZeroLink. Well, ZeroLink is a technology that's tightly tied into the loader. And if you build ZeroLink on a single architecture, but you're building universal using the SDK, you're going to get those warnings. It just meant that he couldn't launch an Intel binary ZeroLink on his PowerPC machine. That's pretty much all it meant. But you notice that the PowerPC build succeeded, and that's what he launched.

So we've taken you through a heck of a lot. We've taken you from opening up an ancient appearance sample application that had its origins in Code Warrior. It's all Carbon. It uses resources. You saw the res build phase going on up there. And it's been updated gradually over the years to run on 10.2.4 and even use some new features. It's been brought into Xcode. We saw reconfiguring it, removing a lot of the old settings, cleaning it up, making it use Xcode 2.1 features, really making it sing with Xcode 2.1, and building it for Intel all in the space of an hour.

Thank you very much for following on. There's a lot more you can do. Come to the labs. If you have an application or you couldn't get through the example, come to the labs. Go to developer.apple.com/wwdc2005. That's where you'll find a lot of Xcode sample code. You'll find sample code for other sessions.

As well, related sessions, to learn more about the Xcode user interface, Wednesday, 5:00, session 403, power programming with Xcode. It's going to be a great session. We're going to take you in depth through a lot of the things like the SCM system, like find and replace, like code completion, like unit testing.

Project management mastery, we're going to give you the inside skinny on build configurations and go into much more depth how to use them in shell script build phases, how to invoke code from the command line as part of an automated build system, things like that. And then if you are bringing code to Xcode for the first time, you're going to need to come to the moving to GCC 4.0 session to learn about the idiosyncrasies of GCC 4.0, where it's pickier about your C++ code and what are the new pragmas you can use in GCC.

Labs, Tuesday, Wednesday, Thursday, starting at 2:00 today, we're going to have the Xcode team, the compiler people, the debugger people. The IDE people, all in the Xcode lab, helping you bring your projects over, helping you check those check boxes and bring your code over to Intel. If you have comments, questions, want to know what our future direction is, have suggestions, come to the feedback forum, Friday, 5:00.

We really don't have time for questions in this session. If you want to follow up, we'll be available in the front row or come to the lab after lunch starting at 2:00 today. Matthew Formica is our representative. He does a great job. You can get him on email. Join the Xcode users discussion list for community-based support.