Clang vs CBindingGen

,

Do you have any unfinished code you could upload?

I might want to take part in the Game Makers Toolkit game jam next month and if i don’t have to start from scratch that might motivate me to get something runable by then.

Not really anything beyond a basic proof of concept. I basically used Gnumic’s example:

wrap.toml

[general]
library_name = ":libraylib"
output_file_path = "./LibRaylib.jl"
module_name = "LibRaylib"
use_julia_native_enum_type = true

wrap.jl

using Clang.Generators

cd(@__DIR__)

const RAYLIB_H = ["/usr/local/include/raylib.h"]

options = load_options(joinpath(@__DIR__, "wrap.toml"))

args = String[]

ctx = create_context(RAYLIB_H, args, options)

build!(ctx)

Running wrap.jl produces LibRayLib.jl which is 99% fine, but needs a tiny bit of editing to account for issues with vararg functions and some macros (no idea if that has been fixed in the meantime). Then code like this works:

run_rl.jl



include("LibRaylib.jl")

const RL = LibRaylib

const screen_width = 1600
const screen_height = 900

function run()
	RL.InitWindow(screen_width, screen_height, "run")

	camera = RL.Camera2D(RL.Vector2(500, 500), 
		RL.Vector2(screen_width/2, screen_height/2),
		0.0,
		1.0)

	x = floor(Int, rand() * 1000) + 200
	y = floor(Int, rand() * 700) + 100

	while RL.WindowShouldClose() == 0
		RL.BeginDrawing()
		
		RL.BeginMode2D(camera)
		RL.ClearBackground(RL.Color(0, 0, 0, 255))

		x += floor(Int, (rand()-0.49)*10)
		y += floor(Int, (rand()-0.49)*10)

		RL.DrawText("Dies ist ein Test!", 200, 200, 20, RL.Color(250, 0, 0, 255))
		RL.DrawCircle(x, y, 100, RL.Color(0, 255, 0, 150))

		RL.EndMode2D()




		RL.EndDrawing()
	end

	RL.CloseWindow()
end


run()
1 Like

Hi, thank you for the thorough examples of using clang. However, I have an issue running the same code as the above.

The LibRaylib.jl is created successfully, but while running the run_rl.jl, I got this error ERROR: could not load library "libraylib".

Any tips to solve this issue?

It seems like you are trying to use a wrapper for a library, but without the library. Are you sure that libraylib is installed on your system?

Hi @serenity4, thank you for responding.

I have installed the raylib (following through this guide Working on GNU Linux · raysan5/raylib Wiki · GitHub), it still gave me the same error.

git clone https://github.com/raysan5/raylib.git raylib
cd raylib
mkdir build && cd build
cmake -DBUILD_SHARED_LIBS=ON ..
make
sudo make install

I am not sure why it doesn’t detect the installation. I am a new Linux user, so maybe I didn’t install it correctly.

You should then make sure that the libraries you built are discoverable within the library search path of your system. You can look into LD_LIBRARY_PATH for example.

Since Raylib is in Yggdrasil (see here), an even better solution would be to use the Julia package Raylib_jll. As long as the library name of the JLL package matches the library name you use in your wrapper, the issue might be solved by just doing import Raylib_jll (at package __init__() time, Raylib_jll will dlopen the shared library and therefore the library will be callable by name directly, i.e. no need to mess with system paths).

1 Like

Thanks, @serenity4!

I will figure out how to continue with this one. However, I tried with a different approach using the JLL package.

using Clang.Generators
using Raylib_jll

cd(@__DIR__)

include_dir = normpath(Raylib_jll.artifact_dir, "include")

# wrapper generator options
options = load_options(joinpath(@__DIR__, "wrap.toml"))

# add compiler flags, e.g. "-DXXXXXXXXX"
args = get_default_args()
push!(args, "-I$include_dir")

header_dir = include_dir
headers = [joinpath(header_dir, header) for header in readdir(header_dir) if endswith(header, ".h")]

# create context
ctx = create_context(headers, args, options)

# run generator
build!(ctx)
[general]
library_name = "libraylib"
output_file_path = "./LibRayLib.jl"
module_name = "LibRaylib"
jll_pkg_name = "Raylib_jll"

However, I got this error message

[ Info: Processing header: /home/vscode/.julia/artifacts/43bf856bd341c937a4ef62a0db273d61985df75e/include/rlgl.h
ERROR: AssertionError: duplicated definitions should be exactly the same!
Stacktrace:
 [1] (::IndexDefinition)(dag::ExprDAG, options::Dict{String, Any})
   @ Clang.Generators ~/.julia/packages/Clang/i9s1u/src/generator/passes.jl:127
 [2] build!(ctx::Context, stage::Clang.Generators.BuildStage)
   @ Clang.Generators ~/.julia/packages/Clang/i9s1u/src/generator/context.jl:169
 [3] build!(ctx::Context)
   @ Clang.Generators ~/.julia/packages/Clang/i9s1u/src/generator/context.jl:160
 [4] top-level scope
   @ /workspaces/Docker/Julia/Raylib/jll/wrap.jl:22

Do you have any idea why this is happening?

If you want to use raylib with Julia, someone already made a Julia wrapper for it:

chengchingwen/Raylib.jl: Julia wrapper for the raylib videogames programming library (github.com)

It works pretty well. See this example:

NanoVG.jl/raylib.jl at main · dylanxyz/NanoVG.jl (github.com)

2 Likes

Hi @dylanxyz, thank you for the response :slight_smile:

What I am trying to do here is to learn about using Clang.jl as a wrapper. Because I stumbled upon a problem when I was trying to make a wrapper for cuQuantum. There is already JLL for this: GitHub - JuliaBinaryWrappers/cuQuantum_jll.jl. But I think something is missing, which makes an error.

So, technically it should be easier for me to build it. But, as I am still new to Julia and cuQuantum, I want to see more examples of how Clang.jl can be used.

If you have any information that someone is already made the wrapper for this project, it would be awesome :slight_smile:

Fixed by Fix an oversight of #393 · JuliaInterop/Clang.jl@b5b2b58 · GitHub

1 Like