Clang

This package provides a Julia language wrapper for libclang: the stable, C-exported interface to the LLVM Clang compiler. The libclang API documentation provides background on the functionality available through libclang, and thus through the Julia wrapper. The repository also hosts related tools built on top of libclang functionality.

Installation

Now, the package provides an out-of-box installation experience on Linux, macOS and Windows. You could simply install it by running:

pkg> add Clang

If you want to run the tests to check that everything is working the usual ] test command will work. If you're making changes to the package you can also use ReTest.jl and TestEnv.jl to run the tests (or a selection) iteratively:

# One-liner to keep in your shell history
julia> using TestEnv; TestEnv.activate(); import ReTest, Clang; ReTest.load(Clang)

# Run all the tests. This will be slow the first time because ReTest needs to
# start the worker process for running the tests.
julia> ClangTests.runtests()

# Run a selection of the tests
julia> ClangTests.runtests("comments")

We need to load the ClangTests module with ReTest.load(Clang) because that will take care of tracking all the include'ed test files if Revise is already loaded. This way the tests will be tracked by Revise just like regular package code and the worker process used for running the tests will be kept around, which is a much faster workflow than running ] test.

C-bindings generator

The package includes a generator to create Julia wrappers for C libraries from a collection of header files. The following declarations are currently supported:

  • function: translated to Julia ccall (some caveats about variadic functions, see Variadic Function)
  • struct: translated to Julia struct
  • enum: translated to Enum or CEnum
  • union: translated to Julia struct
  • typedef: translated to Julia typealias to underlying intrinsic type
  • macro: limited support
  • bitfield: experimental support

The following example wraps include/clang-c/*.h from Clang_jll and prints the wrapper to LibClang.jl.

First write a configuration script generator.toml.

[general]
library_name = "libclang"
output_file_path = "./LibClang.jl"
module_name = "LibClang"
jll_pkg_name = "Clang_jll"
export_symbol_prefixes = ["CX", "clang_"]

Then load the configurations and generate a wrapper.

using Clang.Generators
using Clang.LibClang.Clang_jll

cd(@__DIR__)

include_dir = normpath(Clang_jll.artifact_dir, "include")
clang_dir = joinpath(include_dir, "clang-c")

# wrapper generator options
options = load_options(joinpath(@__DIR__, "generator.toml"))

# add compiler flags, e.g. "-DXXXXXXXXX"
args = get_default_args()
push!(args, "-I$include_dir")

headers = [joinpath(clang_dir, header) for header in readdir(clang_dir) if endswith(header, ".h")]
# there is also an experimental `detect_headers` function for auto-detecting top-level headers in the directory
# headers = detect_headers(clang_dir, args)

# create context
ctx = create_context(headers, args, options)

# run generator
build!(ctx)
Compatibility

The generator above is introduced in Clang.jl 0.14. If you are working with older versions of Clang.jl, check older versions of documentation

LibClang

LibClang is a thin wrapper over libclang. It's one-to-one mapped to the libclang APIs. By using Clang.LibClang, all of the CX/clang_-prefixed libclang APIs are imported into the current namespace, with which you could build up your own tools from scratch. If you are unfamiliar with the Clang AST, a good starting point is the Introduction to the Clang AST.