Skip to content
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

Generate Julia wrappers with Clang.jl #332

Merged
merged 3 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ deps/*
docs/build
docs/site
dos/Manifest.toml
amontoison marked this conversation as resolved.
Show resolved Hide resolved

gen/Manifest.toml

8 changes: 8 additions & 0 deletions gen/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[deps]
Clang = "40e3b903-d033-50b4-a0cc-940c62c95e31"
CUTEst_jll = "bb5f6f25-f23d-57fd-8f90-3ef7bad1d825"
JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899"

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

This directory contains a script that can be used to automatically generate wrappers from C headers provided by CUTEst.
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`.
12 changes: 12 additions & 0 deletions gen/cutest.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_name = "cutest_lib_path"

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

[codegen.macro]
macro_mode = "disable"
44 changes: 44 additions & 0 deletions gen/wrapper.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Script to parse qr_mumps headers and generate Julia wrappers.
amontoison marked this conversation as resolved.
Show resolved Hide resolved
using CUTEst_jll
using Clang
using Clang.Generators
using JuliaFormatter

function main()

cd(@__DIR__)
include_dir = joinpath(CUTEst_jll.artifact_dir, "include")
headers = map(header -> joinpath(include_dir, header), ["cutest.h"])

options = load_options(joinpath(@__DIR__, "cutest.toml"))
options["general"]["output_file_path"] = joinpath("..", "src", "libcutest.jl")
options["general"]["output_ignorelist"] = ["integer", "real", "doublereal", "logical", "rp_", "rpc_", "ip_", "ipc_"]

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)
code = replace(code, "Ptr{integer}" => "Ptr{Cint}")
code = replace(code, "Ptr{doublereal}" => "Ptr{Float64}")
code = replace(code, "Ptr{real}" => "Ptr{Float32}")
code = replace(code, "Ptr{doubleCfloat}" => "Ptr{Float64}")
code = replace(code, "Ptr{logical}" => "Ptr{Bool}")
code = replace(code, "Ptr{rp_}" => "Ptr{Float64}")
code = replace(code, "Ptr{rpc_}" => "Ptr{Float64}")
code = replace(code, "Ptr{ip_}" => "Ptr{Cint}")
code = replace(code, "Ptr{ipc_}" => "Ptr{Cint}")
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
11 changes: 7 additions & 4 deletions src/CUTEst.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ using Libdl
using NLPModels
import Libdl.dlsym

global cutest_lib_path = ""
global cutest_lib = C_NULL
include("libcutest.jl")

# Only one problem can be interfaced at any given time.
global cutest_instances = 0

Expand Down Expand Up @@ -64,7 +68,6 @@ end

const cutest_problems_path = joinpath(dirname(@__FILE__), "..", "deps", "files")
isdir(cutest_problems_path) || mkpath(cutest_problems_path)
global cutest_lib = C_NULL

function __init__()
if success(`bash -c "type gfortran"`)
Expand Down Expand Up @@ -215,8 +218,8 @@ function sifdecoder(
end
run(`mv OUTSDIF.d $outsdif`)
delete_temp_files(suffix)
global cutest_lib =
Libdl.dlopen(libname, Libdl.RTLD_NOW | Libdl.RTLD_DEEPBIND | Libdl.RTLD_GLOBAL)
global cutest_lib = Libdl.dlopen(libname, Libdl.RTLD_NOW | Libdl.RTLD_DEEPBIND | Libdl.RTLD_GLOBAL)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be modified again by the formatter, no?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but I modified the name of the variable before that I reverted it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The auto formater will probably fix other things.

global cutest_lib_path = joinpath(cutest_problems_path, "$libname.$(Libdl.dlext)")
end
end
rm(outlog)
Expand Down Expand Up @@ -298,7 +301,7 @@ function CUTEstModel(
dlsym(cutest_lib, :fortran_open_),
Nothing,
(Ref{Int32}, Ptr{UInt8}, Ptr{Int32}),
funit,
[funit],
outsdif,
io_err,
)
Expand Down
Loading
Loading