Xcode Search Paths 选项配置

Xcode -> Target -> BuildSettingsSearch Paths中, 有两个设置一个是 User Header Search Paths ,一个是 Header Search Paths.其实还有一个废弃的Always Search User Paths
Header Search Paths就是我们平时使用的, 设置头文件搜索路径的方法. 可以通过配置Header Search Paths 来引入头文件, 从而可以使用该类.

Header Search Paths 与 User Header Search Paths 区别

Header Search Paths 管理导入的头文件的路径
Header Search PathsUser Header Search Paths 是具有同样功能的,
区别在于 import 或者 include 头文件时,
Header Search Paths 会多一种方式.

import时, 有两种方式:

#import <SomeClass.h>
#import "SomeClass.h"

若在Header Search Paths中设置SomeClass的路径后, 上面两种方式都可以使用. 但是若在User Header Search Paths中设置后, #import <SomeClass.h> 就会编译报错(include也是一样).

具体一点的区别是,<>是从系统目录空间 (对应Header Search Paths)中搜索文件," " 是从用户目录空间(对应 User Header Search Paths)中搜索文件。如果你把路径加到User Header Search Paths 中,而 <>无法从系统目录空间中找到新加的路径,从而报错。

Library search path

Library Search Paths 管理导入的*.a的路径

Framewrok Search Path

Framework Search Paths 管理导入的*.framework的路径

扩展

1、其实还有另一个设置Always Search User Paths, 如果出现上面这样的错误, 这时把Always Search User Paths设置成 Yes,强制也import<> 也在User Header Search Paths搜索。 但是现在这个设置已经废弃了, 也不必过多探究了.

2、c / c++ 头文件引用问题

  • include <> 引用编译器的类库路径下的头文件
  • include “” 引用工程目录的相对路径的头文件

include 是编译指令,在编译时,编译器会将相对路径替换成绝对路径,因此,头文件绝对路径:

绝对路径 = 搜索路径 + 相对路径

  • Xcode Build Settings 下 Search Paths设置搜索路径,Header Search Paths:头文件搜索路径设置
$(SRCROOT) 和 $(PROJECT_DIR) 都指xxx.xcodeproj所在的父目录

例如:引用工程testDemo/scr/test.h 头文件,

注意:

  • 如果在Header Search Paths中添加$(SRCROOT)/scr,那么头文件引用直接引用 include "test.h"
  • 如果在Header Search Paths中添加$(SRCROOT)/,那么头文件引用直接引用 include "scr/test.h"

一般工作中我们最好都使用相对路径,这样在共同开发项目时,防止发生路径错误问题。
Library / Header Search Paths中写法:

$(SRCROOT) / 当前工程名字 / 需要包含头文件所在文件夹

3、$(inherited)
项目的Framework Search Paths添加$(inherited)参数会从PROJECT -> Build Settings -> Framework Search Paths里面的路径会被其继承,没有的话不会继承。所以一个项目里面有多个target,使用到了同一个库(Library或Framework)那么为了方便我们可以在target添加继承参数,并且PROJECT统一中添加库的路径。

4、non-recursive:默认路径设置,不遍历该目录。
      recursive:遍历该目录,如果路径的属性为recursive,那么编译的时候在找库的路径的时候,会遍历该目录下的所有子目录的库文件。

5、在Other Linker Flags中加入-ObjC或者-all_load或者-force_load
      在ios开发中,我们经常会使用到第三方的一些静态库,导入第三方类库运行程序后你会发现,编译时可以正常编译但是运行时会app会闪退,报出

selector not recognized的错误

一般的第三方库的开发文档中都会写出这种问题的解决方法,在Other Linker Flags中加入-ObjC或者-all_load或者-force_load这样的解决方法。

  • -ObjC
    一般这个参数足够解决前面提到的问题,这个flag告诉链接器把库中定义的Objective-C类和Category都加载进来。这样编译之后的app会变大,因为加载了很多不必要的文件而导致可执行文件变大。但是如果静态库中有类和category的话只有加入这个flag才行,但是Objc也不是万能的,当静态库中只有分类而没有类的时候,Objc就失效了,这就需要使用-all_load或者-force_load了。
  • -all_load
    -all_load会强制链接器把目标文件都加载进来,即使没有objc代码。但是这个参数也有一个弊端,那就是你使用了不止一个静态库文件,那么你很有可能会遇到ld: duplicate symbol错误,因为不同的库文件里面可能会有相同的目标文件 这里会有两种方法解决 1:用命令行就行拆包. 2:就是用下面的这个参数

  • -force_load
    这个flag所做的事情跟-all_load其实是一样的,只是-force_load需要指定要进行全部加载的库文件的路径,这样的话,你就只是完全加载了一个库文件,不影响其余库文件的按需加载 .

Xcode添加静态库以及编译选项配置常见问题
Xcode Search Paths相关配置

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 129,388评论 18 137
  • #include #include 是预处理指令,在编译之前的预处理期执行。它的作用是将引入文件中的内容拷贝到当前...
    寒咯阅读 2,856评论 0 10
  • JMETER中文手册 1. 简介 Apache JMeter是100%纯java桌面应用程序,被设计用来测试客户端...
    捉虫师阅读 27,089评论 0 28
  • 模块化工作中,会指定库与库之间的依赖关系,根据依赖关系分层,但随着开发进行,依赖关系又慢慢被破坏。如何让后续的开发...
    donghuan1阅读 3,091评论 0 3
  • 2018.4.6 几个人一起接视频,我都要抱着手机静静的看着你,看着你的一颦一笑,感觉是多么的幸福啊! 你来陪我聊...
    烟花肆意O阅读 103评论 0 0
  • 洗过澡后,钻进提前打好空调的房间。瞬间感觉到丝丝凉意,不知道是因为空调的存在,还是因为心情缘故。感觉这个房间里的夏...
    浮光若金阅读 578评论 0 1
  • 天涯海角 四面八方 灵魂归于记忆尽头 浩瀚归于微尘 走吧走吧 挥一挥手什么也看不见 感谢你给我一个走四方的梦。 晚安
    西尽阅读 249评论 0 5
  • 【2017年12月21日-007-22】 最近跟着拆书帮一起阅读了《刻意练习》这本书,这次尝试用一种新的方法来看书...
    dream2024阅读 1,214评论 3 7