Re: Understanding CRUNCH embedding

Diogo via Chicken-users <[email protected]> Wed, 17 Dec 2025 09:23:37 +0100
Newsgroups gmane.lisp.scheme.chicken
Message-ID <7oxe44a6efnlg3i7msgb6rwtybdif6rayua4rbp77uxzl3qysf@yh4eqrwnoti5>
On Wed, Dec 03, 2025 at 06:14:05PM +0100, Felix Winkelmann wrote:
> On Tue Dec 2, 2025 at 8:15 AM CET, Diogo Behrens wrote:
> Version 0.993 of CRUNCH now includes the generated file, note that an
> output-filename has to be supplied now when wrappers are generated.
> This isn't the most elegant solution, but should handle most uses
> of wrappers (e.g. as CHICKEN extensions or when writing testing
> modules for CRUCHed code).

This works nicely now. Thank you!

Related to embedding or importing, another problem showed up and I am not sure
how to handle it. So let me use this email thread since it is somewhat related.

I'll try to attach to this email a .tar file with a few .scm files inside. I
hope the mailing list won't reject it. The problem is as follows:

We have a simple CRUNCH file called bytevec-impl.scm, which contains these two
procedures:
     (: (sum-bytevector bytevector) byte)
      (define (sum-bytevector vec)
        (let sum ((idx 0) (val 0))
          (if (= idx (bytevector-length vec))
              val
              (sum (+ 1 idx) (+ val (bytevector-u8-ref vec idx))))))
      (: (make-a-bytevector integer byte) bytevector)
      (define (make-a-bytevector len init)
        (make-bytevector len init))

The first shows that a bytevector created in CHICKEN can be passed to CRUNCH.
The second shows that a bytevector created in CRUNCH can be returned to CHICKEN.

We have two ways how to import this in a CHICKEN test case (bytevec-test.scm),
embedding and importing a wrapper library (that is the connection to the
message I am replying).

    ; bytevec-test.scm
    (import (scheme base)
            (scheme write))

    (cond-expand
      (include-impl
        (import (crunch))
        (crunch
          (include "bytevec-impl.scm")))
      (else (import (bytevec wrap))))

    (display "(sum (1 2 3 4 5)) = ")
    (display (sum-bytevector (bytevector 1 2 3 4 5)))
    (newline)
    (display "(make-a-bytevector 5 0) = ")
    (display (make-a-bytevector 5 0))
    (newline)
    (display "OK\n")


In theory it shouldn't matter if we embed it or import it. There is a script
(runtests.sh) that runs both cases and this is the output:

    % ./runtest.sh
    == CFLAGS based on CRUNCH -cflags
    CFLAGS="$(chicken-crunch -cflags) -DCRUNCH_NO_UTF"
    === EMBEDDING scenario
    == compile CHICKEN test with embedded (crunch ...)
    csc -C "$CFLAGS" bytevec-test.scm -feature include-impl
    == run test with embedding
    (sum (1 2 3 4 5)) = 15
    (make-a-bytevector 5 0) = #u8(0 0 0 0 0)
    OK
    === IMPORTING scenario
    == translate bytevec CRUNCH module and emit a CHICKEN wrapper
    chicken-crunch -emit-wrappers bytevec.wrap.scm bytevec.scm -o bytevec.c
    == compile CHICKEN wrapper and emit a CHICKEN import wrapper
    csc -C "$CFLAGS" -C -DCRUNCH_EMBEDDED bytevec.wrap.scm -J -s
    == compile CHICKEN import wrapper
    csc -s bytevec.wrap.import.scm
    == ls *.so should show
    ==   bytevec.wrap.so (which includes bytevec.c)
    ==   bytevec.wrap.import.so
    bytevec.wrap.import.so	bytevec.wrap.so
    == compile CHICKEN test without embedding
    == run test again
    (sum (1 2 3 4 5)) = 15

    Error: unbound variable: crunch#u8vector-result

    	Call history:

    	bytevec-test.scm:9: chicken.load#load-extension
    	bytevec-test.scm:11: scheme.write#display
    	bytevec-test.scm:12: chicken.bytevector#bytevector
    	bytevec-test.scm:12: bytevec.wrap#sum-bytevector
    	bytevec-test.scm:12: scheme.write#display
    	bytevec-test.scm:13: scheme#newline
    	bytevec-test.scm:14: scheme.write#display
    	bytevec-test.scm:15: bytevec.wrap#make-a-bytevector
    	bytevec.wrap.scm:20: crunch#u8vector-result	  	<--
    (make-a-bytevector 5 0) =

My guess is that it is related to CRUNCH_EMBEDDED and the static or non-static
definitions inside crunch.h. It seems that the CRUNCH_STATIC macro is not ever
used. Or am I missing some flag when building bytevec.wrap.so?

Thanks!

Best,
-Diogo
bytevec.tar (application/x-tar, 10 KB) - not displayed