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"));
3
7
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
9
9
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)
13
15
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." )
23
20
end
24
- # @show headers
25
21
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)))))
34
32
end
33
+ # @show sundials_headers
35
34
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
+ ]
43
39
44
40
# check_use_header(path) = true
45
41
# 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 )
47
43
! ismatch (r" (_parallel|_impl)\. h$" , cursor_header) && # don't wrap parallel and implementation definitions
48
44
(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)
49
45
end
50
46
51
- function wrap_cursor (name:: ASCIIString , cursor)
47
+ function wrap_cursor (name:: AbstractString , cursor)
52
48
if typeof (cursor) == Clang. cindex. FunctionDecl
53
49
# only wrap API functions
54
50
return ismatch (r" ^(CV|KIN|IDA|N_V)" , name)
@@ -63,7 +59,7 @@ function julia_file(header::AbstractString)
63
59
if src_name == " sundials"
64
60
src_name = " libsundials" # avoid having both Sundials.jl and sundials.jl
65
61
end
66
- return string (src_name, " .jl" )
62
+ return joinpath (outpath, string (src_name, " .jl" ) )
67
63
end
68
64
function library_file (header:: AbstractString )
69
65
header_name = basename (header)
@@ -74,18 +70,21 @@ function library_file(header::AbstractString)
74
70
end
75
71
end
76
72
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
89
88
90
89
# 1st arg name to wrapped arg type map
91
90
const arg1_name2type = Dict (
@@ -97,6 +96,7 @@ const arg1_name2type = Dict(
97
96
:idaadj_mem => :(IDAMemPtr), # Sundials typo?
98
97
)
99
98
99
+ # substitute Ptr{Void} with the typed pointer
100
100
const ctor_return_type = Dict (
101
101
" CVodeCreate" => :(CVODEMemPtr),
102
102
" IDACreate" => :(IDAMemPtr),
@@ -246,4 +246,6 @@ context.rewriter = function(exprs)
246
246
mod_exprs
247
247
end
248
248
249
+ info (" Generating .jl wrappers for Sundials in $outpath ..." )
249
250
run (context)
251
+ info (" Done generating .jl wrappers for Sundials in $outpath " )
0 commit comments