KyleMayes / clang-sys

Rust bindings for libclang.
Apache License 2.0
128 stars 65 forks source link

Getting ASTReadError on Linux but not on Windows #162

Closed bafto closed 8 months ago

bafto commented 8 months ago

When using this crate, linking to libclang works fine on both Platforms, but on Linux I always get an 'ASTReadError' as a result from clang_parseTranslationUnit2 while it works on Windows.

Here is the relevant code:

fn main() -> Result<(), Box<dyn Error>> {
    let _args = Args::parse();
    setup_libclang();

    println!("Working directory: {:?}", std::env::current_dir().unwrap());
    let clang_args = Vec::<String>::new();
    let tu = parse("test.h", &clang_args)?;
    print_diagnostics(tu);
    unsafe {
        let cursor = clang_getTranslationUnitCursor(tu);
        clang_visitChildren(cursor, visitor, std::ptr::null_mut());
    }
    Ok(())
}

fn setup_libclang() {
    clang_sys::load().unwrap();
    let library = clang_sys::get_library().unwrap();

    println!("Using libclang {}", library.path().display());
    match library.version() {
        Some(version) => println!("Clang version: {}", version),
        None => {
            println!("Clang version: unsupported");
            std::process::exit(1);
        }
    }
}

#[allow(non_upper_case_globals)]
fn parse(header: &str, include_dirs: &Vec<String>) -> Result<CXTranslationUnit, ClangError> {
    use libc::c_char;
    use libc::c_int;

    let args: Vec<String> = include_dirs.iter().map(|s| format!("-I{}", s)).collect();

    unsafe {
        let index = clang_createIndex(0, 0);
        let mut tu: CXTranslationUnit = std::ptr::null_mut();

        let err_code = clang_parseTranslationUnit2(
            index,
            header.as_ptr() as *const c_char,
            args.as_ptr() as *const *const c_char,
            args.len() as c_int,
            std::ptr::null_mut() as *mut CXUnsavedFile,
            0,
            0,
            &mut tu,
        );

        return match err_code {
            CXError_Success => Ok(tu),
            _ => Err(ClangError::from(err_code)),
        };
    }
}

test.h:

#ifndef TEST_H
#define TEST_H

int foo(int a);

#endif // TEST_H

The output of $cargo run on Linux:

    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/ddp-wrap`
Using libclang /usr/lib/x86_64-linux-gnu/libclang-14.so.14.0.0
Clang version: 12.0.x - 15.0.x
Working directory: "/home/bafto/source/repos/RustRepos/ddp-wrap"
Error: ASTReadError

I have tried this with libclang-12, libclang-14 and libclang-15, and got the same result with each one.

I am running Linux Mint 21. A c++ program which also uses libclang works on the same machine.

The linking to libclang works and the code correctly parses the file on Windows, so I have no idea what could be going on here.

I don't even know if this is a problem with this crate or with something else on my system, but I thought someone here might have had this problem before.