dpp icon indicating copy to clipboard operation
dpp copied to clipboard

c standard library doesn't work on macOS

Open John-Colvin opened this issue 7 years ago • 8 comments
trafficstars

Everything complains about not being able to find the stdint types, e.g. Error parsing '/usr/local/include/nanomsg/nn.h': error: unknown type name 'uint64_t'

even a simple file that just does #include <stdlib.h> doesn't work: Error: object.Exception@../../.dub/packages/libclang-master/libclang/source/clang/package.d(61): Error parsing '/usr/include/stdlib.h': error: unknown type name 'uint8_t'

John-Colvin avatar Apr 05 '18 16:04 John-Colvin

That has to be because of the system headers. I don't know how to find them on MacOS (nor can I try since I don't have access to a mac). On Linux this works (and is being used):

string[] systemPaths() @safe {
    import std.process: execute;
    import std.string: splitLines, stripLeft;
    import std.algorithm: map, countUntil;
    import std.array: array;

    const res = execute(["gcc", "-v", "-xc", "/dev/null", "-fsyntax-only"]);
    if(res.status != 0) throw new Exception("Failed to call gcc:\n" ~ res.output);

    auto lines = res.output.splitLines;

    const startIndex = lines.countUntil("#include <...> search starts here:") + 1;
    assert(startIndex > 0);
    const endIndex = lines.countUntil("End of search list.");
    assert(endIndex > 0);

    return lines[startIndex .. endIndex].map!stripLeft.array;
}

atilaneves avatar Apr 05 '18 19:04 atilaneves

that works fine, it gets /usr/include/stdlib.h it's just that clang can't seem to handle the header it finds.

John-Colvin avatar Apr 05 '18 20:04 John-Colvin

Hmm. This may be to do with incompatibilities between libclang and the system headers, because the system headers belong to an entirely different toolchain (still clang in this case, but not the same clang).

I tried modifying the libclang wrapper to look up the paths using the clang that came with my libclang installation, which avoided any libclang errors about failing to parse the headers, but then choked because the "block pointer" C extension stuff in the modern headers confuses dpp

e.g.

Could not translate cursor Cursor(FunctionDecl, "atexit_b", Type(FunctionProto, "int (void (^ _Nonnull)(void))"), Type(Int, "int")) sourceRange: SourceRange("/usr/include/stdlib.h", 281:1, 281:90) children: [Cursor(FirstAttr, "", Type(Invalid, "")), Cursor(ParmDecl, "", Type(BlockPointer, "void (^)(void)"))]
Error: Type kind BlockPointer not supported: Type(BlockPointer, "void (^)(void)")

John-Colvin avatar Apr 05 '18 20:04 John-Colvin

General problem of precedence. For example imapfilter has a file called regexp.h and GCC standard library has a defunct stub with that name too. So using the -i flag it looks in the wrong order for problem at hand and fails to compile.

Laeeth avatar Apr 05 '18 21:04 Laeeth

Why are the system paths needed? DStep doesn't need them. The compiler will find them by itself.

jacob-carlborg avatar Apr 11 '18 14:04 jacob-carlborg

BTW, here's the result of the above command using Xcode 9.2.

$ gcc -v -xc /dev/null -fsyntax-only
Apple LLVM version 9.0.0 (clang-900.0.39.2)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
 "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.12.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -fsyntax-only -disable-free -disable-llvm-verifier -discard-value-names -main-file-name null -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -fno-strict-return -masm-verbose -munwind-tables -target-cpu penryn -target-linker-version 305 -v -dwarf-column-info -debugger-tuning=lldb -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/9.0.0 -fdebug-compilation-dir /Users/jacobc/.dub/packages/libclang-master -ferror-limit 19 -fmessage-length 158 -stack-protector 1 -fblocks -fobjc-runtime=macosx-10.12.0 -fencode-extended-block-signature -fmax-type-align=16 -fdiagnostics-show-option -fcolor-diagnostics -x c /dev/null
clang -cc1 version 9.0.0 (clang-900.0.39.2) default target x86_64-apple-darwin16.7.0
ignoring nonexistent directory "/usr/local/include"
#include "..." search starts here:
#include <...> search starts here:
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/9.0.0/include
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
 /usr/include
 /System/Library/Frameworks (framework directory)
 /Library/Frameworks (framework directory)
End of search list.

jacob-carlborg avatar Apr 11 '18 14:04 jacob-carlborg

System paths have always been needed with libclang in my experience. I don't know how dstep does it.

atilaneves avatar Apr 13 '18 10:04 atilaneves

For Clang, what's needed is the internal headers. DStep embeds these in the executable (so far only a few of them) [1]. If you use the standard C library of course that is needed as well, but the compiler will find that automatically.

Keep in mind that the internal headers might not be the same for GCC and for Clang. Invoking the system compiler to get the path to the internal headers might not be a good idea. There's a chance that it won't work for a specific combination of platform and the version of Clang that d++ is built against.

[1] https://github.com/jacob-carlborg/dstep/blob/master/clang/Compiler.d

jacob-carlborg avatar Apr 13 '18 11:04 jacob-carlborg