获取 cpp 搜索的包含路径

发布于 2024-09-27 23:42:02 字数 355 浏览 8 评论 0原文

如何获取C预处理器的系统包含搜索路径?这是用于解析任意源文件并需要知道它们 #include 的标头的完整路径名的脚本。让我们暂时忽略用户可以使用编译器标志更改搜索路径的序列。我更喜欢使用 POSIX 系统上的标准工具的解决方案,这样我的脚本几乎不依赖任何东西。

我尝试过:

cpp -v </dev/null | unusually_complex_filter

但这显然没有考虑像 $C{,PLUS}_INCLUDE_PATH 这样的事情。要知道 #include 的向量在哪里,我想我必须知道搜索路径的精确顺序。

How do I obtain the system include search paths of the C preprocessor? This is for a script that parses arbitrary source files and needs to know the full pathnames of the headers they #include. Let's ignore for a moment that the user can alter this sequence of search paths with compiler flags. I'd prefer a solution that uses standard tools found on POSIX systems so my script depends on next to nothing.

I tried:

cpp -v </dev/null | unusually_complex_filter

But this apparently doesn't take in account things like $C{,PLUS}_INCLUDE_PATH. To know where vector of #include <vector> is in, I suppose I must know the search paths in their precise order.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

幻梦 2024-10-04 23:42:02

标准头文件不需要作为包含符合标准的 C 源代码的常规文件进行访问。通常,它们可以作为文件访问,但使用许多扩展名。

也许您可以在源文件上运行预处理器,并使用其输出,该预处理器可以通过 POSIX 兼容方式访问,例如 c99 -E。 POSIX 没有定义预处理器的确切输出,但它通常包含显示每个实际行的来源的特殊行。

The standard headers are not required to be accessible as regular files containing standard-compliant C source. Usually, they are accessible as files but use many extensions.

Perhaps you can run the preprocessor, which is accessible in a POSIX-compliant manner as c99 -E, on the source files and use its output. POSIX does not define the exact output of the preprocessor, but it usually contains special lines that show the origin of each actual line.

晨光如昨 2024-10-04 23:42:02

使用这样的 test.cpp:

#include <string>
#include <iostream>

int main(int, char **)
{
  return 0
}

和 gcc 工具套件中的 cpp ,您可以调用:

cpp test.cpp | grep '^#.*' | awk '{print $3}'

您将得到

"test.cpp"
"<built-in>"
"<command-line>"
"test.cpp"
"/usr/include/c++/4.4/string"
"/usr/include/c++/4.4/string"
"/usr/include/c++/4.4/string"
"/usr/include/c++/4.4/x86_64-linux-gnu/bits/c++config.h"    
"/usr/include/c++/4.4/x86_64-linux-gnu/bits/c++config.h"
"/usr/include/c++/4.4/x86_64-linux-gnu/bits/os_defines.h"

更多行。

显然,您会得到很多“重复项”,因为许多包含文件也被其他包含文件包含。

with test.cpp like this:

#include <string>
#include <iostream>

int main(int, char **)
{
  return 0
}

and cpp from the gcc toolsuite you can call:

cpp test.cpp | grep '^#.*' | awk '{print $3}'

you will get

"test.cpp"
"<built-in>"
"<command-line>"
"test.cpp"
"/usr/include/c++/4.4/string"
"/usr/include/c++/4.4/string"
"/usr/include/c++/4.4/string"
"/usr/include/c++/4.4/x86_64-linux-gnu/bits/c++config.h"    
"/usr/include/c++/4.4/x86_64-linux-gnu/bits/c++config.h"
"/usr/include/c++/4.4/x86_64-linux-gnu/bits/os_defines.h"

and many more lines.

You will obviously get a lot of "duplicates", as many include files are included by other include files as well.

绝對不後悔。 2024-10-04 23:42:02

经过一些聊天来获取上下文后,我认为这个问题只是对cpp解析不同语言的误解。

我不知道 -x 的可移植性如何(或者 -v 的输出格式的可移植性如何),尽管其他编译器可能有非常相似的东西(例如,我相信英特尔的编译器在这里表现相同),但看起来你只需告诉 cpp 您正在使用什么语言来包含它的语言相关的内部配置路径:

$ cpp --version  # my cpp is from gcc
cpp (Ubuntu 4.4.3-4ubuntu5) 4.4.3
...
$ cpp -v </dev/null 2>&1 1>/dev/null | sed -nr 's/^ ([^ ]+)$/\1/p'
/usr/local/include
/usr/lib/gcc/i486-linux-gnu/4.4.3/include
/usr/lib/gcc/i486-linux-gnu/4.4.3/include-fixed
/usr/include/i486-linux-gnu
/usr/include
$ cpp -v -x c++ </dev/null 2>&1 1>/dev/null | sed -nr 's/^ ([^ ]+)$/\1/p'
/usr/include/c++/4.4
/usr/include/c++/4.4/i486-linux-gnu
/usr/include/c++/4.4/backward
/usr/local/include
/usr/lib/gcc/i486-linux-gnu/4.4.3/include
/usr/lib/gcc/i486-linux-gnu/4.4.3/include-fixed
/usr/include/i486-linux-gnu
/usr/include

当您的脚本采用特定于项目的包含路径时,这很好地吻合:

$ mkdir my-include  # or else cpp ignores it
$ cpp -Imy-include -v -x c++ </dev/null 2>&1 1>/dev/null | sed -nr 's/^ ([^ ]+)$/\1/p'
my-include
/usr/include/c++/4.4
/usr/include/c++/4.4/i486-linux-gnu
/usr/include/c++/4.4/backward
/usr/local/include
/usr/lib/gcc/i486-linux-gnu/4.4.3/include
/usr/lib/gcc/i486-linux-gnu/4.4.3/include-fixed
/usr/include/i486-linux-gnu
/usr/include

返回的顺序是搜索的顺序,但是 < >包含跳过“”包​​含的路径(但“”包含搜索<>路径)。在这里,cpp 的输出确实区分了两组路径(如果您需要的话)。

After some chat to get context, I think this question is just a misunderstanding of cpp for parsing different languages.

I don't know how portable -x is (or how portable -v's output format is, for that matter), though other compilers could have something very similar (I believe Intel's compiler behaves identically here, for example), but it seems you just need to tell cpp what language you're using for it to include it's language-dependent, internally-configured paths:

$ cpp --version  # my cpp is from gcc
cpp (Ubuntu 4.4.3-4ubuntu5) 4.4.3
...
$ cpp -v </dev/null 2>&1 1>/dev/null | sed -nr 's/^ ([^ ]+)$/\1/p'
/usr/local/include
/usr/lib/gcc/i486-linux-gnu/4.4.3/include
/usr/lib/gcc/i486-linux-gnu/4.4.3/include-fixed
/usr/include/i486-linux-gnu
/usr/include
$ cpp -v -x c++ </dev/null 2>&1 1>/dev/null | sed -nr 's/^ ([^ ]+)$/\1/p'
/usr/include/c++/4.4
/usr/include/c++/4.4/i486-linux-gnu
/usr/include/c++/4.4/backward
/usr/local/include
/usr/lib/gcc/i486-linux-gnu/4.4.3/include
/usr/lib/gcc/i486-linux-gnu/4.4.3/include-fixed
/usr/include/i486-linux-gnu
/usr/include

This dovetails nicely when your script takes project-specific include paths:

$ mkdir my-include  # or else cpp ignores it
$ cpp -Imy-include -v -x c++ </dev/null 2>&1 1>/dev/null | sed -nr 's/^ ([^ ]+)$/\1/p'
my-include
/usr/include/c++/4.4
/usr/include/c++/4.4/i486-linux-gnu
/usr/include/c++/4.4/backward
/usr/local/include
/usr/lib/gcc/i486-linux-gnu/4.4.3/include
/usr/lib/gcc/i486-linux-gnu/4.4.3/include-fixed
/usr/include/i486-linux-gnu
/usr/include

The returned order is the order to search, however <> includes skip the paths for "" includes (but "" includes do search <> paths). Here, cpp's output does distinguish the two sets of paths, if you need that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文