IRC channel logs
2023-02-10.log
back to list of logs
<old>Say I want a module to be compatible with Guile 2.X because some distros are still on that version. How would you proceed? <old>e.g., I use procedure P that is available since 3.0.9. I could fallback to something else if on 2.X <old>Typically that would be done with the preprocessor in C, but what about Guile? <gnucode>lechner: yes. You need a bit of guile code that needs to be committed to guile properly... <gnucode>I think you might want that to get POST values... <gnucode>lechner: I also have a guile web development playlist... <old>daviid: awesome thank you <apteryx>sxml-match seems not having the right indentation rule in emacs <apteryx>it'd be nice to have json capability in <mwette>do you have this: (put 'sxml-match 'scheme-indent-function 1) <graywolf>I guess creating self-contained executable for guile program would not be that hard right? Can anyone recommend any reading on the topic (if there is any)? <civodul>apteryx: hey! for JSON i recommend define-json-mapping; it lets you map JSON to records in both directions <dthompson>graywolf: I don't know of anyone who has done that because guile can't produce standalone executables. <dthompson>I have generated redistributable binary bundles for guile programs in the past by bundling up the guile executable, libguile, all the shared libs it uses, all the scheme modules, etc. <graywolf>dthompson: Oh, I assumed since you can embed guile into C programs, it should be possible to just statically link it and bundle everything into one executable. Are there technical reasons I am missing? <dthompson>you'd still have to bring along all the scheme modules. <dthompson>I've never tried statically linking libguile into a program. the libraries it depends on would also need static versions to link in. <old>graywolf: It is easier said then done. I've had nighmware with trying to statically link Guile with some binary on a Ubuntu CI. <old>Something something with libunistring <dthompson>our best hope is having a native code compiler in the future that can produce a single executable. <graywolf>Right, so sounds like hard but in theory technically possible hard. Looks like fun research project, one day I might look into it. Thanks :) <dthompson>bundling guile, libguile, etc. is the most practical approach we can take for now. <dthompson>what I haven't tried yet is adding in something like flatpak that can produce a standalone executable with all stuff shoved into it. <graywolf>I have... distaste for flatpak, so I hope that will not be the only way to achieve this... <graywolf>At that point why not just use a typical linux container? Seems like more mature way that many more developers actually understand (at least to some degree). <apteryx>civodul: hi! that's in core Guile? thanks! <dthompson>because you don't need a container runtime installed <old>Guix-pack can do much of that <old>Only for Linux though <old>But what is the use case here for static binary? <dthompson>it all depends on what you can assume about the target system <dthompson>old: giving someone a single file and saying "just run this" <old>right then shipping a shell script with embedded .tar.gz of a guix pack should work <dthompson>right now I've gotten guile game distribution to 2 steps: extract tarball, run executable launcher script. <dthompson>1) a non-containerized guix package requires root privileges <dthompson>2) a containerized version isn't guaranteed to not require root privileges <old>yes I agree there's still some caveat. But it most cases where you want someone to try your stuff, it works <old>at least I was able to run some students work on a HPC node by packing in some place else before. <old>So it depend on the use case. For video game I agree it's not the best option <apteryx>dthompson: I don't understand where the root privileges requirement comes from? <dthompson>apteryx: a non-containerized guix pack extracts to /gnu <apteryx>ah, you mean non-relocatable, not containerized <dthompson>relocatable guix packs aren't guaranteed to work, either <old>Nothing wrong with assuming systems most support linux namespace <dthompson>but shipping the entire dependency tree is not reasonable for all use-cases <dthompson>the last game I made has a bundle that is 17MB. guix pack couldn't get close to that. <old>But if we were to make a bundle Guil <old>I think that having A) A static version of Guile available for download B) A way to patch that static version to include user modules + entry point <dthompson>my bundles are targeted at non-guix FHS distros and assume its being run on a system with a graphical environment. reasonable assumptions for this type of thing. sometimes there are issues but most of the time it works. <old>Or just statically link libguile with a bianry that bootstrap the program that way and include the modules in it <old>In other words, just a matter of linkage here and bootstrapping. <old>Easier said then done ofc, but doable <dthompson>that could work. would be cool to see someone do it. <old>I ain't afraid of low level so I could put a hand on that <old>after my master thesis :-P <old>Then there's the Windows problem <old>Because who use ELF anyway <old>then it's a no brainer. <apteryx>dthompson: fyi, it doesn't solve the fatness of guix packs, but the 'rpm' format (as in 'guix pack -f rpm' is coming soon (in review) <old>The assumption is that the system is a sane one and use ELF as its binary file format <dthompson>what I *almost* got to work was using guix to build relocatable libraries and executables for me. <dthompson>it involved using a tweaked gcc that doesn't do runpath hardcoding (so no /gnu/store stuff) and making package variants for every library I needed that used the modified toolchain. <old>Btw can static binary use dlopen? <old>I don't see why it could not <dthompson>yeah me either but I don't want to be overconfident ;) <old>but I have a vague souvenir of something <old>well there's an easy way to find out. just some hello-world <dthompson>one notable feature of chickadee's bundler that I think is neat is that it loads up the root scheme modules to be bundled and uses guile's module introspection to include only the set of modules needed. <dthompson>that dramatically reduced the size of the final bundle <old>test.c:(.text+0x13): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking <dthompson>in that case might as well just pack up all the shared libs <dthompson>I use ffi stuff heavily so I would need to ship shared libs no matter what <dthompson>until I conquer the world and replace the need for them with scheme code <old>say you statically link all dependencies <old>could we make the ffi to try to resolve library inside the binary itself before looking for external <old>how about something like this <old>try to resolve "librt_shm_open" in the binary if it's available. Otherwise, lookup "shm_open" in "librt.so" <old>Only thing you need to do, generate some weak symbols in the final binary <dthompson>my top priority for the ffi is to add something like CL's define-c-struct <civodul>apteryx: define-json-mapping is in Guile-JSON <old>dthompson: Can't find a reference to what. You have a link? <dthompson>scheme-bytestructures exists but I dunno it feels too abstract. there should be something in core guile specifically for FFI purposes. <old>Can't be that hard to make <dthompson>there's some struct padding rules that seem error prone <dthompson>but nothing that some real-world usage couldn't expose :) <dthompson>and guile has some very primitive struct handling code that does the padding right so we could use that as a starting point <old>From what I can see, we want some syntax that could translate a more human readable form to a form acceptable for make-c-struct <dthompson>yeah it should look like a c struct definition <dthompson>the CL syntax is very close to what it should be in Scheme imo <old>Missing the getter/setter <old>which require an understanding of the memory layout of members. Ofc that can be done <old>we can even throw in a syntax to do something like (point (x 1) (y 2)) instead of (make-point #:x 1 #:y 2) <dthompson>old: yeah that's the basic syntax. unfortunately, using make-c-struct and co. is inefficient. <dthompson>c struct objects should be backed by bytevectors so read/write in either c or scheme is efficient. <dthompson>with a cached pointer object to avoid allocating a fresh pointer every time it's passed through the ffi <old>well just need to pointer->bytevector <old>then it's a matter of bytvector-TYPE-ref/set! <old>with proper alignment and size <old>I'll look into that this weekend if I have time. Should be relatively easy to do with syntax-case <apteryx>the '...' in a match replacement doesn't behaves the same it would in a syntax definition, does it? <old>getters/setters would be a syntax-transformer of the form: (define-syntax (getter obj) (bytevector-TYPE-ref (car obj) 0 (native-endianness) OFFSET) <old>Not a fan of the (car obj) though. Would probably allocate an extra member at the end of the C struct to tag it. Then the object is simply a bytevector and its type is embedded in it <old>apteryx: Both are zero or more? <apteryx>I can work around it using map on revision and lang, but I thought there should be a way to make my original idea work <dthompson>old: I'd recommend using a record type to hold all the data. <old>apteryx: Hmm I'm no match guru unfortunatly :/ <old>dthompson: srfi-9 record are not bytevector? <old>They are list I think <old>how would you make that work? <dthompson>old: the bytevector would be stored within the record <old>but the field of the record <dthompson>so that each distinct c struct type has its own type and they can't get mixed up <old>here's a refined version <old>The type tag is whitin the bytevector. It's guaranteed to be its own type that way <dthompson>it should be false. it's *wrapping* a bytevector and is its own type <old>right. define-wrapped-pointer does that <graywolf>Do I need to define functions in the order they are used? I assumed I can in general do (define (x) (y)) (define (y) #t) (x), and it should work. But it did blow up when I (define ...) function that used a record accessor before doing the (define-record-type). So, does order matter or I just did something bad? <old>sneek: latter tell dthompson there's couple of things to get fix. First module resolving of type with (system foreign) means no composition of structure <sneek>dthompson, old says: there's couple of things to get fix. First module resolving of type with (system foreign) means no composition of structure <old>sneek: later tell dthompson there's couple of things to get fix. First module resolving of type with (system foreign) means no composition of structure <old>sneek: later tell dthompson then there's the referencing with bytevector with I don't like. <mwette>old: If you want to create c-structs for FFI you want to think about referencing and dereferencing, I think. (The nyacc FFI Helper provides pointer-to and value-at.) Also, packed structs may be needed. <old>mwette: Right. I'm on it <mwette>Also, IIRC, wingo once mentioned wish to build ffi-gateway into the VM.