c - C 文件中#include 的路径和给 GCC 的 -I 指令是否应该匹配?
问题描述
我正在查看 AVR 端口的 FreeRTOS 演示项目。Makefile 通过“-I”指令具有指向 RTOS 源文件所在目录的路径。但是,在项目的main.c模块中,#include 没有提供任何这样的路径:
#include "FreeRTOS.h"
所以我无法理解这是仅链接器查找目标文件所需的“-I”指令吗?这是否也意味着一旦文件被编译为目标代码,对于 GCC,如果它知道在哪里查找,它们基本上位于同一个文件夹中?
我之所以感到困惑,是因为我以前见过这样的#include语句:
#include <avr/io.h>
如果 GCC 已经知道io.h的位置,为什么还要在它前面包含“avr”部分?
解决方案
当我们说
#include <foo/bar.h>
编译器通常会bar.h
在一个目录中查找一个文件,该目录foo
在它配置为查找头文件的位置之一中调用。例如,标准头搜索路径通常包含“/usr/include”,因此如果存在“bar.h”文件,将在“/usr/include/foo”中找到它。
如果你-I
像这样使用开关:
-I /usr/include/foo
你也可以写
#include <bar.h>
因为您已将该目录包含foo
在编译器的头文件搜索路径中。
但是,如果foo
是某种库或模块,则使用#include
包含 subdirectory的变体可能更具表现力foo
,而不是操纵标题搜索路径以便您不必这样做。
作为记录,-I
开关对链接行为没有直接影响。
顺便说一句,变体
#include "foo/bar.h"
通常表示foo
与源文件位于同一目录中的目录中的文件。但是,现代编译器似乎也将搜索头路径应用于这些指令。我不确定这是基于标准的行为,还是只是编译器作者试图猜测我们的意图。
推荐阅读
- android - Android Jetpack:如何使用 PagingDataAdapter 在回收器视图中进行多选?
- azure - 使用 dot net 进行 Azure 批处理作业调度
- python - Plotly:如何在构面网格中旋转 yaxis 标题?
- ios - 将名称值对添加到 Firebase 实时数据库中的现有特定键(swift)
- java - 通缉但未调用:Mockito
- kubernetes-ingress - kubernetes-Ingress 资源未按预期工作以使用子域公开 2 个应用程序
- c++ - 具有大量行和列的矩阵的列总和
- c# - 如果用户没有使用 c# 响应,如何在 x 秒内关闭应用程序
- database - 将所有 mongodb 数据库的查询超时设置为 20 分钟
- amazon-web-services - 仅在部署到 AWS 或 Google Cloud 时使用 Okta 登录后 .NET Core 3.1 应用程序中的关联失败异常