简体   繁体   English

如何使用 C 预处理器找到库的完整路径?

[英]How to find the whole path to a library using the C preprocessor?

I'm looking for a simple bash script which, when given the name of a system header, will return its full path from which it would be read in a #include <header> statement.我正在寻找一个简单的 bash 脚本,当给定系统 header 的名称时,该脚本将返回其完整路径,在#include <header>语句中将从该路径中读取它。 I already have an analogous thing for looking up the library archive used by linker.我已经有了类似的东西来查找 linker 使用的库档案。

ld -verbose -lz -L/some/other/dir | grep succeeded | sed -e 's/^\s*attempt to open //' -e 's/ succeeded\s*$//'

For example, this will return the path of libz archive ( /lib/x86_64-linux-gnu/libz.so on my system).例如,这将返回libz存档的路径(在我的系统上是/lib/x86_64-linux-gnu/libz.so )。

For the requested script I know that I could take a list of include directories used by gcc and search them for the file myself, but I'm looking for a more accurate simulation of what's happening inside the preprocessor (unless it's that simple).对于请求的脚本,我知道我可以获取gcc使用的包含目录列表并自己搜索文件,但我正在寻找对预处理器内部发生的事情的更准确模拟(除非它很简单)。

You can use the preprocessor to do the work:您可以使用预处理器来完成这项工作:

user@host:~$ echo "#include <stdio.h>" > testx.c && gcc -M testx.c | grep 'stdio.h'
testx.o: testx.c /usr/include/stdc-predef.h /usr/include/stdio.h \

You can add a bit bash-fu to cut the part you are interested in您可以添加一点 bash-fu 来剪切您感兴趣的部分

Pipe the input to preprocessor and then process the output. Pipe 输入到预处理器,然后处理 output。 Gcc preprocessor output inserts # lines with information and flags that you can parse. Gcc 预处理器 output 插入带有您可以解析的信息和标志的#

$ f=stdlib.h
$ echo "#include <$f>" | gcc -xc -E - | sed '\~# [0-9]* "\([^"]*/'"$f"'\)" 1 .*~!d; s//\1/'
/usr/include/stdlib.h

It can output multiple files, because gcc has #include_next and can improperly detect in some complicated cases where multiple filenames are included with the same name, like in f=limits.h .它可以 output 多个文件,因为gcc具有#include_next并且可以在某些复杂情况下不正确地检测到多个文件名包含同名的复杂情况,例如f=limits.h So you could also filter exactly second line, knowing that the first line is always going to be stdc-predef.h :所以你也可以过滤第二行,知道第一行总是stdc-predef.h

$ f=limits.h; echo "#include <$f>" | gcc -xc -E - | sed '/# [0-9]* "\([^"]*\)" 1 .*/!d;s//\1/' | sed '2!d'
/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/include-fixed/limits.h

But really search the include paths yourself, it's not that hard:但真正自己搜索包含路径,并不难:

$ f=limits.h; echo | gcc -E -Wp,-v - 2>&1 | sed '\~^ /~!d; s/ //' | while IFS= read -r path; do if [[ -e "$path/$f" ]]; then echo "$path/$f"; break; fi; done
/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/include-fixed/limits.h

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM