Skip to content

Expose clang resource/include directory through CMake variable #58918

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
tristan957 opened this issue Nov 10, 2022 · 7 comments
Open

Expose clang resource/include directory through CMake variable #58918

tristan957 opened this issue Nov 10, 2022 · 7 comments
Labels
clang:as-a-library libclang and C++ API

Comments

@tristan957
Copy link

tristan957 commented Nov 10, 2022

I am using libclang to parse C source files. Given a small program like:

#include <stddef.h>

int main(void)
{
  size_t hello = 5;
  return hello;
}

libclang should report fatal error: 'stddef.h' file not found.

On my system (Fedora 36), the resource directory is located:

$ clang -print-resource-dir
/usr/lib64/clang/14.0.5

Which means the include directory is located at $(clang -print-resource-dir)/include). The clang cmake modules already expose a variable called CLANG_INCLUDE_DIRS, but the only directory exposed in this variable is $CMAKE_INSTALL_PREFIX/include, which isn't helpful for what I need.

Ideally these constants would be exposed in a cross buildsystem way like #9777, but I am willing to settle for just appending to the CLANG_INCLUDE_DIRS array since that should be as little effort as possible to solve what I need.

@efriedma-quic
Copy link
Collaborator

Normal usage patterns of libclang should normally find clang's resource directory without requiring you to explicitly pass it in. If that isn't happening, something has gone wrong. See CIndexer::getClangResourcesPath.

@EugeneZelenko EugeneZelenko added clang:as-a-library libclang and C++ API and removed new issue labels Nov 10, 2022
@tristan957
Copy link
Author

tristan957 commented Nov 10, 2022

Here is how I am using libclang

    database = clang_CompilationDatabase_fromDirectory(builddir, &error);
    if (error) {
        fprintf(stderr, "Failed to read the compilation database\n");
        return EX_IOERR;
    }
int
mock_collect(const char *file)
{
    char **argv;
    CXIndex index;
    CXCursor cursor;
    unsigned int argc;
    enum CXErrorCode ret;
    CXTranslationUnit tu;
    unsigned int real_argc;
    CXCompileCommand command;
    CXCompileCommands commands;

    commands = clang_CompilationDatabase_getCompileCommands(database, file);
    if (clang_CompileCommands_getSize(commands) != 1) {
        fprintf(stderr, "More than one series of compile commands detected for %s\n", file);
        return EX_SOFTWARE;
    }
    command = clang_CompileCommands_getCommand(commands, 0);

    argc = clang_CompileCommand_getNumArgs(command);
    argv = calloc(argc + 2, sizeof(*argv));
    argv[0] = "-DHSE_MOCK=__attribute__((__annotate__(\"mock\")))";
    argv[1] = "-I";
    argv[2] = includedir; // $resourcedir/include
    real_argc = 3;
    for (unsigned int i = 1; i < argc; i++) {
        CXString arg = clang_CompileCommand_getArg(command, i);
        const char *arg_data = clang_getCString(arg);

        /* Ignore warnings */
        if (strstr(arg_data, "-W") == arg_data)
            continue;

        argv[real_argc++] = strdup(arg_data);

        clang_disposeString(arg);
    }

    index = clang_createIndex(0, 1);
    ret = clang_parseTranslationUnit2(index, file, (const char **)argv, real_argc - 1, NULL, 0, 0,
        &tu);
    if (ret) {
        fprintf(stderr, "Failed to parse the translation unit: %d\n", ret);
        return EX_SOFTWARE;
    }

    cursor = clang_getTranslationUnitCursor(tu);
    clang_visitChildren(cursor, visit_tu, NULL);

    clang_disposeTranslationUnit(tu);
    clang_disposeIndex(index);
    clang_CompileCommands_dispose(commands);

    for (unsigned int i = 3; i < real_argc; i++)
        free(argv[i]);
    free(argv);

    return 0;
}

I just started using libclang, so I don't know what I might be doing wrong. I can point at the repository this exists in, but this is pretty much everything.

@tristan957
Copy link
Author

I tried switching to clang_parseTranslationUnit2FullArgv(), but that just has the same problems.

@tristan957
Copy link
Author

tristan957 commented Nov 14, 2022

Here is a command like which I pass to clang_parse...().

clang -Ilib/libhse-3.so.3.1.0.p -Ilib -I../lib -Ilib/include -I../lib/include -Iinclude -I../include -Ilib/util/include -I../lib/util/include -Ilib/mpool/include -I../lib/mpool/include -Isubprojects/xxHash-0.8.1 -I../subprojects/xxHash-0.8.1 -Isubprojects/lz4-1.9.3/lib -I../subprojects/lz4-1.9.3/lib -Isubprojects/cJSON-1.7.15/include-workaround-meson -I../subprojects/cJSON-1.7.15/include-workaround-meson -Isubprojects/hyperloglog -I../subprojects/hyperloglog -Ilib/error/include -I../lib/error/include -Ilib/logging/include -I../lib/logging/include -Ilib/pidfile/include -I../lib/pidfile/include -Ilib/rest/include -I../lib/rest/include -Isubprojects/rbtree -I../subprojects/rbtree -Isubprojects/crc32c -I../subprojects/crc32c -Isubprojects/xoroshiro -I../subprojects/xoroshiro -fvisibility=hidden -fcolor-diagnostics -D_FILE_OFFSET_BITS=64 -O0 -g -fmacro-prefix-map=../= -DDEBUG_RCU -fstack-protector-all -DHSE_BUILD_DEBUG -D_GNU_SOURCE -D_LGPL_SOURCE -DLOG_DEFAULT=7 -DLEVEL1_DCACHE_LINESIZE=64 -DURCU_INLINE_SMALL_FUNCTIONS -fPIC -pthread -DXXH_INLINE_ALL -DXXH_STATIC_LINKING_ONLY -MD -MQ lib/libhse-3.so.3.1.0.p/util_lib_dax.c.o -MF lib/libhse-3.so.3.1.0.p/util_lib_dax.c.o.d -c -x c-header -std=gnu11 /home/tpartin/Projects/hse/lib/util/include/hse/util/dax.h -DHSE_MOCK=__attribute__((__annotate__("mock"))) -I /usr/lib64/clang/14.0.5/include

Note that the last 2 arguments are me trying to work around this issue

@efriedma-quic
Copy link
Collaborator

Looks like the relevant bits were last touched in https://reviews.llvm.org/D124815 . CC @aykevl

@tristan957
Copy link
Author

I appreciate your help up to this point with my issue :)

@aykevl
Copy link
Contributor

aykevl commented Nov 17, 2022

@efriedma-quic true, but the patch should only have an effect when dladdr returns NULL - and thus only turn a crash into a non-crash. So I doubt it's related to this bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:as-a-library libclang and C++ API
Projects
None yet
Development

No branches or pull requests

4 participants