# Wrapping VapourSynth with Clang

**URL:** <https://discourse.julialang.org/t/wrapping-vapoursynth-with-clang/14966>\
**Category:** New to Julia\
**Created:** [September 14, 2018, 4:34pm UTC](https://discourse.julialang.org/t/wrapping-vapoursynth-with-clang/14966 "2018-09-14T16:34:18Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![josemaria](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josemaria/32/5365_2.png) [@josemaria](https://discourse.julialang.org/u/josemaria)\
**Post date:** [September 14, 2018, 4:34pm UTC](https://discourse.julialang.org/t/wrapping-vapoursynth-with-clang/14966/1 "2018-09-14T16:34:18Z")

</div>

I am a newbie in Julia, VapourSynth, wrapping C libraries, … so what could go wrong? After this disclaimer:

As the title says, I am trying to wrap [VapourSynth.h](https://github.com/vapoursynth/vapoursynth/blob/master/include/VapourSynth.h) using [Clang.jl](https://github.com/ihnorton/Clang.jl). I am looking for inspiration in [SunDials](https://github.com/JuliaDiffEq/Sundials.jl/blob/master/src/wrap_sundials.jl) and the [examples](https://github.com/ihnorton/Clang.jl/blob/master/examples/generators/wrap_PETSc.jl).

So far, so good. After running the script, I get the error:

```julia
...
└ @ Clang.wrap_c ~/.julia/packages/Clang/FPdiV/src/wrap_c.jl:651
┌ Warning: Not wrapping Clang.cindex.InclusionDirective bits/types.h
└ @ Clang.wrap_c ~/.julia/packages/Clang/FPdiV/src/wrap_c.jl:651
┌ Warning: Not wrapping Clang.cindex.InclusionDirective bits/stdint-uintn.h
└ @ Clang.wrap_c ~/.julia/packages/Clang/FPdiV/src/wrap_c.jl:651
┌ Warning: Not wrapping Clang.cindex.InclusionDirective bits/types.h
└ @ Clang.wrap_c ~/.julia/packages/Clang/FPdiV/src/wrap_c.jl:651
[ Info: Error thrown. Last cursor available in Clang.wrap_c.debug_cursors
ERROR: LoadError: MethodError: no method matching replace(::String, ::String, ::String)
Closest candidates are:
  replace(::String, !Matched::Pair{#s55,B} where B where #s55<:AbstractChar; count) at strings/util.jl:414
  replace(::String, !Matched::Pair{#s52,B} where B where #s52<:Union{Tuple{Vararg{AbstractChar,N} where N}, Set{#s49} where #s49<:AbstractChar, AbstractArray{#s50,1} where #s50<:AbstractChar}; count) at strings/util.jl:419
  replace(::String, !Matched::Pair; count) at strings/util.jl:423
  ...
Stacktrace:
 [1] wrap(::WrapContext, ::DataStructures.OrderedDict{Symbol,Clang.wrap_c.ExprUnit}, ::Clang.cindex.MacroDefinition) at /home/jose/.julia/packages/Clang/FPdiV/src/wrap_c.jl:617
 [2] wrap_header(::WrapContext, ::Clang.cindex.TranslationUnit, ::String, ::Array{Any,1}) at /home/jose/.julia/packages/Clang/FPdiV/src/wrap_c.jl:690
 [3] run(::WrapContext) at /home/jose/.julia/packages/Clang/FPdiV/src/wrap_c.jl:807
 [4] top-level scope at none:0
in expression starting at /home/jose/src/julia/vapoursynth/wrap_vapoursynth.jl:61

```

The script so far looks like this:

```julia
#using Clang.cindex
using Clang.wrap_c

#topcu = cindex.parse_header("./vapoursynth/include/VapourSynth.h")
#data = children(topcu)

#=context = wrap_c.init(; output_file="vapoursynth.jl"
                      , header_library=x->"<packagename>"
                      , common_file="vapoursynth_h.jl"
                      , clang_diagnostics=true )
=#
#wrap_c.wrap_c_headers(context, ["./vapoursynth/include/cython/vapoursynth.h"])

#const outpath = normpath(joinpath(dirname(@ __FILE__ ), "..", "new"))
const outpath = normpath(joinpath(dirname(@ __FILE__ ), "new"))
mkpath(outpath)
#print(outpath)
#header = "./vapoursynth/include/VapourSynth.h"

# Clang Location
const clang_path = "/usr/lib/clang/6.0.1/" # change to your clang location
const clang_includes = [
    joinpath(clang_path, "include"),
]

#const incpath = "./vapoursynth/include"
const incpath = normpath(joinpath(dirname(@ __FILE__ ), "vapoursynth", "include"))

function julia_file(header::AbstractString)
    src_name = basename(dirname(header))
    if src_name == "sundials"
        src_name = "libsundials" # avoid having both Sundials.jl and sundials.jl
    end
    return joinpath(outpath, string(src_name, ".jl"))
end
function library_file(header::AbstractString)
    header_name = basename(header)
    #if startswith(header_name, "nvector")
    # return "libsundials_nvecserial"
    #else
    return "libvapoursynth"#string("libvapoursynth_", basename(dirname(header)))
    #end
end

const contxt = wrap_c.init(
    common_file = joinpath(outpath, "types_and_consts.jl"),
    #=clang_args = [
        "-D", "__STDC_LIMIT_MACROS",
        "-D", "__STDC_CONSTANT_MACROS",
        "-v"
    ],=#
    clang_diagnostics = true,
    clang_includes = [clang_includes; incpath],
    header_outputfile = julia_file,
    header_library = library_file,
    #header_wrapped=wrap_header,
    #cursor_wrapped=wrap_cursor
)
#contxt.headers = ["./vapoursynth/include/VSHelper.h"] 
contxt.headers = ["./vapoursynth/include/VapourSynth.h"]
run(contxt)

```

Any suggestion?

Thanks for your help.

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [September 14, 2018, 5:10pm UTC](https://discourse.julialang.org/t/wrapping-vapoursynth-with-clang/14966/3 "2018-09-14T17:10:42Z")

</div>

PR submitted: [Another upgrading oversight -- replace by Gnimuc · Pull Request #201 · JuliaInterop/Clang.jl · GitHub](https://github.com/ihnorton/Clang.jl/pull/201)

Please feel free to file an issue if you encounter any other problems.
