Not-Nik / raylib-zig

Manually tweaked, auto-generated raylib bindings for zig. https://github.com/raysan5/raylib
MIT License
517 stars 102 forks source link

add raylib submodule @ 3.0.0 #4

Closed ghost closed 4 years ago

ghost commented 4 years ago

also add build helper lib.zig to handle compiling and linking against raylib's source code and using raylib-zig from a sub-directory of a project more easily. Modifies build.zig for examples to reflect lib.zig usage.

Tested cross compilation to x86_64-windows-gnu, and on alpine linux natively. Building natively on linux requires the user to pull in a bunch of X11 development packages; XLib, xinput, xinerama, etc.

checklist

Not-Nik commented 4 years ago

Very nice. Eliminating the need for a system raylib is definitely a good idea, however, I would at least give the user the option to use their system library instead of completely recompiling raylib. Additionally, GLFW on MacOS uses Cocoa instead of X11 (Xquartz). Thanks for your contribution ^^

ghost commented 4 years ago

however, I would at least give the user the option to use their system library instead of completely recompiling raylib.

Understood. I just wanted to buzz what I have so far by you to see if you were interested in lib.zig concept, and building raylib. I would definitely like to flesh it out a little better before you consider merging, I will add a checklist to the original comment.

Not-Nik commented 4 years ago

Making this a draft for now. Keep up your work, looking great so far :)

Not-Nik commented 4 years ago

Ok, I tried building your fork on my system (MacOS 10.15) and not linking with the system library works like a charm, but building it results in the following error:

In file included from /Volumes/nikolas/dev/extern/raylib-zig/raylib/src/core.c:136:
/Volumes/nikolas/dev/extern/raylib-zig/raylib/src/rlgl.h:652:18: fatal error: 'OpenGL/gl3.h' file not found
        #include <OpenGL/gl3.h>         // OpenGL 3 library for OSX
                 ^~~~~~~~~~~~~~
1 error generated.

<Commands that failed here>

The same thing happens when forcing OpenGL version 1.1, just that the missing header is <OpenGL/gl.h>. Since these includes work when using make with

find_package(OpenGL REQUIRED)
target_link_libraries(target ${OPENGL_LIBRARIES})

so I reckon it is an issue with zig's build system.

P.S.: I love lib.zig. Is it a standard for a planned Zig package manager or did you come up with that?

ghost commented 4 years ago

Yeah talking to some people on discord about it, apparently the system's frameork directory is not added by default even when building natively with macosx, and I have no machine to tests some specific work around on.

This would be implemented in terms of exe.addFrameworkDir() in the macosx switch on exe.target.toTarget().os.tag in Pkg.link taking into account some element of the OS version range in exe.target. The system's default framework directory path seems to include version specific path elements, so we cannot just bake in a path. Something like:

// lib.zig

            switch (exe.target.toTarget().os.tag) {
                .windows => {
                    exe.linkSystemLibrary("winmm");
                    exe.linkSystemLibrary("gdi32");
                    exe.linkSystemLibrary("opengl32");
                },
                .macosx => {
                    exe.addFrameworkDir("/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/" ++ something target specific here ++".sdk/System/Library/Frameworks/
                    exe.linkFramework("OpenGL");
                    exe.linkFramework("Cocoa");

I have the 'allow edits by maintainers' box checked for this PR, so If you can figure it out you should be able to push to the raylib-submodule branch on my fork. I will see if I can figure something more specific out in the mean time on my end.

P.S.: I love lib.zig. Is it a standard for a planned Zig package manager or did you come up with that?

The initial idea i came up with independently, but apparently a few other people have come to a similar conclusion about how to get package specific stuff into a dependent project's build.zig.

So what is here now has taken some inspiration from https://github.com/MasterQ32/zig-bearssl/blob/master/bearssl.zig. It really isn't a good long-term solution because it requires that the package to be in a sub-directory of the dependent package at the moment.

Zig doesn't let you import source files outside of the top level of the package (to include implied packages, like the one used for compiling build.zig) which usually isn't a problem, but in our case we are depending on lib.zig in our build.zig. This imposes the requirement that lib.zig be within the build directory of a dependent project.

So, lib.zig existing within the raylib-zig package directory conflicts with a more general purpose dependency management strategy. However, in the case of something like raylib where it only really makes sense to depend on the package at the top-level of a project, and not in sub-packages, its not a problem in practice.

But this means that how it's working here probably will not make it into any sort of standard package management. It only makes sense for specific sorts of packages.

Not-Nik commented 4 years ago

As far as I'm concerned this code should store the proper framework path in frameworkPath regardless of whether Xcode or only the Command Line Tools are installed:

var buffer: [100]u8 = undefined;

var frameworkDir: []u8 = std.fmt.bufPrint(buffer[0..], "/Library/Developer/CommandLineTools/SDKs/MACOSX{}.{}.sdk/System/Library/Frameworks", .{
    exe.target.toTarget().os.version_range.semver.max.major,
    exe.target.toTarget().os.version_range.semver.max.minor,
}) catch unreachable;

We do have one remaining problem though: GLFW for macOS uses Objective-C and judging by the errors Zig outputs, telling me that it doesn't know some built-in Obj-C types like NSString or NSDictionary, it can't handle the language. If you're ok with it I'd just say we call it a day and output a message that raylib compilation using Zig is not supported on macOS. System library should be able to link with a local file (?) so no special search paths would be required for anyone setting up their own compiled raylib.

ghost commented 4 years ago

Well the default right now is building raylib's vendored version of GLFW, and looking at it's source code, it does include Obj-C modules for joystick support. Opting to to use the system version of glfw on macos will likely fix this. This is/was a desirable default for the windows-gnu target because it makes cross compilation very easy.

I will disable this on macos, and include the above code for finding the system framework directory and see where we get.

Not-Nik commented 4 years ago

Commit above just puts less bloat into the terminal in case it does work sometime. The command is now officially segmentation faulting (terminated by signal SIGSEGV (Address boundary error)) and I don't think there is much we can do about it. In case you do want to try out new changes you can use Vagrant to set up a macOS virtual machine easily.

Not-Nik commented 4 years ago

Also let me know if I should just add a notice raylib compilation doesn't work on macOS and merge

ghost commented 4 years ago

the segfault is likely the size of the buffer being used to print the framework path, but since I really cannot test any of the macosx stuff myself it's probably just better that we stub it out for now and merge. I'll handle that in lib.zig, squash out some of this commit noise, and leave any sort of readme edits to you if you want documentation of the feature to be a part of this PR.

ghost commented 4 years ago

OK, this seems to be 'good enough'. Future work in lib.zig should probably include

Not-Nik commented 4 years ago

Something I'll change immediately after merging, correct me if I'm wrong: raylib system linking works without linking the other libraries since raylib is already linked to them, so we can move the part where we check for system raylib to the top of the function

ghost commented 4 years ago

I don't know, this is probably just a demonstration of my gaps in understanding about dynamic linking. I think sometimes the symbols of a dynamic libraries' dependencies are left ultimately to the executable to satisfy, since different linking strategies and versions can be used to do this. For instance libc; maybe its satisfied by musl lib c, maybe glibc... and maybe its satisfied by a dynamic library or a static library.

I think we have to figure this out on a case-by-case basis for dynamic raylib's dependencies.