【转载】XCode工程中 Project 和 Targets区别

来源:互联网 发布:炒股软件接口 编辑:程序博客网 时间:2024/04/30 13:04

感谢,转载自:http://blog.sina.com.cn/s/blog_9244b6150102whtv.html


XCode工程中 Targets讲解是本文要介绍的内容,相信很多人都注意到XCode中,有个Target的概念. 这在很多地方都有所体现, 比如打开一个工程后, 左侧的列表中有Targets一项,而在工程界面的顶部菜单中, project里面也有多个涉及到Target的项目,那么这个Target到底是什么呢? 

Apple的人是这样说的:“ Targets that definethe products to build. A target organizes the files andinstructions needed to build a product into a sequence of buildactions that can be taken.”

简单的理解的话, 可以认为一个target对应一个新的product(基于同一份代码的情况下). 但都一份代码了,弄个新product做啥呢? 折腾这个有意思么?

其实这不是单纯的瞎折腾, 虽然代码是同一份, 但编译设置(比如编译条件), 以及包含的资源文件却可以有很大的差别.于是即使同一份代码, 产出的product也可能大不相同.

我们来举几个典型的应用多Targets的情况吧, 比如完整版和lite版; 比如同一个游戏的20关, 30关, 50关版;再或者比如同一个游戏换些资源和名字就当新游戏卖的(喂喂, 你在教些什么...)

Targets之间, 什么相同, 什么不同

既然是利用同一份代码产出不同的product, 那么到底不同Target之间存在着什么样的差异呢?

要解释这个问题, 我们就要来看看一个Target指定了哪些内容.

从XCode左侧的列表中, 我们可以看到一个Target包含了Copy Bundle Resources, CompileSources, Link Binary With Libraries. 其中

Copy Bundle Resources 是指生成的product的.app内将包含哪些资源文件

Compile Sources 是指将有哪些源代码被编译

Link Binary With Libraries 是指编译过程中会引用哪些库文件

通过Copy Bundle Resources中内容的不同设置, 我们可以让不同的product包含不同的资源, 包括程序的主图标等,而不是把XCode的工程中列出的资源一股脑的包含进去.

而这还不是一个target所指定的全部内容. 每个target可以使用一个独立,不同的Info.plist文件. 

我们都知道, 这个Info.plist文件内定义了一个iPhone项目的很多关键性内容, 比如程序名称,最终生成product的全局唯一id等等.
 
   
而且不同的target还可以定义完整的差异化的编译设置, 从简单的调整优化选项, 到增加条件编译所使用的编译条件,以至于所使用的base SDK都可以差异化指定.

创建第二个Target

为什么是第二个? 因为第一个就是创建好工程后的默认Target呀! (废话这么多, 拖走...)

创建target有多种方法, 我们可以从现有的target上复制出一份, 然后略加改动, 也可以完全新建一个target出来.但其实说穿了, 两个方法大同小异

首先我们来看看利用复制的方法创建target

利用复制创建target

我们在XCode左侧的列表中, 展开 Targets 项, 在现有的target上, 右键选择 "Duplicate",或者选中现有target后, 在顶部菜单的Edit内选择"Duplicate"也可以.

此时我们就得到了一个新的target, 而在Resource里面也会得到一个 xxxx copy.plist.这个新的target与原有的target是完全一致的, 余下的就是一些差异化的修改, 这个我们后面再说

创建全新的target

类似复制的方法, 我们可以在左侧的列表中很多地方按下右键菜单, 都可以看到Add中会有"New Target..."一项,而在工程顶部菜单的Project内, 也可以看到这个"New Target..."的身影.

点击后, 首先会让你选择target的类型, 既然我一直所指的都是程序本身, 那么自然选择Application了(至于其他的嘛,有兴趣的自己研究吧, 比如我们可以把程序中的部分提取成一个Static Library).

Next后, 会让你输入一个新的Target的名字, 而不像复制的方法中, 默认生成 xxxxxcopy这样的target名.

但是这样生成出的Target几乎是空的. Copy Bundle Resources, Compile Sources, LinkBinary With Libraries里面都没有任何内容. 编译设置也是完全原始的状态.

可以通过拖拽内容到这些target的设置中, 以及调整编译选项来完成Target的配置。

Target中部分内容的修改方法

其实这段的部分内容, 在非多Targets的工程中也可能会用得到.

由于修改基本都是在工程/编译设置中完成, 因此没有特殊情况, 就不再声明了,打开target对应的工程/编译设置的方法可以采用在该target上右键, 选择get info来做到.

生成的product名称的修改: Packing段内的Product Name一项

Info.plist文件名: Packing段内的Info.plist File一项, 比如复制出来的target觉得那个xxxxxcopy.plist太傻就可以在这里改

条 件编译: 增加一个User-Defined Setting(Target "xxxx"Info的build页的左下角那个齿轮中可以看到这个内容), 在Other C Flag里面填入,比如要定义一个叫做LITE_VERSION的define值, 我们可以写上 "-DLITE_VERSION" 或"-DLITE_VERSION=1". 那么在程序中就可以用

  1. #if defined(LITE_VERSION)  
  2. #else   
  3. #endif  

这样的条件编译来部分差异化代码了

也许有些朋友记得我在代码区贴过的检测破解版的代码, 其中有一种检测方法就是看info.plist是文本还是二进制的,那么我们能否建议一个模拟破解的target, 直接生成文本的info.plist以便测试呢?

当然可以, 在packing段内, 有一项叫"Info.plist Output Encoding", 默认值是Binary,我们只要选成xml, 那么生成出的product.app内的info.plist就直接是文本样式的了.

另外, 向Copy Bundle Resources, Compile Sources, Link Binary WithLibraries内添加/删除文件, 可以在要改动的文件上, 选择get info, 并且切换到Target页,勾选要引用这个文件的target即可. 比如icon.png可以指定给默认target, 而icon_lite.png指定给liteversion的target


[摘要:正在ios开辟时,我们常常会碰到对统一个app开辟多个版本(Pro、Lite、Free)的环境,那里便触及到xcode里经过增加多个targets去举行版本操纵的题目了,上面便简略解释一下:面击左边的工] 

   在ios开发时,我们经常会遇到对同一个app开发多个版本(Pro、Lite、Free)的情况,这里就涉及到xcode里通过添加多个targets来进行版本控制的问题了,下面就简单说明一下:

   点击左侧的工程名称,右侧会出现PROJECT和TARGETS,点击你现在的target,假如叫A,右键弹出菜单中,选择Duplicate,复制一个相同的target,复制的target一般叫Acopy,A copy和A的设置(编译条件、源文件、资源文件)完全一样,此时你可以根据需要修改Acopy的编译条件和资源文件了;


1、A copy的名称是不是显得不够专业?现在来修改一下:

1)首先修改Xcode左上角的target名称:

点击xcode左上角Run、Stop右边的工程名称,下拉框中选择ManageSchemes,在弹出框中,点击A copy那行,点击一次、再点击一次,就可以修改Acopy为你想要的名字了,比如ALite;

2)修改xcode左下方Products下的Acopy.app名称:

点击Targets下你刚才改名后的ALite,点击BulidSetting,搜索Packaging下的Private Headers Folder Path,修改Acopy.app/PrivateHeaders为:ALite.app/PrivateHeaders;


2、修改Bundle Identifier和选择不同的证书,让app区分开来

1)新target需要的.plist文件

    新建一个文件夹X,添加X到项目中,添加时选择target为ALite,不要选targetA了,因为不是共用的;复制原来target的A-Info.plist到X,修改其名称为ALite-Info.plist,xcode中右键AddFile To ...,选择添加到target ALite中;

2)点击target: ALite->Summary:提示你需要选择plist文件,选择1)中添加的ALite-Info.plist;

3)点击target: ALite->Summary:设置Bundle Idenfitier;

4)点击target: ALite->BuildSettings->Code Signing:选择另外的证书;


3、修改程序名称

   一般说来,多个target的程序名称不同,复制zh-Hans.lproj和en.lproj下的InfoPlist.strings文件到X,xcode中右键AddFile To ...,选择添加到targetALite中;然后修改InfoPlist.strings的内容:CFBundleDisplayName="程序名称Lite";

 

4、2个target到现在就创建好了,你添加资源文件的时候,通过选择添加的target来控制不同版本的内容;再说一下预编译宏的事情:target->BuildSetting,搜索:PreprocessorMacros,设置Debug和Release里的预编译宏内容,比如TARGET_VERSION_LITE=1表示lite版本(注意=前后不能右空格,有空格会编译不过),程序中对不同版本这样判断:

 

#if TARGET_VERSION_LITE ==1

...

 

#elif TARGET_VERSION_LITE ==2

...

 

#endif




参考文章:

1、http://blog.163.com/lengfeng_04/blog/static/80470603201273111549529/

 

XCode同一Project创建多个target  

 

 

由于项目需求,同一项目需要发两个版本,两个版本只有小部分不同,特地研究了一下target,小有了解,把创建target的经过记录在案,方便过后查看,如有疏漏,请网友指正。


创建target有两种方式,

1是通过新建target可以通过File-->New-->Target,然后选择其中一个模板来创建,app类型的target,可以选择EmptyApplication模板,不过新建的target有自己的AppDelegate和main,这点还没研究好,如何与原来的AppDelegate和main复用

2.另一种方法是通过对原有的target做duplicate,复制一份,目前只研究了如何通过duplicate来新建target,做下记录。

假设原来的target名字为A,我们需要新建一个targetB


1.在原来的target上右键,选择duplicate,Xcode会复制一个名为A copy的target对象,同时生成一个Acopy-info.plist和A copy的scheme

2. 改名

a)对A copytarget改名,可以直接单击target来修改,改成B

b)Acopy-info.plist,默认生成在程序环境根目录,也就是A.xcodeproj的同级目录中,如果想放到里层(比如与A-info.plist放在同级目录),可以先在Xcode删除Acopy-info.plist索引,然后拷贝文件到制定目录中,然后更名为B-info.plist,在add到project中。在Project的BuildSettings中,修改Info.plistFile选项为B-info.plist的目录(相对路径),这样就可以看到Info页了(就是B-info.plist),接着修改ProductName和Bundleidentifier,使之成为另一个app。PrefixHeader的路径,视具体需求而定是否要修改,如果两个target可以公用同一个PrefixHeader,那么就不需要修改这里的路径

c)修改scheme,在调试的Stop按钮边上,我们可以选择本工程中所有的target来做编译,如果不修改,在这里选择出来的名字就是Acopy,为了与新建的target统一起来,同样也要修改这里的名字。点击scheme选择区,然后选Manager Scheme,找到Acopy,然后改成你需要的名字,比如B


用duplicate的好处是,如果两个target的相同点很多,用duplicate,就可以把相关的设置全部拷贝过来,而不需要做过多的修改


生成一个新的target,一定会与原target有区别,这里可以定义预编译宏,来区分两个版本的不同代码,预编译宏可以在BuildSettings中Preprocessor Macros定义,比如在我们新建的targetB中定义预编译宏MACRO,然后在代码中通过

#if defined(MACRO)

//target  B需要执行的代码

#else

//targetA需要执行的代码

#endif

来区分


其他:BuildPhases(各target编译所包含的内容,需要注意的是,如果创建了target B后,再往A里面添加资源或文件,targetB中不会自动增加这些资源,需要手动添加)

1.CompileSources

需要编译的代码文件

2.Link BinaryWith Libraries

编译所依赖的库

3.Copy BundleResources

编译需要的资源

每个target可以根据具体需要增减里面的内容


2、http://kan.weibo.com/con/3550176548481250?_from=text

http://stackoverflow.com/questions/1807377/xcode-multiple-targets-multiple-internationalized-names

 

同一份代码多个Target,在支持多语言下分别设置其名称的方法

真不好用一个标题来概括这个东西。Xcode 4.2+ 在项目多语言包 xx.lproj 里引入了一个叫InfoPlist.strings 的文件,可以对同一个 App 在不同系统语言下显示不同的 Display Name。比如:

InfoPlist.strings (English) -

"CFBundleDisplayName" = "English Name";
InfoPlist.strings (Chinese) - "CFBundleDisplayName" = "中文";

在单 Target 下很容易做,多 Target 的时候就需要做一点额外的处理。在项目目录下新建与 Target同名的文件夹(同名是为了方便区分),然后将 xx.lproj 文件夹 复制 到各个 Target 下面,目录结构会是这个样子:

./Target1/         
en.lproj/InfoPlist.strings 
       
 
zh-Hans.lproj/InfoPlist.strings
./Target2/ 
        
en.lproj/InfoPlist.strings 
       
 
zh-Hans.lproj/InfoPlist.strings

复制后保持项目目录下还有 xx.lproj 文件夹,里面保留Localizable.strings,因为多语言化一般是通用的,没必要针对每一个 Target 做多语言。复制后的Target1/xx.lproj 下只有 InfoPlist.strings。然后添加到 Xcode 项目里,打开 Xcode -Views - Utilities (Command+Option+0),在 Target Membership 下针对不同的Target 把对应文件夹下的 InfoPlist.strings 对应连接起来,Done。

0 0
原创粉丝点击