查找 include 指令使用了哪个文件

Find which file was used by an include directive

有没有办法获取#include <hdr.h>指令读取的文件的绝对路径? 对于 #include "hdr.h" 指令? 我在 Win 10 / Msys2 下工作。

我的意思是在 src/sha1-git.c 的编译过程中找到哪个 stdint.h,因为:

  1. 它应该声明 uint32_t 但显然它没有这样做,根据我得到的

    $ make -V=1
    
    /bin/sh ../../libtool  --tag=CC   --mode=compile gcc -DPACKAGE_NAME=\"aircrack-ng\" -DPACKAGE_TARNAME=\"aircrack-ng\" -DPACKAGE_VERSION=\"1.5.2\" -DPACKAGE_STRING=\"aircrack-ng\ 1.5.2\" -DPACKAGE_BUGREPORT=\"https://forum.aircrack-ng.org\" -DPACKAGE_URL=\"\" -DPACKAGE=\"aircrack-ng\" -DVERSION=\"1.5.2\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DLT_OBJDIR=\".libs/\" -D_REVISION=\"1.5.2\" -DHAVE_OPENSSL_CRYPTO_H=1 -DHAVE_OPENSSL_CMAC_H=1 -DHAVE_OPENSSL_CMAC_H=1 -DHAVE_SQLITE3_H=1 -DHAVE_SQLITE3=1 -DHAVE_SQLITE=1 -D_FILE_OFFSET_BITS=64 -DHAVE_PTHREAD_PRIO_INHERIT=1 -D_REENTRANT=1 -DHAVE___MINGW_ALIGNED_MALLOC=1 -DCACHELINE_SIZE=64 -DINTEL_ASM=1 -DCACHELINE_SIZE=64 -I.  -I../.. -I../../src/include -I../../src   -DCYGWIN -DMSYS2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -D_FORTIFY_SOURCE=2 -pthread   -Wall -O3 -std=gnu99 -fno-strict-aliasing -Wpointer-arith -Wstrict-overflow=2 -Wstrict-prototypes -fvisibility=hidden -Wno-unused-but-set-variable -Wno-array-bounds  -mconsole -mwindows -DMSYS2 -MT libaircrack_crypto_la-sha1-git.lo -MD -MP -MF .deps/libaircrack_crypto_la-sha1-git.Tpo -c -o libaircrack_crypto_la-sha1-git.lo `test -f 'sha1-git.c' || echo './'`sha1-git.c
    libtool: compile:  gcc -DPACKAGE_NAME=\"aircrack-ng\" -DPACKAGE_TARNAME=\"aircrack-ng\" -DPACKAGE_VERSION=\"1.5.2\" "-DPACKAGE_STRING=\"aircrack-ng 1.5.2\"" -DPACKAGE_BUGREPORT=\"https://forum.aircrack-ng.org\" -DPACKAGE_URL=\"\" -DPACKAGE=\"aircrack-ng\" -DVERSION=\"1.5.2\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DLT_OBJDIR=\".libs/\" -D_REVISION=\"1.5.2\" -DHAVE_OPENSSL_CRYPTO_H=1 -DHAVE_OPENSSL_CMAC_H=1 -DHAVE_OPENSSL_CMAC_H=1 -DHAVE_SQLITE3_H=1 -DHAVE_SQLITE3=1 -DHAVE_SQLITE=1 -D_FILE_OFFSET_BITS=64 -DHAVE_PTHREAD_PRIO_INHERIT=1 -D_REENTRANT=1 -DHAVE___MINGW_ALIGNED_MALLOC=1 -DCACHELINE_SIZE=64 -DINTEL_ASM=1 -DCACHELINE_SIZE=64 -I. -I../.. -I../../src/include -I../../src -DCYGWIN -DMSYS2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -D_FORTIFY_SOURCE=2 -pthread -Wall -O3 -std=gnu99 -fno-strict-aliasing -Wpointer-arith -Wstrict-overflow=2 -Wstrict-prototypes -fvisibility=hidden -Wno-unused-but-set-variable -Wno-array-bounds -mconsole -mwindows -DMSYS2 -MT libaircrack_crypto_la-sha1-git.lo -MD -MP -MF .deps/libaircrack_crypto_la-sha1-git.Tpo -c sha1-git.c  -DDLL_EXPORT -DPIC -o .libs/libaircrack_crypto_la-sha1-git.o
    sha1-git.c: In function 'blk_SHA1_Final':
    sha1-git.c:328:21: error: 'uint32_t' undeclared (first use in this function); did you mean 'wint_t'?
      padlen[0] = htonl((uint32_t)(ctx->size >> 29));
    

编辑

  1. 在我的Msys2的子目录树中有好几个stdint.h作为候选。我 应该 能够通过检查编译命令行来跟踪 "by hand" 包含哪个 stdint.h,列出包含目录的顺序等等,我做到了之前几次。 但我的意思是自动执行此操作,以避免错误。

PS: 因为我在 Msys2 下,我改变了(递归地)所有出现的 #include <arpa/inet.h> 经过 #include <winsock.h>src/*.hsrc/*.c 中。 在文件 src/sha1-git.c 中我添加了 #include <stdint.h> 紧接着(插入第 43 行)得到 uint32_t.

PS2: 还有一个文件 src/aircrack-crypto/sha1-git.c 没有 #include <stdint.h>。 这个文件的编译是问题所在。我在另一个文件中添加了 #include ... 并继续编译 .

PS3:我的意思是完成这项工作,所以也许这个特定 OP 的答案只是朝着目标迈出了一步,但还不够...... 编辑 2 确认。 不得不执行make V=1 CFLAGS="-I/usr/include" LDFLAGS="-L/usr/lib"后(否则编译common.c时没有发现sys/wait.h),得到

.../MSYS2Portable/App/msys32/mingw64/x86_64-w64-mingw32/include/winsock.h:309:34: error: conflicting types for 'gethostname'                                                                                                                                                                       
   WINSOCK_API_LINKAGE int WSAAPI gethostname(char *name,int namelen);                                                                                                    
                                  ^~~~~~~~~~~                                                                                                                             
In file included from .../MSYS2Portable/App/msys32/usr/include/unistd.h:4,                                               
                 from common.c:42:                                                                                                                                        
.../MSYS2Portable/App/msys32/usr/include/sys/unistd.h:300:6: note: previous declaration of 'gethostname' was here        
  int gethostname (char *__name, size_t __len);                                                                                                                           
      ^~~~~~~~~~~                                                                                                                                                         
make[2]: *** [Makefile:713: libaircrack_util_la-common.lo] Error 1                                                                                                        

mingw64/x86_64-w64-mingw32/include 中的文件似乎与 usr/include 中的文件不一致。 而且mingw64/x86_64-w64-mingw32/include中没有sys/wait.h,所以我还要在搜索路径中添加usr/include,给我带来麻烦。

我可能会放弃在 Msys2 下编译,我会得到一个 vbox。

将 material 从评论转移到答案并扩展它。

使用 GCC,-H 选项列出了包含的 header,同时还指示了嵌套级别。不过,您需要指定您使用的是哪个编译器;适用于 GCC 的可能适用于 Clang,但可能不适用于其他编译器。

由于您使用的是自动没收的项目和 GCC,因此对于如何获取特定文件的信息,您至少有两个选择。

  1. 广泛——不具体:

    ./configure CC='gcc -H'
    

    这会将 C 编译器设置为 gcc -H,这会产生噪音。无论如何这样做可能是明智的,但可能只有在配置阶段出现问题(除非下一个选项中的警告最终适用)。

  2. 缩小 — 特定文件:

    make …normal options…   CC='gcc -H' problemchild.o
    

    这会在编译特定问题 child 源文件时将 C 编译器设置为 gcc -H。如果你正在处理一个源代码在多个目录中的项目,或者如果源代码在一个目录中而 object 代码在另一个目录中,或者一些构建系统使用的其他变体。

无论哪种方式,或使用任何变体,这个想法的关键部分是您告诉系统您的编译器的名称是 gcc -H 而不仅仅是 gcc。这通常可以工作。有时,系统会为 C 编译器使用 CC 以外的 Make 宏名称(并且用于 C++ 编译器的宏名称也可能有所不同)。在这种情况下,您必须找出它使用的名称(例如 ./configure CC=/opt/gcc/bin/gcc 通常有效,但您可能需要找到使用 /opt/gcc/bin/gcc 的位置并相应地使用 makefile。

尽快停止使用 -H 选项。它在大型系统上产生大量输出。例如,在我所做的构建中,这可能是几百行 header。但是,使用它可以提供很多信息。