XCode环境变量及路径设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
一般我们在xcode里面配置包含工程目录下头文件的时候,都要关联着相对路径和绝对路径,如果只是自己用这个项目,用绝对路径的问题不大,但是如果你把工程发给别人,别人就要在改这个绝对路径,这时候绝对路径的缺点立马出现。
 
所以在修改User Header Search Paths这个选项的时候使用
"$(SRCROOT)/当前工程名字/需要包含头文件所在文件夹"
将上面的双引号里面的字符串拷贝之后,你会发现这个“$(SRCROOT)”,会自动变成当前工程所以的目录。
这样就可以了,发给别人,别人也不用在去修改路径了。
 
 
 
 
xcode4的环境变量,Build Settings参数,workspace及联编设置
一、xcode4中的环境变量
 
$(BUILT_PRODUCTS_DIR)
build成功后的,最终产品路径--可以在Build Settings参数的Per-configuration Build Products Path项里设置
 
$(TARGET_NAME)
目标工程名称
 
$(SRCROOT)
工程文件(比如Nuno.xcodeproj)的路径
 
$(CURRENT_PROJECT_VERSION)
当前工程版本号
 
  
 
其他:
 
当编译静态库,设备选模拟器(iPhone 5.0 Simulator),未设置任何Build Settings参数时,默认的基础路径:
 
/Users/xxx/Library/Developer/Xcode/DerivedData/xxxWorkspace-caepeadwrerdcrftijaolkkagbjf
 
下面用$()代替上面一长串东东
 
$(SYMROOT) = $()/Build/Products
 
$(BUILD_DIR) = $()/Build/Products
 
$(BUILD_ROOT) =  $()/Build/Products
 
这三个变量中的$()不会随着Build Settings参数的设置而改变
 
相反,以下可以通过设置而改变
 
$(CONFIGURATION_BUILD_DIR) = $()/Build/Products/Debug-iphonesimulator
 
$(BUILT_PRODUCTS_DIR) = $()/Build/Products/Debug-iphonesimulator
 
$(CONFIGURATION_TEMP_DIR) = $()/Build/Intermediates/UtilLib.build/Debug-iphonesimulator
 
$(TARGET_BUILD_DIR) = $()/Build/Products/Debug-iphonesimulator
 
$(SDK_NAME) = iphonesimulator5.0
 
$(PLATFORM_NAME) = iphonesimulator
 
$(CONFIGURATION) = Debug
 
$(TARGET_NAME) = UtilLib
 
$(EXECUTABLE_NAME) = libUtilLib.a 可执行文件名
 
${IPHONEOS_DEPLOYMENT_TARGET} 5.0
 
$(ACTION) = build
 
$(CURRENTCONFIG_SIMULATOR_DIR) 当前模拟器路径
 
$(CURRENTCONFIG_DEVICE_DIR) 当前设备路径
 
  
 
$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME =
 
$()/Build/Products/Debug-iphonesimulator
 
$(PROJECT_TEMP_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) = $()/Build/Intermediates/UtilLib.build/Debug-iphonesimulator
 
  
 
自定义变量
 
${CONFIGURATION}-iphoneos 表示:Debug-iphoneos
 
${CONFIGURATION}-iphonesimulator 表示:Debug-iphonesimulator
 
$(CURRENTCONFIG_DEVICE_DIR) = ${SYMROOT}/${CONFIGURATION}-iphoneos
 
$(CURRENTCONFIG_SIMULATOR_DIR) = ${SYMROOT}/${CONFIGURATION}-iphonesimulator
 
自定义一个设备无关的路径(用来存放各种架构arm6/arm7/i386输出的产品)
 
$(CREATING_UNIVERSAL_DIR) = ${SYMROOT}/${CONFIGURATION}-universal
 
自定义变量代表的值
 
$(CURRENTCONFIG_DEVICE_DIR) = $()/Build/Products/Debug-iphoneos
 
$(CURRENTCONFIG_SIMULATOR_DIR) = $()/Build/Products/Debug-iphonesimulator
 
$(CREATING_UNIVERSAL_DIR) = $()/Build/Products/Debug-universal
 
  
 
iphoneos5.0下的编译脚本:
 
xcodebuild -project  "UtilLib.xcodeproj"  -configuration  "Debug"  -target  "UtilLib"  -sdk  "iphoneos5.0"  -arch  "armv6 armv7"  build RUN_CLANG_STATIC_ANALYZER= NO   $(BUILD_DIR)= "${BUILD_DIR}"  BUILD_ROOT= "${BUILD_ROOT}"
 
  
 
iphonesimulator5.0下的编译脚本:
 
xcodebuild -project  "UtilLib.xcodeproj"  -configuration  "Debug"  -target  "UtilLib"  -sdk  "iphonesimulator5.0"  -arch  "i386"  build RUN_CLANG_STATIC_ANALYZER= NO  $(BUILD_DIR)= "${BUILD_DIR}"   BUILD_ROOT= "${BUILD_ROOT}"
 
加上下面一句表示输出到文件:
 
"${BUILD_ROOT}.build_output"
 
  
 
lipo脚本工具:合并iPhone模拟器和真机的静态类库,生成通用库
 
lipo -create -output  "${CREATING_UNIVERSAL_DIR}/${EXECUTABLE_NAME}"  "${CURRENTCONFIG_DEVICE_DIR}/${EXECUTABLE_NAME}"          "${CURRENTCONFIG_SIMULATOR_DIR}/${EXECUTABLE_NAME}"
 
意思是:把"${CURRENTCONFIG_DEVICE_DIR}目录下的.a文件,和${CURRENTCONFIG_SIMULATOR_DIR}目录下的.a文件合并,
 
在${CREATING_UNIVERSAL_DIR}目录下,生成两个设备都通用的静态库,
 
例如:lipo -create -output xy.a x.a y.a
 
  
 
二、xcode4中build Settings常见参数解析
 
1.Installation Directory:安装路径
 
静态库编译时,在Build Settings中Installation Directory设置“$(BUILT_PRODUCTS_DIR)”
 
Skip Install设为 YES
 
Installation Directory默认为/usr/local/lib
 
因为Build Location默认时,.a文件会放在很长(比如:/Users/xxx/Library/Developer/Xcode/DerivedData/xxxProgram
 
dalrvzehhtesxdfqhxixzafvddwe/Build/Products/Debug-iPhoneos)的路径下,或是我们target指定的路径
 
Skip Install如果是 NO ,可能会被安装到默认路径/usr/local/lib
 
2.Public Headers Folder Path:对外公开头文件路径
 
设为“include”(具体的头文件路径为:$(BUILT_PRODUCTS_DIR)/include/xx.h)
 
在最终文件.a同级目录下生成一个include目录
 
默认:/usr/local/include
 
Public Headers Folder Path这个路径就是使用这lib的某工程需要依赖的外部头文件.导入这路径后,#include/import  "xx.h" 才能看到
 
3.User Header Search Paths:依赖的外部头文件搜索路径
 
设置为“$(BUILT_PRODUCTS_DIR)/include”
 
和2中路径对应
 
4.Per-configuration Build Products Path:最终文件路径
 
比如设为“../app”,就会在工程文件.xcodeproj上一层目录下的app目录里,创建最终文件
 
默认为$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
 
等于$(BUILT_PRODUCTS_DIR)
 
5.Per-configuration Intermediate Build Files Path:临时中间文件路径
 
默认为:$(PROJECT_TEMP_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
 
6.Code Signing Identity:真机调试的证书选择
 
选一个和Bundle identifier相对应的证书
 
Library Search Paths:库搜索路径
 
Architectures:架构,设为 armv6 或 armv7
 
Valid Architectures:应用框架,可以设为 armv6、 armv7 或i386
 
Product Name:工程文件名,默认为$(TARGET_NAME)
 
Info.plist File:info文件路径
 
Build Variants:默认为normal
 
Other Linker Flags:其他链接标签
 
设为“-ObjC”
 
当导入的静态库使用了类别,需要设为-ObjC
 
iOS Deployment Target:ios部署对象
 
比如可以选择设为,ios3到ios5的一种版本
 
Prefix Header:预编头文件(比如:UtilLib/UtilLib-Prefix.pch)
 
Precompile Prefix Header:设为“Yes”,表示允许加入预编译头
 
  
 
三、workspace(工作区)
 
作用:管理多个工程(project),多工程联编
 
  
 
四、workspace多工程联编设置
 
一、
 
1.新建一个静态库工程,比如UtilLib,并生成UtilLib.h和UtilLib.m文件
 
2.选中需要公开的头文件,
 
 
把右侧栏的Target Membership中设置为 public
 
 
或则,选中工程目录target的Build Phases标签的 copy  headers项,在 public 中添加要公开的头文件
 
 
3.Architectures设为:armv6 armv7
 
4.Valid Architectures设为:armv6 armv7 i386
 
5.Build Products Path设为:$(SRCROOT)/../build
 
6.Per-configuration Build Products Path设为:
 
$(SRCROOT)/../build/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
 
7.Per-configuration Intermediate Build Files Path设为:
 
$(SRCROOT)/../build/$(TARGET_NAME).build/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
 
8.设置安装路径:Installation Directory项
 
 
9.设置对外公开的头文件路径:Public Headers Folder Path项
 
 
 
 
10.为静态库添加依赖的shell脚本
 
选中工程目录target的Build Phases标签,点击由下角的Add Build Phase按钮
 
 
在弹出的菜单里选择Add run script项,然后页面中会多出一个Run Script项
 
 
在黑框里填写 "$SRCROOT/mergeArmSymbols.sh"
 
 
建立对此脚本的依赖(编译静态库的后会运行此脚本)
 
如果编译时设备选的是iphone simulator:
 
则此脚本会在对应iphone device的产品目录Debug-iphoneos中,生成对device有用的.a静态库,
 
相反,如果设备选的是iphone device:
 
则此脚本会在对应iphone simulator的产品目录Debug-iphoneos中,生成对simulator有用的.a静态库
 
最后,此脚本调用lipo工具,把本工程生成静态库与此脚本生成的静态库合并,生成simulator和device都通用的.a文件
 
  
 
11.具体bash shell脚本如下:
 
[plain] view plaincopy
mergeArmSymbols.sh 
  # Version 2.0 (updated for Xcode 4, with some fixes) 
    
  # Author: Adam Martin - http://twitter.com/redglassesapps 
  # Based on: original script from Eonil (main changes: Eonil's script WILL NOT WORK in Xcode GUI - it WILL CRASH YOUR COMPUTER) 
 
    
  #################[ Tests: helps workaround any future bugs in Xcode ]######## 
 
  DEBUG_THIS_SCRIPT= "true" 
    
  if  [ $DEBUG_THIS_SCRIPT =  "true" 
  then 
  echo  "########### TESTS #############" 
  echo  "Use the following variables when debugging this script; note that they may change on recursions" 
  echo  "BUILD_DIR = $BUILD_DIR" 
  echo  "BUILD_ROOT = $BUILD_ROOT" 
  echo  "CONFIGURATION_BUILD_DIR = $CONFIGURATION_BUILD_DIR" 
  echo  "BUILT_PRODUCTS_DIR = $BUILT_PRODUCTS_DIR" 
  echo  "CONFIGURATION_TEMP_DIR = $CONFIGURATION_TEMP_DIR" 
  echo  "TARGET_BUILD_DIR = $TARGET_BUILD_DIR" 
  echo  "SDK_NAME = $SDK_NAME" 
  echo  "PLATFORM_NAME = $PLATFORM_NAME" 
  echo  "CONFIGURATION = $CONFIGURATION" 
  echo  "TARGET_NAME = $TARGET_NAME" 
  echo  "ARCH_TO_BUILD = $ARCH_TO_BUILD" 
  echo  "ARCH_TO_BUILD = $ARCH_TO_BUILD" 
  echo  "ACTION = $ACTION" 
  echo  "SYMROOT = $SYMROOT" 
  echo  "EXECUTABLE_NAME = $EXECUTABLE_NAME" 
  echo  "CURRENTCONFIG_SIMULATOR_DIR = $CURRENTCONFIG_SIMULATOR_DIR" 
  echo  "CURRENTCONFIG_DEVICE_DIR = $CURRENTCONFIG_DEVICE_DIR" 
    
  echo  "#############Other###########" 
  echo  "BUILD_DIR/CONFIGURATION/EFFECTIVE_PLATFORM_NAME = $BUILD_DIR/$CONFIGURATION$EFFECTIVE_PLATFORM_NAME" 
    
  echo  "PROJECT_TEMP_DIR/CONFIGURATION/EFFECTIVE_PLATFORM_NAME = $PROJECT_TEMP_DIR/$CONFIGURATION$EFFECTIVE_PLATFORM_NAME" 
    
  fi 
    
  #####################[ part 1 ]################## 
  # First, work out the BASESDK version number 
  #    (incidental: searching for substrings in sh is a nightmare! Sob) 
    
  SDK_VERSION=$(echo ${SDK_NAME} | grep -o  '.\{3\}$'
    
  # Next, work out if we're in SIM or DEVICE 
    
  if  [ ${PLATFORM_NAME} =  "iphonesimulator" 
  then 
  OTHER_SDK_TO_BUILD=iphoneos${SDK_VERSION} 
  ARCH_TO_BUILD= "armv6 armv7" 
  else 
  OTHER_SDK_TO_BUILD=iphonesimulator${SDK_VERSION} 
  ARCH_TO_BUILD= "i386" 
  fi 
    
  echo  "XCode has selected SDK: ${PLATFORM_NAME} with version: ${SDK_VERSION} (although back-targetting: ${IPHONEOS_DEPLOYMENT_TARGET})" 
  echo  "...therefore, OTHER_SDK_TO_BUILD = ${OTHER_SDK_TO_BUILD}" 
 
  #####################[ end of part 1 ]################## 
    
  #####################[ part 2 ]################## 
 
  # IF this is the original invocation, invoke whatever other builds are required 
 
  # Xcode is already building ONE target... build ONLY the missing platforms/configurations. 
    
  if  "true"  == ${ALREADYINVOKED:- false } ] 
  then 
  echo  "RECURSION: Not the root invocation, don't recurse" 
  else 
  # Prevent recursion 
  export ALREADYINVOKED= "true" 
    
  echo  "RECURSION: I am the root... recursing all missing build targets..." 
  echo  "RECURSION: ...about to invoke: xcodebuild -configuration \"${CONFIGURATION}\" -target \"${TARGET_NAME}\" -sdk \"${OTHER_SDK_TO_BUILD}\" -arch \"${ARCH_TO_BUILD}\" ${ACTION} RUN_CLANG_STATIC_ANALYZER=NO" 
  xcodebuild -project  "${TARGET_NAME}.xcodeproj"  -configuration  "${CONFIGURATION}"  -target  "${TARGET_NAME}"  -sdk  "${OTHER_SDK_TO_BUILD}"  -arch  "${ARCH_TO_BUILD}"  ${ACTION} RUN_CLANG_STATIC_ANALYZER= NO  BUILD_DIR= "${BUILD_DIR}"  BUILD_ROOT= "${BUILD_ROOT}"  "${BUILD_ROOT}.build_output" 
  ACTION= "build" 
    
  # Merge all platform binaries as a fat binary for each configurations. 
    
  # Calculate where the (multiple) built files are coming from: 
  CURRENTCONFIG_DEVICE_DIR=${SRCROOT}/../build/${CONFIGURATION}-iphoneos 
  CURRENTCONFIG_SIMULATOR_DIR=${SRCROOT}/../build/${CONFIGURATION}-iphonesimulator 
    
  echo  "Taking device build from: ${CURRENTCONFIG_DEVICE_DIR}" 
  echo  "Taking simulator build from: ${CURRENTCONFIG_SIMULATOR_DIR}" 
    
  CREATING_UNIVERSAL_DIR=${SRCROOT}/../build/${CONFIGURATION}-universal 
  echo  "...outputing a universal arm6/arm7/i386 build to: ${CREATING_UNIVERSAL_DIR}" 
    
  # ... remove the products of previous runs of this script 
  #      NB: this directory is only created by this script - it should be safe to delete 
    
  rm -rf  "${CREATING_UNIVERSAL_DIR}" 
  mkdir  "${CREATING_UNIVERSAL_DIR}" 
    
 
  echo  "lipo: for current configuration (${CONFIGURATION}) creating output file: ${CREATING_UNIVERSAL_DIR}/${EXECUTABLE_NAME}" 
  lipo -create -output  "${CREATING_UNIVERSAL_DIR}/${EXECUTABLE_NAME}"  "${CURRENTCONFIG_DEVICE_DIR}/${EXECUTABLE_NAME}"  "${CURRENTCONFIG_SIMULATOR_DIR}/${EXECUTABLE_NAME}" 
    
  #######custom######## 
  #copy universal lib to ../libs 
  libsDir=../libs 
  includeDir=../include 
    
  rm -rf  "${libsDir}" 
  mkdir -p  "${libsDir}" 
    
  echo  "cp -R ${CREATING_UNIVERSAL_DIR}/${EXECUTABLE_NAME} ${libsDir}" 
    
  cp -R  "${CREATING_UNIVERSAL_DIR}/${EXECUTABLE_NAME}"  "${libsDir}" 
    
  echo  "cp -R ${CURRENTCONFIG_DEVICE_DIR}/include ${includeDir}" 
    
  cp -R  "${CURRENTCONFIG_DEVICE_DIR}/include"  "${includeDir}" 
    
  fi 
 
 
下载右边的图片,然后把后缀改为.sh(其实就是上面的脚本,因为博客园只能上传图片)
 
静态库编译后的目录结构如下:
 
 
 
  
 
二、
 
1.新建主工程,比如Nuno,添加对静态库的依赖
 
点击工程,在Build Phases标签的Link Binary With Libraries项中点击加号添加UtilLib.a库
 
 
 
 
选中上面的红色项,在右边栏的Location选Relative to Project,把值设为../libs/libUtilLib.a
 
2.设置主工程依赖的外部头文件路径:User Header Search Paths项
 
$(SRCROOT)/../include
 
3.设置Header Search Paths为:$(SRCROOT)/../include
 
4.设置Library Search Paths为:$(SRCROOT)/../libs
 
编译运行即可实现联编
 
  
 
(备注:选择模拟器iphone 5.0 simulator,编译静态库的时,最终文件会在Debug-iphonesimulator,就算成功.a文件还是红色,
 
这是可能是xcode的bug,不会自动切换路径
 
因为$(BUILT_PRODUCTS_DIR)所指的位置,是build/Debug-iphonesos,不是包含最终.a文件的Debug-iphonesimulator;
 
选择ios Device,编译成的最终文件才在build/Debug-iphonesos下,.a文件变成非红色
 
所有得用mergeArmSymbols.sh脚本来解决)
 
 
 
reference:
http: //blog.sina.com.cn/s/blog_6de18992010190kk.html
http: //www.cnblogs.com/xiaodao/archive/2012/03/28/2422091.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值