Skip to content

Instantly share code, notes, and snippets.

@p1xelHer0
Created January 2, 2024 07:26
Show Gist options
  • Save p1xelHer0/713444565ae6eff586f21500efa0733a to your computer and use it in GitHub Desktop.
Save p1xelHer0/713444565ae6eff586f21500efa0733a to your computer and use it in GitHub Desktop.
Gerbil ncurses FFI macOS

So, I am a little bit (very) new to C, "systems programming" and the tools surrounding C. I thought it would be fun to try to make a little ncurses thing with Gerbil!

I've installed gcc version 12.3.0 (with Nix if that matters) and ncurses6 with Homebrew. This would be instead of using clang provided by macOS by default? I think I read in the docs that gcc is preferred. Is this still the case on macOS?

I've compiled a C-program using ncurses with gcc and got it to run using the following:

gcc `ncurses6-config --cflags --libs` test.c -o test.out

The program if that matters:

#include <ncurses.h>

int main(int argc, char **argv)
{
    initscr();

    WINDOW *win = newwin(5, 10, 0, 0);
    refresh();

    box(win, 0, 0);

    mvwprintw(win, 2, 2, "Hello");

    wrefresh(win);

    getch();
    endwin();
    return 0;
}

Now I wanted to write some FFI to call ncurses from Gerbil, so far I have the following:

;;; -*- Gerbil -*-
(import :std/foreign)
(export #t)

(begin-ffi (initscr
            refresh
            end-window
            getch)

  (c-declare "#include <ncurses.h>")

  (define-c-lambda initscr () void "initscr")
  (define-c-lambda refresh () void "refresh")
  (define-c-lambda getch   () void "getch")
  (define-c-lambda endwin  () void "endwin"))

I believe I need to provide the flags to the linker as well, my build.ss looks like this:

#!/usr/bin/env gxi
;;; -*- Gerbil -*-
(import :std/build-script)

(defbuild-script
  '("rogue/lib" "rogue/ncurses"
    (exe: "rogue/main" bin: "rogue"
          "-ld-options" "ncurses6-config --cflags --libs")))

I've probably missed something, the build results in the following:

github/p1xelHer0/rogue-gerbil
λ gerbil build
... build in current directory
... compile rogue/ncurses
ld: warning: object file (/Users/p1xelher0/code/github/p1xelHer0/rogue-gerbil/.gerbil/lib/p1xelher0/rogue/ncurses__0.o1.o) was built for newer macOS version (13.0) than being linked (11.0)
ld: warning: object file (/Users/p1xelher0/code/github/p1xelHer0/rogue-gerbil/.gerbil/lib/p1xelher0/rogue/ncurses__0.o) was built for newer macOS version (13.0) than being linked (11.0)
Undefined symbols for architecture arm64:
  "_endwin", referenced from:
      ____H_ncurses____0 in ncurses__0.o
  "_initscr", referenced from:
      ____H_ncurses____0 in ncurses__0.o
  "_stdscr", referenced from:
      ____H_ncurses____0 in ncurses__0.o
  "_wgetch", referenced from:
      ____H_ncurses____0 in ncurses__0.o
  "_wrefresh", referenced from:
      ____H_ncurses____0 in ncurses__0.o
ld: symbol(s) not found for architecture arm64
collect2: error: ld returned 1 exit status
"gcc"
*** Unhandled exception in #<thread #30>

*** ERROR IN ?
--- Syntax Error at compile: Compilation error; process exit with nonzero status
... form:   Continuation backtrace:
[0] gxc#gsc-compile-file
[1] gxc#compile-scm-file__%
[2] gxc#compile-runtime-code
[3] gxc#compile-runtime-code
*** ERROR IN std/misc/concurrent-plan#perform-plan/threads__% -- Build Failure at rogue/ncurses

*** ERROR IN ?
--- Syntax Error at compile: Compilation error; process exit with nonzero status
... form:   "gcc"
*** ERROR IN std/misc/process#run-process__% --
*** ERROR IN "misc/process.ss"@28.35-28.46 [ProcessError]: process exited with non-zero status
--- irritants: "/Users/p1xelher0/code/github/p1xelHer0/rogue-gerbil/build.ss" 17920 (path: "/Users/p1xelher0/code/github/p1xelHer0/rogue-gerbil/build.ss" arguments: ("compile") environment: #f directory: #f stdin-redirection: #t stdout-redirection: #f stderr-redirection: #f pseudo-terminal: #f show-console: #f)
--- continuation backtrace:
[0] raise
[1] std/misc/process#run-process__%                                                                                                                                            ((if (let () (declare (not safe)) (procedure? _check-status568488_)) _check-s...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment