当使用Python的libclang时,它似乎不会自动搜索系统的包含路径。
有没有可靠的方法来获得这些路径?我不喜欢硬编码路径,因为我正在编写将在各种UNIX系统上运行的代码。
例如,给定test.cpp
#include <stdio.h>
int main()
{
puts("Hello, world!");
}
和test.py
from clang.cindex import Index
tu = Index.create().parse(None, ["test.cpp"])
print(list(tu.diagnostics))
正在运行python test.py
将打印:
[<Diagnostic severity 4, location <SourceLocation file 'test.cpp', line 1,
column 10>, spelling "'stdio.h' file not found">]
当然,我可以通过
找到系统包含路径$ clang -v -E test.cpp
并将"-Isome/path"
添加到parse
参数列表,即
args = ["-I/Applications/[...]", "test.cpp"]
这实际上有效并且不会产生任何错误。
然而,这不是可移植的,如果我能以编程方式让clang自动使用它们,那将是非常好的。
答案 0 :(得分:2)
这个问题已经有一段时间了,所以我会尝试自己回答。
似乎即使是Clang本身也主要使用硬编码路径。
它枚举候选路径并添加适合当前上下文的路径。这可以在clang/lib/Frontend/InitHeaderSearch.cpp中看到。如,
uses
System.Classes, Winapi.Windows;
type
PIMAGE_NT_HEADERS = ^IMAGE_NT_HEADERS;
PIMAGE_EXPORT_DIRECTORY = ^IMAGE_EXPORT_DIRECTORY;
function ImageNtHeader(Base: Pointer): PIMAGE_NT_HEADERS; stdcall; external 'dbghelp.dll';
function ImageRvaToVa(NtHeaders: Pointer; Base: Pointer; Rva: ULONG; LastRvaSection: Pointer): Pointer; stdcall; external 'dbghelp.dll';
procedure EnumerateImageExportedFunctionNames(const ImageName: string; NamesList: TStrings);
var
i: Integer;
FileHandle: THandle;
ImageHandle: THandle;
ImagePointer: Pointer;
Header: PIMAGE_NT_HEADERS;
ExportTable: PIMAGE_EXPORT_DIRECTORY;
NamesPointer: Pointer;
NamesPtr: PCardinal;
NamePtr: PAnsiChar;
begin
//NOTE: our policy in this procedure is to exit upon any failure and return and empty list
NamesList.Clear;
FileHandle := CreateFile(
PChar(ImageName),
GENERIC_READ,
FILE_SHARE_READ,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0
);
if FileHandle=INVALID_HANDLE_VALUE then begin
exit;
end;
Try
ImageHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil);
if ImageHandle=0 then begin
exit;
end;
Try
ImagePointer := MapViewOfFile(ImageHandle, FILE_MAP_READ, 0, 0, 0);
if not Assigned(ImagePointer) then begin
exit;
end;
Try
Header := ImageNtHeader(ImagePointer);
if not Assigned(Header) then begin
exit;
end;
if Header.Signature<>$00004550 then begin // "PE\0\0" as a DWORD.
exit;
end;
ExportTable := ImageRvaToVa(Header, ImagePointer, Header.OptionalHeader.DataDirectory[0].VirtualAddress, nil);
if not Assigned(ExportTable) then begin
exit;
end;
NamesPtr := ImageRvaToVa(Header, ImagePointer, Cardinal(ExportTable.AddressOfNames), nil);
if not Assigned(NamesPtr) then begin
exit;
end;
for i := 0 to ExportTable.NumberOfNames-1 do begin
NamePtr := ImageRvaToVa(Header, ImagePointer, NamesPtr^, nil);
if not Assigned(NamePtr) then begin
exit;
end;
NamesList.Add(NamePtr);
inc(NamesPtr);
end;
Finally
UnmapViewOfFile(ImagePointer); // Ignore error as there is not much we could do.
End;
Finally
CloseHandle(ImageHandle);
End;
Finally
CloseHandle(FileHandle);
End;
end;
对于Linux,此代码有通知:
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
"i686-apple-darwin10", "", "x86_64", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0",
"i686-apple-darwin8", "", "", triple);
// ...
在llvm_unreachable("Include management is handled in the driver.");
下,我们可以在clang/lib/Driver/
,ToolChains.cpp
和CrossWindowsToolChain.cpp
等文件中找到更多这些路径。
我希望的是MinGWToolChain.cpp
中的代码将通过libclang向Python公开。