shirok / Gauche-makiki

A simple multithreaded http server
BSD 3-Clause "New" or "Revised" License
34 stars 2 forks source link

html rendering - as currently in makiki: with single quotes throughout - causes issues - solution provided as well #11

Open reuleaux opened 7 months ago

reuleaux commented 7 months ago

OK, another one - and it's late into the night in London currently (and I am kind of exhausted) - thus bear with me (and this is not a polished bug report thus), but I want to get this out nevertheless:

Makiki is Great! Many thanks, again. - I am just not convinced that the current way of rendering the html tree with functions

tree->string & sxml:sxml->html

is the best one possible (and tree->string from text.tree is just calling write-tree with a string output port, as I have learned from the Gauche-Manual. And we have just recently discussed them here in the issue tracker ...)

Now the issue I have with them is, that attributes there are rendered in single quotes throughout: just look at the source code of any (simple) rendered page (rendered with):

(respond/ok req blahblah)

and you can see (you know) it looks like this:

<html lang='en'><head><meta charset='utf-8'> ...</html>

Now comes the problem: I have a (very simple) contact database application: one can see a list of contacts, view the details of one or the other contact, edit them (or similarly add new contacts) - nothing complicated: To make it simple: say one contact has only three fields: first name, last name , and a mobile number.

Thus the edit form has some input fields:

first name: 
last name:
mobile:

in detail:

<input type='text' name='firstName' id='firstName' value='Paul'>

and likewise for lastName, and mobile. - These are form fields (within a form element, which is then sent with a post request to the server ... you know all this! that's basic stuff). the server notes the changes, and responds with another page: these contact details in a view page. (such a view page is very similar, just with readonly='t' for the input fields).

Now I have a bad habit of taking notes in form fields, likes so: for the mobile number I note not only the number, but also when / where I got this number I enter into this text input field

mobile:
0987654321 - from Blah, in November '23

I.e. I type (among other characters) a literal single quote in my (mobile number) form field. - I save it (it's sent to the server, the server notes the changes, and sends back the corresponding view page:

The page sent back looks strange - and not too surprisingly: I look at its source:

<input type='text' readonly='t' name='mobile' id='mobile' value='0987654321 - from Blah, in November '23'>

See the problem?

I have thus swapped out tree->string & sxml:sxml->html (for now), and replaced it with some other function that works for me - from some blog post of David Thompson originally (then adapted for my needs in Guile at the time, and now ported to Gauche,): I am attaching the module below : oursxml2html.scm (and I have written a few more words in the comments therein).

Now instead of calling

(respond/ok req blahblah)

for rendering some sexp tree blablah I just call:


(use oursxml2html :only (sxml->html-string))

;; and deep inside a handler:

        (respond/ok req
          (format #f "~a~%~a"
        "<!doctype html>"
        ($ sxml->html-string $ cdr blahblah)
        ))

i.e. I strip off the sxml root node with cdr (as I don't want to change my application too much), and then I do my own (David Thompson's) rendering: And (as is usual anyway, I guess?): double quotes are used for attributes. - All the pages render fine, and the above issue is gone.

I guess you can reproduce the above issue on your own. - If not: let me know, and then I can provide a complete example: but I will want to strip down my code to its essential core (thus not here/now).

Thus at this time only the oursxml2html rendering module with function sxml->html-string therein below. - If you really want to use this code then: I guess you should test it more thoroughly / give it some polish (and maybe see with regards to licensing: maybe contact David).

OK ... I just tried to upload it - but I got a message: we don't support that file type (a scheme file i.e.)... Thus I am pasting it in here - if that's getting too complicated: I can send it by e-mail

Thanks, Andreas


;; This is from an article / blog by David Thompson (of Guile fame):
;; https://dthompson.us/rendering-html-with-sxml-and-gnu-guile.html

;; modifications (for Gauche, among others) & comments are mine (Andreas Reuleaux)

;; Apparently there are different versions of these rendering html functions:

;; (1)
;; the original article contained a slightly more powerful version
;; as I remember: also providing for unescaped / raw html output.

;; (2)
;; whereas the version found in Haunt (David's static website generator in Guile)
;; was less powerful: did not take raw html into account.

;; that's why I looked into this in more detail at the time - in Guile:
;; I switched raw html rendering back on again.

;; that's why there are two functions: sxml->html and sxml->html2
;; at the end (with and wo/ raw ...)

;; But all this raw rendering is of no importance here for Gauche:
;; (it's just an introduction: why I looked into that html rendering in
;; more detail at the time).

;; Now having spent some time with this rendering by hand (as by David's functions below),
;; taking them to Gauche now, was not too difficult: (paragraphs should be swapped: 
;; continue reading below with basically) ...

;; Also, now that I look at it again: I see that there is also a means to take
;; care of (render) a doctype declaration somehow: I don't know how it works
;; (have tried this at the time, but not now again), as I am rendering the doctype separately now: like so
;; typically:

;; (respond/ok req
;;   (format #f "~a~%~a"
;;  "<!doctype html>"
;;  ($ sxml->html-string $ cdr (edit c))
;;  ))

;; Thus maybe this doctype stuff below can be removed? - likewise the raw html stuff
;; that's rarely ever needed...

;; basically  - to make it work with Gauche -

;; * I had to get rid of one nested function definition
;;  in string->escaped-html below: turned the inner function into a let & lambda

;; * and have used the Gauche way of getting (asking about) elements in a hash table

;; Ah, and as I remember: the module did provide a function pair: ...sxml->xml & sxml->html - I have split this in two,
;; and am only covering the sxml->html part here.

;; That's it: sxml->html-string renders all my html beautifully now,
;; and without any issues

(define-module oursxml2html

  (use util.match)

  (export sxml->html-string)

  )

(select-module oursxml2html)

;; I guess we need this
(define *unspecified* '|*unspecified*|)

;; as I understand: these  have an impact of how empty elements (with no children) are rendered
;; (being in this list or not i.e.) - yet to try out in more detail.

(define %void-elements
  '(area
    base
    br
    col
    command
    embed
    hr
    img
    input
    keygen
    link
    meta
    param
    source
    track
    wbr))

(define (void-element? tag)
  "Return #t if TAG is a void element."
  (pair? (memq tag %void-elements)))

(define %escape-chars
  (alist->hash-table
   '((#\" . "quot")
     (#\& . "amp")
     (#\< . "lt")
     (#\> . "gt"))))

;; two modifications from the guile version:
;; (1) could not define an inner function - thus a lambda, let-bound instead
;; (2) have used the gauche way of hash referencing: hash-table-get with a default value #f

(define (string->escaped-html s port)
  "Write the HTML escaped form of S to PORT."
  (let ([escape (^c
          (let (
             [escaped (hash-table-get %escape-chars c #f)]
             )
           (if escaped
             (format port "&~a;" escaped)
             (display c port))))])
    (string-for-each escape s)))

(define (object->escaped-html obj port)
  "Write the HTML escaped form of OBJ to PORT."
  (string->escaped-html
   (call-with-output-string (cut display obj <>))
   port))

(define (attribute-value->html value port)
  "Write the HTML escaped form of VALUE to PORT."
  (if (string? value)
      (string->escaped-html value port)
      (object->escaped-html value port)))

(define (attribute->html attr value port)
  "Write ATTR and VALUE to PORT."
  (format port "~a=\"" attr)
  (attribute-value->html value port)
  (display #\" port))

(define (element->html tag attrs body port)
  "Write the HTML TAG to PORT, where TAG has the attributes in the
list ATTRS and the child nodes in BODY."
  (format port "<~a" tag)
  (for-each (match-lambda
             ((attr value)
              (display #\space port)
              (attribute->html attr value port)))
            attrs)
  (if (and (null? body) (void-element? tag))
      (display " />" port)
      (begin
        (display #\> port)
        (for-each (cut sxml->html <> port) body)
        (format port "</~a>" tag))))

(define (doctype->html doctype port)
  (format port "<!DOCTYPE ~a>" doctype))

;; orig - as from haunt

(define (sxml->html tree :optional (port (current-output-port)))
  "Write the serialized HTML form of TREE to PORT."
  (match tree

    [() *unspecified*]

    [('doctype type)
      (doctype->html type port)]

    [((? symbol? tag) ('@ attrs ...) body ...)
      (element->html tag attrs body port)]

    [((? symbol? tag) body ...)
      (element->html tag '() body port)]

    [(nodes ...)
      (for-each (cut sxml->html <> port) nodes)]

    [(? string? text)
      (string->escaped-html text port)]

    ;; Render arbitrary Scheme objects, too.
    (obj (object->escaped-html obj port))))

;; as from the article
;; https://dthompson.us/rendering-html-with-sxml-and-gnu-guile.html
;; w/ raw

(define (sxml->html2 tree :optional (port (current-output-port)))
 "Write the serialized HTML form of TREE to PORT."
 (match tree
   (() *unspecified*)
   (('doctype type)
    (doctype->html type port))

   ;; Unescaped, raw HTML output
   (('raw html)
    (display html port))

   (((? symbol? tag) ('@ attrs ...) body ...)
    (element->html tag attrs body port))
   (((? symbol? tag) body ...)
    (element->html tag '() body port))
   ((nodes ...)
    (for-each (cut sxml->html <> port) nodes))
   ((? string? text)
    (string->escaped-html text port))
   ;; Render arbitrary Scheme objects, too.
   (obj (object->escaped-html obj port))))

(define (sxml->html-string sxml)
  "Render SXML as an HTML string."
  (call-with-output-string
   (lambda (port)
     (sxml->html sxml port))))
shirok commented 7 months ago

I do remember I was bitten by this quirk before. I think I used workaround with my own renderer just as you did, but since we've got another victim, I think it's time to address this once and for all.

Providing yet another sxml->html is not very difficult, but I don't like having multiple similar libraries in bundle. I've refrained from modifying sxml libraries from the original, so that it would be easier to follow the upstream update, but sxml development seems stalled for years so I may just go and fix it in the library.

reuleaux commented 7 months ago

And I am adding: given that the above function sxml->html-string uses double quotes for attributes, like so:

<input type="text" class="v" readonly="t" name="lastName" id="lastName" value="Antonio" />

I am challenging this approach: misusing my input-type-text mobile field again - writing not only a mobile telephone number, but some double quotes, as well, say:

mobile:
0987654321 the "Lioness" 

and the server responds this time correctly (using the above sxml->html-string function) with:

<input type="text" readonly="t" name="mobile" id="mobile" value="0987654321 - &quot;the Lioness&quot;" />

without me having to think about any escaping.

reuleaux commented 7 months ago

Ah, and I have only now read your message above: yes fine: do what you consider is appropriate (and let me know) - and I will use my own renderer for now, and then the updated libraries (once you have fixed them)

reuleaux commented 7 months ago

Ah, and one more remark and one more question:

You might as well look at the Guile way of handling all thing web: below is a simple web server in Guile: this is all very low level stuff (nowhere near the comfort of Makiki): you have to write your own dispatcher, etc. - but (!) their sxml->xml function (from (sxml simple)) returns xml correctly quoted in double quotes (I think they have also a sxml->html function, I don't remember why I have used the sxml->xml function instead - or maybe I am wrong: there is no such sxml->html function, and therefore the article by David Thompson). - You will find more explanations in the Guile Reference Manual.

...Which brings me to another question - with regards to Makiki: I have always wondered why the respond/* functions need the req as argument in Makiki

(respond/ok req someanswer)

I am sure there is a technical reason, but (on this low level of Guile at least - as below - that is not necessary:

(respond someanswer)

Which seems simpler to me, and also more in harmony with the intuition of communication:

You ask me question, like: "How are you?" (req)

And I respond: "Thanks, fine!" (respond , respond/ok) (i.e. I just respond, I don't usually repeat your question: "How are you? - Thanks, fine!" or: "How am I? - Thanks, fine!"

(You do this kind of always repeating the question with the elderly who have hearing issues, but not in normal day to day conversation.)

I would be curious to know why in Makiki the req is required in all the response functions. (apparently on a lower level: as in Guile below this is not necessary (one can just call: (respond (page)) below).

Thanks again, Andreas

file basic.scm

#!/usr/bin/guile \
-e main -s
!#

(read-set! keywords 'prefix)

(use-modules

  (web server)
  (web request)
  (web response)
  (web uri)

  (sxml simple)

  ;; (sxml xpath)

 )

(define (page)
  `(html (@ (lang en))
     (head
       (meta (@ (charset utf-8)))
       (title page)
       (link (@
           (type text/css)
               (rel stylesheet)
               (href /main.css)
               ))
       (body
         (div (@ (id main))
           (span "blah")
           )
         ))
     ))

(define* (respond
       :optional body
           :key
           (status 200)
           (doctype "<!DOCTYPE html>\n")
           (content-type-params '((charset . "utf-8")))
           (content-type 'text/html)
           (extra-headers '())
           (sxml body)
           )
  (values (build-response
           :code status
           :headers `((content-type
            . (,content-type ,@content-type-params))
                       ,@extra-headers)
            :port 8080
           )
    (lambda (port)
      (if sxml
        (begin
          (if doctype (display doctype port))
          (sxml->xml sxml port))))))

(define (dispatch request body)
  (let
    (

      [path (uri-path (request-uri request))]

      ;; [query (uri-query (request-uri request))]
      )

    (cond

     [(string= path "/page")
       (respond (page))
       ]

      [else
    (respond "not found")
    ]

      )

    ))

(define (main args)
  (run-server dispatch)
  )
shirok commented 7 months ago

The request packet is not merely a static data to represent a request, but rather managing the context of that reqest-response. Some info in it is used to produce the response. (So it may be a misnomer, but 'context' is too generic.)

The reason that we carry around a request (or context) packet is to allow "wrapper" pattern in a consistent way. Remember, a handler is a procedure (lambda (request app-data) ...). You can provide a library to add a specific feature with (lambda (inner-handler) (lambda (request app-data) ...do-something-with-request-packet... (inner-handler request app-data))). See with-* procedures in makiki.scm.

By having a single packet to carry the context, all with-* procedures can be easily composed together.

reuleaux commented 7 months ago

OK, Great! - And thanks for this explanation!

shirok commented 7 months ago

Pushed a fix to Gauche repo for attribute value escaping in sxml:sxml->xml and sxml:sxml->html. Can you try it to see it addresses your original issue?

reuleaux commented 7 months ago

Hm, I am not sure - but this might as well be my bad: I did install Gauche with

get-gauche.sh --auto --prefix ~/opt/gauche

Now, when I do:

get-gauche.sh --auto --prefix ~/opt/gauche

You already have Gauche 0.9.14 in '/home/rx/opt/gauche/bin/gosh'.
No need to install.  (Use --force option to install 0.9.14.)

therefore I do

get-gauche.sh --auto --prefix ~/opt/gauche --force

which then did recompile/reinstall gauche - I am not sure though: maybe this is just for Gauche releases? And this is not the proper way to update to git head as well? - as one would normally do with git fetch & git merge origin/master e.g.? Anyway, with this reinstalled Gauche (as I said: this may not be completely up to date ) I still have the issue when now using

(respond/ok req (edit))

and my edit form being defined as

(define (edit)
  `(sxml
      (html (@ (lang "en"))
      ....
       ))

I am busy in the next hours - but I will get back to this - and move to a more manual git work flow with gauche, I guess: git fetch & git merge - so I know at least what version / patches I am working with (or maybe just brutally remove all of my gauche, and use try get-gauche again:

so basically - with this probably not quite up-to-date gauche I am currently stlill seeing (then in my view form):

<input type='text' readonly='t' name='mobile' id='mobile' value='0987654321 - Nov '23'>

so there are two things here:

If one uses single quotes for attributes (as is the case above): then obviously single quotes must be escaped.

If double quotes are used (which I would find nicer style - by the way) like so

<input type="text" readonly="t" name="mobile" id="mobile" value="0987654321 - Nov '23">

then this November '23 example is not an issue, but one has to properly escape double quotes: for values like: 09876543 - the "Lioness"

Did you stick with single quotes for attributes? and are now escaping them for values? Or did you choose double quotes? - I haven't had the time yet to look at your patch in detail. - Anyway: I will get back to this later. thanks so far.

reuleaux commented 7 months ago

OK (as I understand:) I need to set up a proper dev environment, git clone gauche, and follow the steps in the HACKING document.

And I seem to remember: I need a proper release installed first (which I have: with get-gauche as above), for I can build this dev gauche - it needs gosh during the build process.

Thus with my release gauche in ~/opt/gauche. I trying to build a devgauche now:

git clone https://github.com/shirok/Gauche devgauche
cd devgauche
./DIST gen
./configure --prefix ~/opt/devgauche

some complaints about tls: I will look into this later (--with-tls), and then

make

having my release gosh in my path, or as a function in my case: like so

$ type gosh
gosh is a function
gosh () 
{ 
    ~/opt/gauche/bin/gosh -I. "$@"
}
rx@softland ~ $

maybe just having ~/opt/gauche/bin in my path would be better? - Anyway: make stops at some point with

...
GAUCHE_LOAD_PATH="" GAUCHE_DYNLOAD_PATH="" "/home/rx/opt/gauche/bin/gosh" -v:0.9.14 -l./preload -I../src -I../lib -I../lib -I. `cat ./features.flags` ../lib/tools/precomp -D LIBGAUCHE_BODY libextra.scm
gosh: "ERROR": cannot find "gauche/collection" in ("/home/rx/opt/devgauche/share/gauche-0.98/site/lib" "/home/rx/opt/devgauche/share/gauche-0.98/0.9.14/lib")
make[1]: *** [Makefile:29: libextra.c] Error 1
make[1]: Leaving directory '/home/rx/tmp/gauche/src'
make: *** [Makefile:47: all] Error 1
rx@softland {master} ~/tmp/gauche $ 

Maybe I have to set some more variables (pointing to my release gauche in ~/opt/gauche for things like gauche/collection to be found?

maybe I need this % gauche-config --reconfigure | sh step (as on the download page)? Anyway, I am continuing with this... Thanks so far.

shirok commented 7 months ago

Best bet is to include your installation path in PATH. I test it in that way all the time. Sometimes, if your previous build is incomplete, some unsatisfied dependency causes a build error; generally starting over from make distclean solves the issue.

reuleaux commented 7 months ago

I am one step further: got a development Gauche installed, and can confirm that with this latest (git head) Gauche, the escaping of attributes in (nice now:) double quotes works fine! Many thanks.

My way of installing was this: as explained above I had previously installed Gauche with

./get-gauche.sh --auto --prefix ~/opt/gauche

I call this a release gauche (Gauche 0.9.14 in ~/opt/gauche), and I didn't want to touch this / mess with this, as already I am relying on some working gauche on my system.

Now, while previously/above having tried to install a development version of Gauche in ~/opt/devgauche, by making use of this already installed release gauche - I guess this all got too confusing at some point with regards to the paths: two different gauche paths: ~/opt/gauche/bin and ~/opt/devgauche/bin ... (but maybe it is possible somehow w/ BUILD_GOSH - I haven't tried this any further), I have now installed:

(1) first a release gauche in ~/opt/devgauche with

./get-gauche.sh --auto --prefix ~/opt/devgauche

(2) and then into this same location a dev gauche with

./configure --prefix ~/opt/devgauche --with-tls=none
make
make check
make install

having my path set with

export PATH=$PATH:$HOME/opt/devgauche/bin

i.e. both: the release gauche, and the yet to built gauche (during installation) sharing the same (bin and make target) path. This worked fine! - And now with makiki installed again, html rendering works fine:

(in the view form sent back by the server, having made some challenging changes in the edit form):

rendering attributes with single quotes isn't an issue (needs no escaping), as attributes are rendered in double quotes now (nice, thanks!):

<input type="text" readonly="t" name="mobile" id="mobile" value="0987654321 - Nov '23">

and for my friend Lea (I call her the "Lioness") I note her phone number ... and get back her phone number field correctly escaped:

<input type="text" readonly="t" autocomplete="off" name="phone" id="phone" value="0654321 - the &quot;Lioness&quot;">

Everything seems fine now, thanks again!

shirok commented 7 months ago

There's a feature to let multiple versions of Gauche coexist. However, it only works when they have different version numbers; I haven't bumped the version number from 0.9.14 yet, so you can't install 0.9.14 release and HEAD together.

But there have been quite a few changes, so I might bump it to 0.9.14-p1 or something. Once I do it, you can install HEAD with the same prefix, and gosh -v0.9.14 ... would run the 0.9.14 release, while just gosh would run the HEAD.

In fact, it is convenient that gosh -v0.9.14 always run the proper 0.9.14 release... I could immidately bump the version number with suffix after release so that it is always possible to distinguish official release and HEAD.

reuleaux commented 7 months ago

OK, thanks - I may try this in the future then!

reuleaux commented 7 months ago

There are still some issues with the rendering unfortunately! (while the escaping of values with double quotes is fixed now, as discussed above, thanks again):

Below are two little code snippets from the leanpub Alpine.js book https://leanpub.com/getting-started-alpine-js - to make them work, you'd have to either add a script tag

`(script (@
         (defer "")
         (src "https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js")

or otherwise download alpine.js - very simple beginner examples, i.e.: hiding/showing some content, and graying out some buttons depending on state.

But the (Makiki) rendering issue is visible even without installing Alpine: (and I am by no means an Alpine expert: a beginner really - but the rendering issue is easily seen):

In the first example:

(div (@
       (x-data "{ open: false }")
       )
  (button (@
        (x-on:click "open=!open")
        )
    "Give me a click"
    )
  (div (@ (x-show "open"))
    "Hidden by default"
    ))

the button is rendered only with

<button click="open=!open">Give me a click</button>

were really it should be rendered as

<button x-on:click="open=!open">Give me a click</button>

i.e. the x-on: part of the attribute is cut off.

In this case there is a simple fix for me: use @click instead

(button (@
         (@click "open=!open")
           )

which works just as well, and is rendered fine. - However: with my own renderer sxml->html-string (as above), I don't have this issue at all: the button is rendered as

<button x-on:click="open=!open">Give me a click</button>

as it should be.

The second example is similar:

(div (@
       (x-data "{ woman: true }")
       )
  (button (@
        (x-bind:disabled "woman==false")
        (x-on:click "woman=false")
        )
    "Man")
  (button (@
        (:disabled "woman==true")
        (@click "woman=true")
        )
    "Woman")
  )

the buttons are rendered only as

<button disabled="woman==false" click="woman=false">Man</button>
<button disabled="woman==true" @click="woman=true">Woman</button>

i.e. the x-bind: and x-on: part of the attributes are cut off, resp for the second button: the colon before disabled.

With my own sxml->html-string renderer I don't have these issues: no part of any attribute is cut off i.e. - and this works thus: clicking on Man greys out Man (and makes Woman clickable), and vice versa - rendered as:

<div x-data="{ woman: true }">
<button x-bind:disabled="woman==false" x-on:click="woman=false">Man</button>
<button :disabled="woman==true" @click="woman=true">Woman</button>
</div>

Is there something special about these attributes with colons ?

If you need I can send you a complete working example - not now though (as I am busy) - but later.

Thanks again (in advance). - Andreas

shirok commented 7 months ago

I see, that's another quirk from the fact that HTML is not XML. SXML is strictly based on XML and as such, x-on:click is understood as click in the XML namespace x-on. SXML core has mechanism to deal with namespaces, but it looks like sxml:sxml->html was written without much thought about this issue. It blindly drops namespaces. (srl:sxml->html does not drop namespace info, but the way it emits output won't help either, although it is a valid XML).

I think it is wrong to recognize XML namespeace prefix within HTML. I can fix sxml:sxml->html.

I wonder why I haven't been bitten by this... Maybe I've used text.html-lite when I used JS framework that asks a colon in attribute names. Anyway, it's better that sxml.tools can handle stuff seamlessly.

shirok commented 7 months ago

Fix pushed in Gauche. The version of Gauche HEAD is also bumped to 0.9.14-p1, so you can install it with the same prefix with the released version of 0.9.14 if you like. If you run just gosh, it will run whatever you installed last. You can specify the version with -v option, e.g . -v0.9.14.

reuleaux commented 7 months ago

OK, thanks a lot! - I will have a look soon (being busy still). - And I meant to answer earlier: namespaces ... - I understand / makes sense! ...

reuleaux commented 7 months ago

Hm, I am struggling with the installation / build steps (again) - and have at some point decided to start anew - with the steps that had previously/above worked for me (i.e. from a completely clean environment):

have removed my target directory ~/opt/devgauche

rm -rf ~/opt/devgauche

have installed a release gauche (0.9.14) therein anew:

bash ./get-gauche.sh --auto --prefix ~/opt/devgauche

so far, so good:

~/opt/devgauche/bin/gosh -V

shows version 0.9.14, and - as previously - I have this in my path:

export PATH=$PATH:$HOME/opt/devgauche/bin

so this is the gauche that's being used for the next build steps:

And after some messing around in my git repository (in ~/tmp/devgauche), have decided to completely clean up everything therein, starting from a pristine HEAD checkout i.e.

I did

git fetch
git merge origin/master

and then therein

make distclean

and I git restored ... some build artefacts from previous builds: gc/ltmain.sh, gc/m4/libtool.m4, gc/m4/ltversion.m4- so now my git repository is completely clean - and up to date (shows in green in my bash prompt):

rx@softland {master} ~/tmp/devgauche $ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean
rx@softland {master} ~/tmp/devgauche $

Therein I start

./DIST gen
./configure --prefix ~/opt/devgauche --with-tls=none

and at the end of this configure run I see: we are about to build 0.9.14-p1 - Fine!

...
config.status: creating Makefile
config.status: creating bdw-gc.pc
config.status: creating include/config.h
config.status: executing depfiles commands
config.status: executing libtool commands
config.status: executing default commands

This Gauche has been configured with the following parameters:
           version: 0.9.14-p1
     documentation: Yes
              slib: /usr/local/slib
            thread: pthreads
           tls/ssl: 
          CA store: check 
  optional modules: gdbm zlib

rx@softland {master} ~/tmp/devgauche $

So there we go:

make

and this make is busy compiling for some time ..., but then stops with:

gcc -DHAVE_CONFIG_H -I. -I. -I./../gc/include -I../gc/include `./get-atomic-ops-flags.sh .. .. --cflags`   -g -O2 -Wall -Wextra -Wno-unused-label -fPIC -fomit-frame-pointer  -c test-extra.c
GAUCHE_LOAD_PATH="" GAUCHE_DYNLOAD_PATH="" "/home/rx/opt/devgauche/bin/gosh" -v:0.9.14 -l./preload -I../src -I../lib -I../lib -I. `cat ./features.flags` ../lib/tools/precomp -D LIBGAUCHE_BODY libextra.scm
gosh: "ERROR": cannot find "gauche/collection" in ("/home/rx/opt/devgauche/share/gauche-0.98/site/lib" "/home/rx/opt/devgauche/share/gauche-0.98/0.9.14-p1/lib")
make[1]: *** [Makefile:29: libextra.c] Error 1
make[1]: Leaving directory '/home/rx/tmp/devgauche/src'
make: *** [Makefile:47: all] Error 1
rx@softland {master} ~/tmp/devgauche $

I.e. gauche/collection is searched in /home/rx/opt/devgauche/share/gauche-0.98/0.9.14-p1/lib - well there is none yet: we are only building this 0.9.14-p1 after all!

There is a gauche collection in /home/rx/opt/devgauche/share/gauche-0.98/0.9.14/lib, but I have a hard time telling configure and/or make to use this path: I have tried

configure ... --with-local=/home/rx/opt/devgauche/share/gauche-0.98/0.9.14 ...

and various other configurations - but there are so many variables to set: LT_SYS_LIBRARY_PATH / GAUCHE_LOAD_PATH / GAUCHE_DYNLOAD_PATH as environment variables before configure / make / ... ? - as configure options ? - I am a bit at a loss here.

(I hope that my above explanations are reasonably clear: if you would follow them: you would run into the same dead end, I guess).

And some some advice is appreciated thus!

Thanks!

reuleaux commented 7 months ago

to summarise: for me the (installation) situation was easier, when both: the latest release (that I could install with get-gauche.sh) and git HEAD were at the same version (0.9.14 till recently): now that HEAD has moved forward to -p1, I cannot install HEAD any more. I see that one older -p1 version was also installable with get-gauche.sh, namely 0.9.11-p1

get-gauche.sh --list
....
0.9.11-p1
0.9.11

Maybe it would be possible to make 0.9.14-p1 get-gauche.sh installable as well? (other install suggestions / advice welcome, of course). In the worst case I will have to wait: for HEAD and the latest release being at the same version number again. - Thanks.

shirok commented 7 months ago

Hmm, that shouldn't be the case, I need to take a look. Meanwhile, I made 0.9.14-p1 available for get-gauche. Currently I need to package it manually, but maybe I can set up an automated process to make bleeding-edge nightly build available for get-gauche.

reuleaux commented 7 months ago

OK, thanks a lot: I will try with 0.9.14-p1 via get-gauche then next (and then I should be able to install HEAD as well) - That worked for me at least when both were at 0.9.14.

When you take the time then to take a closer look: I tried to write down my exact steps above in as clear a manner as possible (starting from a clean checkout etc.) - adjust them to your liking, of course: call my ~/opt/devgauche directory just targetdir etc. - The INSTALL.adoc and HACKING.adoc documents talk in general terms about how to proceed, but here is my step-by-step attempt to get from zero to a working HEAD gauche on Linux (maybe there is just some tiny parameter / config setting / env param missing somewhere?) Thanks again.

reuleaux commented 7 months ago

So I have been able to successfully install HEAD now (with first installing

./get-gauche.sh --version 0.9.14-p1 --auto --prefix ~/opt/devgauche 

and then

./configure --prefix ~/opt/devgauche --with-tls=none
make 
make check
make install

thanks!

And the attributes (Alpine.js examples) are rendered just fine!

Thanks again.

PS: I have edited this comment: originally I had issues still. - But that was my bad really: I had two servers running at the same time (one of them the older version still). - I hope, you got to see the right message: that everything is fine now, indeed. Many thanks, again.