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

Odin lang raylib is broken #348498

Open
oworope opened this issue Oct 14, 2024 · 9 comments
Open

Odin lang raylib is broken #348498

oworope opened this issue Oct 14, 2024 · 9 comments
Labels
0.kind: bug Something is broken

Comments

@oworope
Copy link

oworope commented Oct 14, 2024

Describe the bug

It's not possible to run raylib app on wayland (and probably on X too)

$ odin run .
INFO: Initializing raylib 5.0
INFO: Platform backend: DESKTOP (GLFW)
INFO: Supported raylib modules:
INFO:     > rcore:..... loaded (mandatory)
INFO:     > rlgl:...... loaded (mandatory)
INFO:     > rshapes:... loaded (optional)
INFO:     > rtextures:. loaded (optional)
INFO:     > rtext:..... loaded (optional)
INFO:     > rmodels:... loaded (optional)
INFO:     > raudio:.... loaded (optional)
WARNING: GLFW: Error: 65544 Description: X11: Failed to load Xlib
WARNING: GLFW: Failed to initialize GLFW
Segmentation fault (core dumped)

Steps To Reproduce

Steps to reproduce the behavior:

  1. Run any wayland session
  2. Create a main.odin file that uses raylib
package main

import "core:fmt"
import rl "vendor:raylib"

main :: proc() {
	rl.InitWindow(800, 600, "Raylib")
	for !rl.WindowShouldClose() {
		// nop
	}
}
  1. odin run .

Expected behavior

A window should open (or at least there should be no errors)

Additional context

I assume that /share/vendor libraries should be patched

Notify maintainers

@luc65r @Astavie @znaniye

Metadata

$ nix-shell -p nix-info --run "nix-info -m"
 - system: `"x86_64-linux"`
 - host os: `Linux 6.6.54, NixOS, 24.11 (Vicuna), 24.11.20241009.5633bcf`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.18.8`
 - channels(root): `"nixos-24.05"`
 - nixpkgs: `/nix/store/60sn02zhawl3kwn0r515zff3h6hg6ydz-source

Add a 👍 reaction to issues you find important.

@oworope oworope added the 0.kind: bug Something is broken label Oct 14, 2024
@oworope
Copy link
Author

oworope commented Oct 14, 2024

@KaiserCalm
Copy link

Can confirm aswell that on a Wayland only DE (COSMIC), raylib errors out with the exact same error.

@themaxhero
Copy link
Contributor

Can confirm aswell that on a Wayland only DE (COSMIC), raylib errors out with the exact same error.

I have the same problem, and I'm running i3.

@themaxhero
Copy link
Contributor

Not a fix, but maybe might help in the diagnostics.
If I run with steam-run it works.

@oworope
Copy link
Author

oworope commented Dec 28, 2024

I think the problem is that Odin uses built-in libraries for vendor libs, and they probably use glfw from /usr/lib or /lib or whatever, not /nix/store

@ShadowSeick
Copy link

I think the problem is that Odin uses built-in libraries for vendor libs, and they probably use glfw from /usr/lib or /lib or whatever, not /nix/store

It seems that you are totally correct @oworope . I have managed to make it work by exporting the library paths it needs to search it
export LD_LIBRARY_PATH=${pkgs.xorg.libX11}/lib:${pkgs.xorg.libXrandr}/lib:${pkgs.xorg.libXinerama}/lib:${pkgs.xorg.libXcursor}/lib:${pkgs.xorg.libXi}/lib:${pkgs.raylib}/lib:${pkgs.mesa}/lib:${pkgs.libglvnd}/lib:$LD_LIBRARY_PATH

In my case I use it as a whole nix env shell

pkgs.mkShell
        {
          nativeBuildInputs = with pkgs; [
            gcc
            odin
            raylib
            glfw
            xorg.libX11
            xorg.libXrandr
            xorg.libXinerama
            xorg.libXcursor
            xorg.libXi
            xorg.xeyes
            mesa
            libglvnd
          ];

          shellHook = ''
            export LD_LIBRARY_PATH=${pkgs.xorg.libX11}/lib:${pkgs.xorg.libXrandr}/lib:${pkgs.xorg.libXinerama}/lib:${pkgs.xorg.libXcursor}/lib:${pkgs.xorg.libXi}/lib:${pkgs.raylib}/lib:${pkgs.mesa}/lib:${pkgs.libglvnd}/lib:$LD_LIBRARY_PATH
            export LIBGL_ALWAYS_SOFTWARE=1
            export DISPLAY=:0
            export XDG_SESSION_TYPE=x11
            export GDK_BACKEND=wayland
            export SDL_VIDEODRIVER=wayland
            echo "Odin environment running"
          '';
        };

@diniamo
Copy link
Contributor

diniamo commented Jan 1, 2025

Here is a more proper solution for those that care. This works by patching Odin to use an externally provided Raylib version. Note that this specific derivation only copies the vendored Raylib over, to use other libraries, you would need to patch and copy those as well. Another quirk is that the Odin bindings have been updated to Raylib 5.5, whereas #357729 still isn't merged, so the example uses my nixpkgs branch.

flake.nix
{
  inputs = {
    nixpkgs.url = "github:diniamo/nixpkgs/update-raylib";
  };

  outputs = {nixpkgs, ...}: let
    system = "x86_64-linux";
    pkgs = nixpkgs.legacyPackages.${system};

    # raylib = pkgs.raylib.override { platform = "SDL"; };
    odin = pkgs.callPackage ./odin.nix {};
  in {
    devShells.${system}.default = pkgs.mkShell {
      packages = [odin pkgs.raylib];
    };
  };
}
odin.nix
{
  fetchFromGitHub,
  lib,
  llvmPackages,
  makeBinaryWrapper,
  which,
}: let
  inherit (llvmPackages) stdenv;
in
  stdenv.mkDerivation {
    pname = "odin";
    version = "2024-12-06";

    src = fetchFromGitHub {
      owner = "odin-lang";
      repo = "Odin";
      rev = "dev-2024-12";
      hash = "sha256-BkPdVzgbEc3S4eSi5TbFKPzkRGkaJTILN/g9o8hfdEw=";
    };

    patches = [./odin-system-raylib.patch];

    dontConfigure = true;
    LLVM_CONFIG = "${llvmPackages.llvm.dev}/bin/llvm-config";

    buildFlags = ["release"];

    nativeBuildInputs = [
      makeBinaryWrapper
      which
    ];

    postPatch = ''
      patchShebangs build_odin.sh
    '';

    installPhase = ''
      runHook preInstall

      mkdir -p $out/bin
      cp odin $out/bin/odin

      mkdir -p $out/share
      cp -r {base,core,shared} $out/share

      mkdir -p $out/share/vendor/raylib
      cp -r vendor/raylib/{rlgl,*.odin} $out/share/vendor/raylib

      # make -C "$out/share/vendor/cgltf/src/"
      # make -C "$out/share/vendor/stb/src/"
      # make -C "$out/share/vendor/miniaudio/src/"

      wrapProgram $out/bin/odin \
        --set-default ODIN_ROOT $out/share \
        --prefix PATH : ${
        lib.makeBinPath (
          with llvmPackages; [
            bintools
            llvm
            clang
            lld
          ]
        )
      }

      runHook postInstall
    '';
  }
odin-system-raylib.patch
diff --git a/vendor/raylib/raygui.odin b/vendor/raylib/raygui.odin
index a15467ae8..89c1483a0 100644
--- a/vendor/raylib/raygui.odin
+++ b/vendor/raylib/raygui.odin
@@ -2,28 +2,8 @@ package raylib
 
 import "core:c"
 
-RAYGUI_SHARED :: #config(RAYGUI_SHARED, false)
-
-when ODIN_OS == .Windows {
-	foreign import lib {
-		"windows/rayguidll.lib" when RAYGUI_SHARED else "windows/raygui.lib",
-	}
-} else when ODIN_OS == .Linux  {
-	foreign import lib {
-		"linux/libraygui.so" when RAYGUI_SHARED else "linux/libraygui.a",
-	}
-} else when ODIN_OS == .Darwin {
-	when ODIN_ARCH == .arm64 {
-		foreign import lib {
-			"macos-arm64/libraygui.dylib" when RAYGUI_SHARED else "macos-arm64/libraygui.a",
-		}
-	} else {
-		foreign import lib {
-			"macos/libraygui.dylib" when RAYGUI_SHARED else "macos/libraygui.a",
-		}
-	}
-} else {
-	foreign import lib "system:raygui"
+foreign import lib {
+	"system:raygui",
 }
 
 RAYGUI_VERSION :: "4.0"
diff --git a/vendor/raylib/raylib.odin b/vendor/raylib/raylib.odin
index a5be660c6..6d1f4d0d9 100644
--- a/vendor/raylib/raylib.odin
+++ b/vendor/raylib/raylib.odin
@@ -99,36 +99,10 @@ MAX_TEXT_BUFFER_LENGTH :: #config(RAYLIB_MAX_TEXT_BUFFER_LENGTH, 1024)
 
 #assert(size_of(rune) == size_of(c.int))
 
-RAYLIB_SHARED :: #config(RAYLIB_SHARED, false)
-
-when ODIN_OS == .Windows {
-	@(extra_linker_flags="/NODEFAULTLIB:" + ("msvcrt" when RAYLIB_SHARED else "libcmt"))
-	foreign import lib {
-		"windows/raylibdll.lib" when RAYLIB_SHARED else "windows/raylib.lib" ,
-		"system:Winmm.lib",
-		"system:Gdi32.lib",
-		"system:User32.lib",
-		"system:Shell32.lib",
-	}
-} else when ODIN_OS == .Linux  {
-	foreign import lib {
-		// Note(bumbread): I'm not sure why in `linux/` folder there are
-		// multiple copies of raylib.so, but since these bindings are for
-		// particular version of the library, I better specify it. Ideally,
-		// though, it's best specified in terms of major (.so.4)
-		"linux/libraylib.so.550" when RAYLIB_SHARED else "linux/libraylib.a",
-		"system:dl",
-		"system:pthread",
-	}
-} else when ODIN_OS == .Darwin {
-	foreign import lib {
-		"macos/libraylib.550.dylib" when RAYLIB_SHARED else "macos/libraylib.a",
-		"system:Cocoa.framework",
-		"system:OpenGL.framework",
-		"system:IOKit.framework",
-	} 
-} else {
-	foreign import lib "system:raylib"
+foreign import lib {
+	"system:raylib",
+	"system:dl",
+	"system:pthread",
 }
 
 VERSION_MAJOR :: 5
diff --git a/vendor/raylib/rlgl/rlgl.odin b/vendor/raylib/rlgl/rlgl.odin
index 9d4682294..f39ea2035 100644
--- a/vendor/raylib/rlgl/rlgl.odin
+++ b/vendor/raylib/rlgl/rlgl.odin
@@ -112,43 +112,10 @@ import rl "../."
 
 VERSION :: "5.0"
 
-RAYLIB_SHARED :: #config(RAYLIB_SHARED, false)
-
-// Note: We pull in the full raylib library. If you want a truly stand-alone rlgl, then:
-// - Compile a separate rlgl library and use that in the foreign import blocks below.
-// - Remove the `import rl "../."` line
-// - Copy the code from raylib.odin for any types we alias from that package (see PixelFormat etc)
-
-when ODIN_OS == .Windows {
-	@(extra_linker_flags="/NODEFAULTLIB:" + ("msvcrt" when RAYLIB_SHARED else "libcmt"))
-	foreign import lib {
-		"../windows/raylibdll.lib" when RAYLIB_SHARED else "../windows/raylib.lib" ,
-		"system:Winmm.lib",
-		"system:Gdi32.lib",
-		"system:User32.lib",
-		"system:Shell32.lib",
-	}
-} else when ODIN_OS == .Linux  {
-	foreign import lib {
-		// Note(bumbread): I'm not sure why in `linux/` folder there are
-		// multiple copies of raylib.so, but since these bindings are for
-		// particular version of the library, I better specify it. Ideally,
-		// though, it's best specified in terms of major (.so.4)
-		"../linux/libraylib.so.500" when RAYLIB_SHARED else "../linux/libraylib.a",
-		"system:dl",
-		"system:pthread",
-	}
-} else when ODIN_OS == .Darwin {
-	foreign import lib {
-		"../macos" +
-			("-arm64" when ODIN_ARCH == .arm64 else "") +
-			"/libraylib" + (".500.dylib" when RAYLIB_SHARED else ".a"),
-		"system:Cocoa.framework",
-		"system:OpenGL.framework",
-		"system:IOKit.framework",
-	}
-} else {
-	foreign import lib "system:raylib"
+foreign import lib {
+	"system:raygui",
+	"system:dl",
+	"system:pthread",
 }
 
 GRAPHICS_API_OPENGL_11  :: false

@Vonixxx
Copy link
Contributor

Vonixxx commented Jan 6, 2025

This needs to be done in order to let Odin find all needed libraries. This is the flake i use with nix develop.

{
 inputs = {
   nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
 };

 outputs = {
   nixpkgs
 , ...
 }:

let
  inherit (pkgs)
   mkShell;

  inherit (pkgs.lib)
   makeLibraryPath;

  pkgs = import nixpkgs {
    system = "x86_64-linux";
  };
in {
   devShells.x86_64-linux.default = mkShell {
     buildInputs = with pkgs; [
       libGL
       xorg.libX11
     ];

     LD_LIBRARY_PATH = with pkgs; "$LD_LIBRARY_PATH:${
        makeLibraryPath [
         libGL
         xorg.libX11
        ]
     }";
   };
 };
}

For other issues relating to Odin and RayLib, see #338972.

@diniamo
Copy link
Contributor

diniamo commented Jan 6, 2025

That's actually not needed. Using mkShell and packages works just fine. And LD_LIBRARY_PATH doesn't even do anything, since that's for dynamic libraries, and Odin links statically. This can also be confirmed by using mkShellNoCC instead, in which case that won't work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0.kind: bug Something is broken
Projects
None yet
Development

No branches or pull requests

6 participants