如何使用 C 预处理器找到库的完整路径?
How to find the whole path to a library using the C preprocessor?
我正在寻找一个简单的 bash 脚本,当给定一个系统的名称 header 时,它将 return 它的完整路径,从中读取它#include <header>
声明。我已经有一个类似的东西来查找链接器使用的库存档。
ld -verbose -lz -L/some/other/dir | grep succeeded | sed -e 's/^\s*attempt to open //' -e 's/ succeeded\s*$//'
例如,这将 return libz
存档的路径(在我的系统上 /lib/x86_64-linux-gnu/libz.so
)。
对于请求的脚本,我知道我可以获取 gcc
使用的包含目录列表并自己在其中搜索文件,但我正在寻找更准确的模拟内部发生的事情预处理器(除非它很简单)。
您可以使用预处理器来完成这项工作:
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 \
你可以加一点bash-fu把你感兴趣的部分删掉
将输入通过管道传递给预处理器,然后处理输出。 Gcc 预处理器输出插入 #
lines with information and flags 您可以解析。
$ f=stdlib.h
$ echo "#include <$f>" | gcc -xc -E - | sed '\~# [0-9]* "\([^"]*/'"$f"'\)" 1 .*~!d; s///'
/usr/include/stdlib.h
它可以输出多个文件,因为gcc
有#include_next
并且在一些复杂的情况下检测不正确,例如在f=limits.h
中包含多个同名文件。所以你也可以过滤第二行,知道第一行总是 stdc-predef.h
:
$ f=limits.h; echo "#include <$f>" | gcc -xc -E - | sed '/# [0-9]* "\([^"]*\)" 1 .*/!d;s///' | sed '2!d'
/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/include-fixed/limits.h
但真正自己搜索包含路径,并不难:
$ 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
我正在寻找一个简单的 bash 脚本,当给定一个系统的名称 header 时,它将 return 它的完整路径,从中读取它#include <header>
声明。我已经有一个类似的东西来查找链接器使用的库存档。
ld -verbose -lz -L/some/other/dir | grep succeeded | sed -e 's/^\s*attempt to open //' -e 's/ succeeded\s*$//'
例如,这将 return libz
存档的路径(在我的系统上 /lib/x86_64-linux-gnu/libz.so
)。
对于请求的脚本,我知道我可以获取 gcc
使用的包含目录列表并自己在其中搜索文件,但我正在寻找更准确的模拟内部发生的事情预处理器(除非它很简单)。
您可以使用预处理器来完成这项工作:
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 \
你可以加一点bash-fu把你感兴趣的部分删掉
将输入通过管道传递给预处理器,然后处理输出。 Gcc 预处理器输出插入 #
lines with information and flags 您可以解析。
$ f=stdlib.h
$ echo "#include <$f>" | gcc -xc -E - | sed '\~# [0-9]* "\([^"]*/'"$f"'\)" 1 .*~!d; s///'
/usr/include/stdlib.h
它可以输出多个文件,因为gcc
有#include_next
并且在一些复杂的情况下检测不正确,例如在f=limits.h
中包含多个同名文件。所以你也可以过滤第二行,知道第一行总是 stdc-predef.h
:
$ f=limits.h; echo "#include <$f>" | gcc -xc -E - | sed '/# [0-9]* "\([^"]*\)" 1 .*/!d;s///' | sed '2!d'
/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/include-fixed/limits.h
但真正自己搜索包含路径,并不难:
$ 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