include_path详解

include_path详解

1.php默认的包含路径为 .;C:\php\pear 即为当前目录和C:\php\pear目录


2.如果设置ini_set("include_path", "");  则改变为默认们目录(即为上面的)

运行时的包含顺序:

1.如果为绝对路径  则直接包含, 并结束(找不到直接退出).

2.如果是是相对路径((形如./file, ../dir/file)  则跳过include_path的作用逻辑, 直接解析相对路径(找不到直接退出)

   注意:在使用相对路径的包含文件的情况下,如果一个文件被另一个文件所包含,则这个文件的”相对“则指的是包含他的那个文件

3.都不是以上两种情况

会根据include_path,和当前执行文件的path组成一个待选的目录列表 (即先include path  再当前文件所在的目录,注意:文件的真实目录

然后, 依次从待选列表头部开始, 根据PATH_SEPARATOR(windows下是”;”,linux下是":")取出待选列表中的一个路径, 然后把要包含的文件名附加在这个路径后面, 进行尝试. 如果成功包含, 则返回(不在向下寻找), 否则继续下一个待选路径.

小结:

1. 因为使用include_path和相对路径的情况下, 性能会和寻找的次数有关, 最坏的情况下, 如果你有10个include_path, 那么最多可能会重试11次才能找到要包含的文件, 所以, 在能使用绝对路径的情况下最好使用绝对路径.

 

2. 因为目录相对路径的basedir, 永远都是当前工作路径, 如果要使用, 需要和实际部署路径相关, 所以实际使用的很少(当然, 也有借助chdir来完成的模块).

 

3. 在模块化的系统设计中, 一般应该在模块内, 通过获取模块的部署路径(dirname(__FILE__), php5.3以后更是提供了__DIR__常量)从而使用绝对路径.

原文地址:http://www.laruence.com/2010/05/04/1450.html

 

<think>这段代码是 CMake 中用于查找 glog 库的头文件路径,并将其添加到目标(BridgeLibrary)的包含目录中。下面我将详细解释每一部分: ### 代码解释 ```cmake find_path(GLOG_INCLUDE_DIR glog/logging.h PATHS ${CMAKE_CURRENT_SOURCE_DIR}/glog/include NO_DEFAULT_PATH ) ``` 1. **`find_path` 命令**: - 用于查找包含指定文件的目录路径。 - 第一个参数 `GLOG_INCLUDE_DIR` 是存储结果的变量名。 - 第二个参数 `glog/logging.h` 是要查找的文件名(相对路径形式)。 2. **`PATHS` 参数**: - 指定搜索路径列表,这里只指定了一个路径:`${CMAKE_CURRENT_SOURCE_DIR}/glog/include`。 - `CMAKE_CURRENT_SOURCE_DIR` 是 CMake 变量,表示当前处理的 CMakeLists.txt 文件所在的目录。 3. **`NO_DEFAULT_PATH` 选项**: - 禁用默认的搜索路径(如系统默认路径),只在指定的 `PATHS` 中查找。 - 这样可以确保只在项目内的指定位置查找,避免意外找到系统安装的版本。 --- ```cmake if(NOT GLOG_INCLUDE_DIR) message(FATAL_ERROR "glog headers not found in ${CMAKE_CURRENT_SOURCE_DIR}/glog/include") endif() ``` 4. **检查是否找到**: - 如果 `GLOG_INCLUDE_DIR` 变量为空(即未找到头文件),则触发致命错误。 - `message(FATAL_ERROR ...)` 会停止配置过程,并显示错误信息。 --- ```cmake target_include_directories(BridgeLibrary PRIVATE ${GLOG_INCLUDE_DIR}) ``` 5. **添加到目标包含目录**: - `target_include_directories` 将找到的路径添加到目标(BridgeLibrary)的包含路径中。 - `PRIVATE` 表示这个包含路径只用于构建目标本身,不会传递给依赖此目标的其他目标。 ### 工作流程 1. 在 `${CMAKE_CURRENT_SOURCE_DIR}/glog/include` 目录下查找 `glog/logging.h` 文件。 2. 如果找到,将目录路径存储在 `GLOG_INCLUDE_DIR` 变量中。 3. 如果没找到,报错并停止配置。 4. 将找到的路径添加到目标(BridgeLibrary)的包含路径中。 ### 潜在问题与改进 1. **路径问题**: - 如果项目结构发生变化,路径可能需要调整。 - 改进:使用更灵活的路径定义,例如: ```cmake set(GLOG_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/glog") find_path(GLOG_INCLUDE_DIR glog/logging.h PATHS ${GLOG_ROOT_DIR}/include NO_DEFAULT_PATH ) ``` 2. **多平台支持**: - 当前代码只在指定路径查找,如果需要支持系统安装的 glog,可以增加回退查找: ```cmake find_path(GLOG_INCLUDE_DIR glog/logging.h PATHS ${GLOG_ROOT_DIR}/include # 首先在项目内查找 PATH_SUFFIXES glog # 额外的子目录尝试 DOC "Path to glog headers" ) ``` 3. **版本兼容性**: - 如果 glog 版本不同,头文件路径可能不同(如旧版本可能直接放在 `include` 下)。 - 改进:增加版本检查逻辑。 ### 完整示例(增强版) ```cmake # 设置 glog 根目录(假设在项目内) set(GLOG_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/glog") # 查找头文件 find_path(GLOG_INCLUDE_DIR NAMES glog/logging.h PATHS ${GLOG_ROOT_DIR}/include NO_DEFAULT_PATH ) # 如果项目内没找到,尝试系统路径(可选) if(NOT GLOG_INCLUDE_DIR) find_path(GLOG_INCLUDE_DIR glog/logging.h) endif() # 检查是否找到 if(NOT GLOG_INCLUDE_DIR) message(FATAL_ERROR "Failed to find glog headers. Please install glog or set GLOG_ROOT_DIR.") endif() # 添加到目标 target_include_directories(BridgeLibrary PRIVATE ${GLOG_INCLUDE_DIR}) ``` ### 注意事项 - **区分项目内和系统库**:如果项目内自带了 glog 源码,建议使用 `add_subdirectory(glog)` 并链接目标,而不是手动管理包含路径。 - **依赖管理**:对于现代 CMake,推荐使用 `find_package` 查找系统库,并导入目标(如果 glog 支持的话)。 §§相关问题§§: 1. CMake 中 `find_package` 和 `find_path` 有什么区别? 2. 如何让 CMake 在项目内找不到依赖时自动下载并编译? 3. `target_include_directories` 的 PUBLIC、PRIVATE 和 INTERFACE 有什么区别? 4. 如何在 CMake 中正确处理第三方库的版本兼容性问题?</think># CMake 中 `find_path` 命令详解与使用 这段代码是 CMake 中用于查找第三方库头文件路径的标准方法,特别是针对 Google Logging (glog) 库。下面我将详细解释每一部分的作用和原理: ## 完整代码解释 ```cmake # 查找 glog 头文件路径 find_path(GLOG_INCLUDE_DIR glog/logging.h PATHS ${CMAKE_CURRENT_SOURCE_DIR}/glog/include NO_DEFAULT_PATH ) # 检查是否找到 if(NOT GLOG_INCLUDE_DIR) message(FATAL_ERROR "glog headers not found in ${CMAKE_CURRENT_SOURCE_DIR}/glog/include") endif() # 将找到的路径添加到目标 target_include_directories(BridgeLibrary PRIVATE ${GLOG_INCLUDE_DIR}) ``` ## 逐行解析 ### 1. `find_path` 命令 ```cmake find_path(GLOG_INCLUDE_DIR glog/logging.h PATHS ${CMAKE_CURRENT_SOURCE_DIR}/glog/include NO_DEFAULT_PATH ) ``` - **`GLOG_INCLUDE_DIR`**: 存储查找结果的变量名 - **`glog/logging.h`**:要查找的具体头文件(相对路径) - **`PATHS`**: 指定搜索路径列表 - **`${CMAKE_CURRENT_SOURCE_DIR}/glog/include`**: 具体搜索路径 - **`NO_DEFAULT_PATH`**: 禁用默认的系统搜索路径 **作用**:在指定目录下查找 `glog/logging.h` 文件,如果找到,将完整路径存储到 `GLOG_INCLUDE_DIR` 变量中。 ### 2. 检查结果 ```cmake if(NOT GLOG_INCLUDE_DIR) message(FATAL_ERROR "glog headers not found in ${CMAKE_CURRENT_SOURCE_DIR}/glog/include") endif() ``` - **`NOT GLOG_INCLUDE_DIR`**: 检查变量是否为空(未找到) - **`message(FATAL_ERROR ...)`**: 如果未找到,终止配置过程并显示错误信息 ### 3. 添加包含路径 ```cmake target_include_directories(BridgeLibrary PRIVATE ${GLOG_INCLUDE_DIR}) ``` - **`BridgeLibrary`**: 目标名称(可执行文件或库) - **`PRIVATE`**: 作用域限定符 - **`${GLOG_INCLUDE_DIR}`**: 要添加的包含路径 **作用**:将找到的头文件路径添加到 `BridgeLibrary` 目标的包含路径中,使编译器能正确找到头文件。 ## 关键概念详解 ### 1. `find_path` 命令参数 | 参数 | 说明 | 示例 | |------|------|------| | 变量名 | 存储结果的变量 | `GLOG_INCLUDE_DIR` | | 头文件 | 要查找的文件 | `glog/logging.h` | | `PATHS` | 搜索路径列表 | `${CMAKE_CURRENT_SOURCE_DIR}/glog/include` | | `PATH_SUFFIXES` | 路径后缀 | `include/glog` | | `NO_DEFAULT_PATH` | 禁用系统路径 | 只在指定路径搜索 | | `REQUIRED` | 强制要求 | CMake 3.18+ 支持 | ### 2. 作用域限定符 | 限定符 | 作用域 | 继承性 | |--------|--------|--------| | `PRIVATE` | 仅当前目标 | 不传递给依赖者 | | `INTERFACE` | 仅依赖者 | 不用于当前目标 | | `PUBLIC` | 当前目标和依赖者 | 完全继承 | ### 3. 路径变量 | 变量 | 说明 | 示例值 | |------|------|--------| | `CMAKE_CURRENT_SOURCE_DIR` | 当前 CMakeLists.txt 所在目录 | `/project/src` | | `CMAKE_SOURCE_DIR` | 顶级 CMakeLists.txt 所在目录 | `/project` | | `PROJECT_SOURCE_DIR` | 当前项目目录 | `/project` | ## 高级用法与改进 ### 1. 多路径搜索 ```cmake find_path(GLOG_INCLUDE_DIR glog/logging.h PATHS ${CMAKE_CURRENT_SOURCE_DIR}/glog/include ${CMAKE_SOURCE_DIR}/third_party/glog/include /usr/local/include PATH_SUFFIXES glog # 尝试在路径后添加/glog ) ``` ### 2. 使用缓存变量 ```cmake set(GLOG_ROOT_DIR "" CACHE PATH "Root directory of glog installation") find_path(GLOG_INCLUDE_DIR glog/logging.h HINTS ${GLOG_ROOT_DIR} PATH_SUFFIXES include ) ``` ### 3. 现代 CMake 方法(推荐) ```cmake # 使用 find_package(如果 glog 提供 CMake 支持) find_package(glog CONFIG REQUIRED) target_link_libraries(BridgeLibrary PRIVATE glog::glog) ``` ### 4. 添加版本检查 ```cmake if(GLOG_INCLUDE_DIR) # 检查 glog 版本 file(READ "${GLOG_INCLUDE_DIR}/glog/logging.h" GLOG_HEADER) string(REGEX MATCH "#define GLOG_VERSION [0-9]+" GLOG_VERSION "${GLOG_HEADER}") if(GLOG_VERSION LESS 2023000) message(WARNING "Found glog version ${GLOG_VERSION}, requires at least 2023.0.0") endif() endif() ``` ## 完整示例:查找并链接 glog ```cmake cmake_minimum_required(VERSION 3.12) project(MyProject) # 选项:使用系统 glog 还是内置 option(USE_SYSTEM_GLOG "Use system-installed glog" OFF) if(USE_SYSTEM_GLOG) # 尝试查找系统安装的 glog find_package(glog QUIET) endif() if(glog_FOUND) message(STATUS "Using system glog") target_link_libraries(BridgeLibrary PRIVATE glog::glog) else() # 使用内置 glog set(GLOG_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/glog") # 查找头文件 find_path(GLOG_INCLUDE_DIR glog/logging.h PATHS ${GLOG_ROOT_DIR}/include NO_DEFAULT_PATH ) # 查找库文件 find_library(GLOG_LIBRARY NAMES glog PATHS ${GLOG_ROOT_DIR}/lib NO_DEFAULT_PATH ) if(GLOG_INCLUDE_DIR AND GLOG_LIBRARY) message(STATUS "Using bundled glog") target_include_directories(BridgeLibrary PRIVATE ${GLOG_INCLUDE_DIR}) target_link_libraries(BridgeLibrary PRIVATE ${GLOG_LIBRARY}) else() message(FATAL_ERROR "glog not found, please install or set USE_SYSTEM_GLOG=ON") endif() endif() ``` ## 常见问题解决方案 ### 1. 找不到头文件 - **原因**:路径错误或文件不存在 - **解决**: ```cmake message(STATUS "Searching for glog in: ${CMAKE_CURRENT_SOURCE_DIR}/glog/include") file(GLOB GLOG_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/glog/include/glog/*.h") if(NOT GLOG_HEADERS) message(WARNING "No glog headers found at expected location") endif() ``` ### 2. 跨平台路径问题 ```cmake # 统一路径格式 file(TO_CMAKE_PATH "${PROJECT_SOURCE_DIR}/glog/include" GLOG_SEARCH_PATH) find_path(GLOG_INCLUDE_DIR glog/logging.h PATHS ${GLOG_SEARCH_PATH} NO_DEFAULT_PATH ) ``` ### 3. 多个候选路径 ```cmake # 尝试多个可能位置 set(GLOG_POSSIBLE_PATHS "${CMAKE_SOURCE_DIR}/glog" "${CMAKE_SOURCE_DIR}/third_party/glog" "${CMAKE_SOURCE_DIR}/external/glog" ) find_path(GLOG_INCLUDE_DIR glog/logging.h PATHS ${GLOG_POSSIBLE_PATHS} PATH_SUFFIXES include ) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值