Making a raylib binding with Swift for a game engine; does SwiftPM support C linking?

Title says it all. So I already built Raylib on my machine with cmake and I just ideally want to take the headers from that repo and the dynamic libs .so (for my Linux machine, I expect for windows I will build for .dll?) My only major pain point has always been the PM. I find it kind of lackingly documented for using with C. Regardless, I have no idea what I am doing other then I just want to make a high level game engine with Swift and using that C base.

Otherwise, I have a pretty high level project next to it for my actual swift game and engine, but I wouldn't even know if implementing the Package.swift needs some higher magic with C headers/source...

Plus, I love swift, so I really, really want to make this work cross platform.
Sorry if that is open ended and alot, please be patient with me.

2 Likes

You could check out how the Raylib for Swift project does it!

1 Like

I am going to pretend this wasnt the obvious solution, so basically to go over this.

  • Swift supports Package.swift using conditional compilation with #if-platform(os) and end so I can just pick and choose the raylib files per platform? Does this work say, if I made my own Vulkan and I Would have to go "well you should work on Windows and Linux, but for Apple I Will have to turn that SPIR-V to Metal" (purely an example btw, just wanted to probe the features I can use)
  • The linker settings is an array variable for C and CXxx, I also found this documentation clearing that up I believe
  • Package — Swift Package Manager
  • Finally, so other then linking and sort of mapping our files from say C/C++/Objective C.... the Package.swift will build so long as the structure of the file-tree parses correctly? Because for better or worse, I just ripped that old Package file and it builds fine. Trying to replicate it in another, blank project and that builds fine too.

Anyway, sorry if this is not your wheel house and it took a while. I am currently sort of manually grepping, see what I can do. And since I want to write my own swift packages and import them here, I sort of just want to make it all work best I can.
But basically, the Package.swift is a series of arrays/map, with various conditional compilation options with # and using linker settings with [CSettings], as an example for my use case. Are there other C bindings that Swift has I can clone and study?

Hi, I am really late to the party, but I found a way to make last version of raylib running with swift.

OS: MACOS

  1. Install Raylib via Homebrew
  2. Download release from github.
    2.1 LINK: Release raylib v5.5 · raysan5/raylib · GitHub
  3. Create swift executable project
  4. Inside Sources
    4.1 create Folder Craylib
    4.2 Copy raylib release into Craylib (including the include and lib folders)
    4.3 Create the following module.modulemap file
module Craylib {
    header "include/raylib.h"
    link "raylib"
    export *
} 
  1. Configure Craylib dependency in package file
    targets: [
        .target(
            name: "Craylib",
            path: "Sources/Craylib",
            linkerSettings: [
                .linkedLibrary("raylib"),
                .linkedFramework("CoreVideo"),
                .linkedFramework("CoreGraphics"),
                .linkedFramework("IOKit"),
                .linkedFramework("AppKit")
            ]
        ),
        .executableTarget(
            name: "game",
            dependencies: ["Craylib"],
            path: "Sources"
        ),
    ]
  1. Main file can now import Craylib package
// The Swift Programming Language
// https://docs.swift.org/swift-book

import Craylib

public struct Colors {
    public static let rayWhite = Color(r: 245, g: 245, b: 245, a: 255)
    public static let lightGray = Color(r: 200, g: 200, b: 200, a: 255)
    public static let gray = Color(r: 130, g: 130, b: 130, a: 255)
    public static let darkGray = Color(r: 80, g: 80, b: 80, a: 255)
    public static let yellow = Color(r: 253, g: 249, b: 0, a: 255)
    public static let gold = Color(r: 255, g: 203, b: 0, a: 255)
    public static let orange = Color(r: 255, g: 161, b: 0, a: 255)
    public static let pink = Color(r: 255, g: 109, b: 194, a: 255)
    public static let red = Color(r: 230, g: 41, b: 55, a: 255)
    public static let maroon = Color(r: 190, g: 33, b: 55, a: 255)
    public static let green = Color(r: 0, g: 228, b: 48, a: 255)
    public static let lime = Color(r: 0, g: 158, b: 47, a: 255)
    public static let darkGreen = Color(r: 0, g: 117, b: 44, a: 255)
    public static let skyBlue = Color(r: 102, g: 191, b: 255, a: 255)
    public static let blue = Color(r: 0, g: 121, b: 241, a: 255)
    public static let darkBlue = Color(r: 0, g: 82, b: 172, a: 255)
    public static let purple = Color(r: 200, g: 122, b: 255, a: 255)
    public static let violet = Color(r: 135, g: 60, b: 190, a: 255)
    public static let darkPurple = Color(r: 112, g: 31, b: 126, a: 255)
    public static let beige = Color(r: 211, g: 176, b: 131, a: 255)
    public static let brown = Color(r: 127, g: 106, b: 79, a: 255)
    public static let darkBrown = Color(r: 76, g: 63, b: 47, a: 255)
    public static let white = Color(r: 255, g: 255, b: 255, a: 255)
    public static let black = Color(r: 0, g: 0, b: 0, a: 255)
    public static let blank = Color(r: 0, g: 0, b: 0, a: 0)
    public static let magenta = Color(r: 255, g: 0, b: 255, a: 255)
}

let window: Void = InitWindow(800, 600, "Hello, World!")

while !WindowShouldClose() {
    BeginDrawing()
    ClearBackground(Colors.rayWhite)
    DrawText("Hello, World!", 20, 20, 20, Colors.black)
    EndDrawing()
}

CloseWindow()

We have to redefine Colors because that comes from a C macro that is not compatible in swift

I hope that helps.