Skip to content

Commit

Permalink
Use Clang.jl to generate the Julia wrappers
Browse files Browse the repository at this point in the history
  • Loading branch information
amontoison committed Apr 21, 2024
1 parent d78db22 commit b447608
Show file tree
Hide file tree
Showing 8 changed files with 852 additions and 157 deletions.
7 changes: 7 additions & 0 deletions gen/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[deps]
Clang = "40e3b903-d033-50b4-a0cc-940c62c95e31"
qr_mumps_jll = "e37b5aa0-c611-5f0f-83fb-aee446c0b77e"
JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899"

[compat]
julia = "1.6"
10 changes: 10 additions & 0 deletions gen/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Wrapping headers

This directory contains a script that can be used to automatically generate wrappers from C headers provided by qr_mumps.
This is done using Clang.jl.

# Usage

Either run `julia wrapper.jl` directly, or include it and call the `main()` function.
Be sure to activate the project environment in this folder (`julia --project`), which will install `Clang.jl` and `JuliaFormatter.jl`.
The `main` function supports the boolean keyword argument `optimized` to clear the generated wrappers.
12 changes: 12 additions & 0 deletions gen/qrmumps.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[general]
use_julia_native_enum_type = true
print_using_CEnum = false
library_names = {"sqrm_c.h" = "libsqrm", "dqrm_c.h" = "libdqrm", "cqrm_c.h" = "libcqrm", "zqrm_c.h" = "libzqrm", "qrm_common_c.h" = "libqrm_common"}

[codegen]
use_julia_bool = true
always_NUL_terminated_string = true
use_ccall_macro = true

[codegen.macro]
macro_mode = "disable"
54 changes: 54 additions & 0 deletions gen/wrapper.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Script to parse qr_mumps headers and generate Julia wrappers.
using qr_mumps_jll
using Clang
using Clang.Generators
using JuliaFormatter

function main()

cd(@__DIR__)
include_dir = joinpath(qr_mumps_jll.artifact_dir, "include")
headers = map(header -> joinpath(include_dir, header), ["sqrm_c.h", "dqrm_c.h", "cqrm_c.h", "zqrm_c.h", "qrm_common_c.h"])

options = load_options(joinpath(@__DIR__, "qrmumps.toml"))
options["general"]["output_file_path"] = joinpath("..", "src", "wrapper", "libqrmumps.jl")
options["general"]["output_ignorelist"] = ["[sdcz]qrm_spmat_type_c", "[sdcz]qrm_spfct_type_c", "icntl", "rcntl", "ords", "gstats", "yn"]

args = get_default_args()
push!(args, "-I$include_dir")

ctx = create_context(headers, args, options)
build!(ctx)

path = options["general"]["output_file_path"]

code = read(path, String)
for pattern in ("::", ",", ")")
qrm_spmat_c = "qrm_spmat_c" * pattern
spmat = "spmat" * pattern
code = replace(code, qrm_spmat_c => spmat)

qrm_spfct_c = "qrm_sptct_c" * pattern
spfct = "spfct" * pattern
code = replace(code, qrm_spfct_c => spfct)
end

for (version, type) in [("s", "Float32"), ("d", "Float64"), ("c", "ComplexF32"), ("z", "ComplexF64")]
type_spmat_c = "Ptr{" * version * "qrm_spmat_type_c}"
type_spmat_julia = "Ref{c_spmat{" * type * "}}"
code = replace(code, type_spmat_c => type_spmat_julia)

type_spfct_c = "Ptr{" * version * "qrm_spfct_type_c}"
type_spfct_julia = "Ref{c_spfct{" * type * "}}"
code = replace(code, type_spfct_c => type_spfct_julia)
end
write(path, code)

format_file(path, YASStyle())
return nothing
end

# If we want to use the file as a script with `julia wrapper.jl`
if abspath(PROGRAM_FILE) == @__FILE__
main()
end
1 change: 1 addition & 0 deletions src/QRMumps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ else
end

include("wrapper/qr_mumps_common.jl")
include("wrapper/libqrmumps.jl")
include("wrapper/qr_mumps_api.jl")

export qrm_spmat, qrm_spfct,
Expand Down
Loading

0 comments on commit b447608

Please sign in to comment.