Skip to content

Commit a65a152

Browse files
committed
cleanup wrapper generator
* add comments and status messages * don't cd() to the directory where the headers are generated * don't require JULIAHOME env variable
1 parent b277395 commit a65a152

File tree

1 file changed

+52
-50
lines changed

1 file changed

+52
-50
lines changed

src/wrap_sundials.jl

Lines changed: 52 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,50 @@
1-
# This file is not an active part of the package. This is the code
2-
# that uses the Clang.jl package to wrap Sundials using the headers.
1+
# This script is not an active part of the package.
2+
# It uses Clang.jl package to parse Sundials C headers and generate
3+
# Julia wrapper for Sundials API.
4+
#
5+
# To run the script from Julia console:
6+
# include(joinpath(Pkg.dir("Sundials"), "src", "wrap_sundials.jl"));
37

4-
# Find all headers
5-
incpath = normpath(joinpath(dirname(@__FILE__), "..", "deps", "usr", "include"))
6-
if !isdir(incpath)
7-
error("Run Pkg.build(\"Sundials\") before trying to wrap C headers.")
8-
end
8+
using Clang.wrap_c
99

10-
wdir = joinpath(dirname(@__FILE__), "..", "new")
11-
mkpath(wdir)
12-
cd(wdir)
10+
# `outpath` specifies, where the julian wrappers would be generated.
11+
# If the generated .jl files are ok, they have to be copied to the "src" folder
12+
# overwriting the old ones
13+
const outpath = normpath(joinpath(dirname(@__FILE__), "..", "new"))
14+
mkpath(outpath)
1315

14-
sundials_names = ["nvector", "sundials", "cvode", "cvodes", "ida", "idas", "kinsol"]
15-
if isdir(joinpath(incpath, "arkode"))
16-
push!(sundials_names, "arkode")
17-
end
18-
headers = ASCIIString[]
19-
for name in sundials_names
20-
path = joinpath(incpath, name)
21-
append!(headers, map(x->joinpath(path, x),
22-
sort!(convert(Vector{ASCIIString}, readdir(path)))))
16+
# Find all relevant Sundials headers
17+
const incpath = normpath(joinpath(dirname(@__FILE__), "..", "deps", "usr", "include"))
18+
if !isdir(incpath)
19+
error("Sundials C headers not found. Run Pkg.build(\"Sundials\") before trying to wrap C headers.")
2320
end
24-
# @show headers
2521

26-
27-
## Do wrapping using Clang.jl
28-
ENV["JULIAHOME"] = "/Users/jgoldfar/Public/julia/usr/"
29-
30-
using Clang.wrap_c
31-
32-
if (!haskey(ENV, "JULIAHOME"))
33-
error("Please set JULIAHOME variable to the root of your julia install")
22+
info("Scanning Sundials headers in $incpath...")
23+
const sundials_folders = filter!(isdir, map!(folder -> joinpath(incpath, folder),
24+
["nvector", "sundials", "cvode", "cvodes",
25+
"ida", "idas", "kinsol", "arkode"]))
26+
const sundials_headers = similar(sundials_folders, 0)
27+
for folder in sundials_folders
28+
info("Processing $folder...")
29+
append!(sundials_headers,
30+
map(x->joinpath(folder, x),
31+
sort!(convert(typeof(sundials_headers), readdir(folder)))))
3432
end
33+
# @show sundials_headers
3534

36-
clang_includes = map(x->joinpath(ENV["JULIAHOME"], x), [
37-
"deps/llvm-3.2/build/Release/lib/clang/3.2/include",
38-
"deps/llvm-3.2/include",
39-
"deps/llvm-3.2/include",
40-
"deps/llvm-3.2/build/include/",
41-
"deps/llvm-3.2/include/"
42-
])
35+
const clang_path = "/usr/lib/clang/3.8.0" # change to your clang location
36+
const clang_includes = [
37+
joinpath(clang_path, "include"),
38+
]
4339

4440
# check_use_header(path) = true
4541
# Callback to test if a header should actually be wrapped (for exclusion)
46-
function wrap_header(top_hdr::ASCIIString, cursor_header::ASCIIString)
42+
function wrap_header(top_hdr::AbstractString, cursor_header::AbstractString)
4743
!ismatch(r"(_parallel|_impl)\.h$", cursor_header) && # don't wrap parallel and implementation definitions
4844
(top_hdr == cursor_header) # don't wrap if header is included from the other header (e.g. nvector in cvode or cvode_direct from cvode_band)
4945
end
5046

51-
function wrap_cursor(name::ASCIIString, cursor)
47+
function wrap_cursor(name::AbstractString, cursor)
5248
if typeof(cursor) == Clang.cindex.FunctionDecl
5349
# only wrap API functions
5450
return ismatch(r"^(CV|KIN|IDA|N_V)", name)
@@ -63,7 +59,7 @@ function julia_file(header::AbstractString)
6359
if src_name == "sundials"
6460
src_name = "libsundials" # avoid having both Sundials.jl and sundials.jl
6561
end
66-
return string(src_name, ".jl")
62+
return joinpath(outpath, string(src_name, ".jl"))
6763
end
6864
function library_file(header::AbstractString)
6965
header_name = basename(header)
@@ -74,18 +70,21 @@ function library_file(header::AbstractString)
7470
end
7571
end
7672

77-
clang_extraargs = [
78-
"-D", "__STDC_LIMIT_MACROS", "-D", "__STDC_CONSTANT_MACROS",
79-
"-v"]
80-
context = wrap_c.init(
81-
common_file="types_and_consts.jl",
82-
clang_args = clang_extraargs, clang_diagnostics = true,
83-
clang_includes = [clang_includes; incpath],
84-
header_outputfile = julia_file,
85-
header_library = library_file,
86-
header_wrapped=wrap_header,
87-
cursor_wrapped=wrap_cursor)
88-
context.headers = headers
73+
const context = wrap_c.init(
74+
common_file="types_and_consts.jl",
75+
clang_args = [
76+
"-D", "__STDC_LIMIT_MACROS",
77+
"-D", "__STDC_CONSTANT_MACROS",
78+
"-v"
79+
],
80+
clang_diagnostics = true,
81+
clang_includes = [clang_includes; incpath],
82+
header_outputfile = julia_file,
83+
header_library = library_file,
84+
header_wrapped=wrap_header,
85+
cursor_wrapped=wrap_cursor
86+
)
87+
context.headers = sundials_headers
8988

9089
# 1st arg name to wrapped arg type map
9190
const arg1_name2type = Dict(
@@ -97,6 +96,7 @@ const arg1_name2type = Dict(
9796
:idaadj_mem => :(IDAMemPtr), # Sundials typo?
9897
)
9998

99+
# substitute Ptr{Void} with the typed pointer
100100
const ctor_return_type = Dict(
101101
"CVodeCreate" => :(CVODEMemPtr),
102102
"IDACreate" => :(IDAMemPtr),
@@ -246,4 +246,6 @@ context.rewriter = function(exprs)
246246
mod_exprs
247247
end
248248

249+
info("Generating .jl wrappers for Sundials in $outpath...")
249250
run(context)
251+
info("Done generating .jl wrappers for Sundials in $outpath")

0 commit comments

Comments
 (0)