with-extensions does not add native extensions to the load path

  • Open
  • quality assurance status badge
Details
3 participants
  • Ludovic Courtès
  • Z572
  • Tomas Volf
Owner
unassigned
Submitted by
Tomas Volf
Severity
normal
T
T
Tomas Volf wrote on 25 Nov 18:49 +0100
(address . bug-guix@gnu.org)
871pyzdwzi.fsf@wolfsden.cz
The documentation for `with-extensions' says:

Toggle quote (4 lines)
> In the same vein, sometimes you want to import not just pure-Scheme
> modules, but also “extensions” such as Guile bindings to C libraries
> or other “full-blown” packages.

However it does not actually add those C libraries into
(guile-extensions-path), which means that trying to actually use a
library imported this way will lead to an error.

I guess `load-path-expression' in (guix gexp) needs to also append to
the `guile-extensions-path' based on the search-paths of the imported
packages?

Reproduction is simple. Make sure you *do not* have guile-yamlpp
installed in your profile. Then build the `test' into a store item.

Toggle snippet (6 lines)
(use-modules (gnu packages guile-xyz))
(define test
(with-extensions (list guile-yamlpp)
(program-file "test" #~(use-modules (yamlpp)))))

And try to run it:

Toggle snippet (39 lines)
$ /gnu/store/nq0sahcnph5sxms4irq4inv2hq2hfbzr-test
Backtrace:
19 (primitive-load "/gnu/store/nq0sahcnph5sxms4irq4inv2hq2hfbzr-test")
In ice-9/eval.scm:
721:20 18 (primitive-eval _)
In ice-9/psyntax.scm:
1229:36 17 (expand-top-sequence _ _ _ #f _ _ _)
1221:19 16 (parse _ (("placeholder" placeholder)) ((top) #(ribcage () () ())) _ e (eval) #)
259:10 15 (parse _ (("placeholder" placeholder)) (()) _ c&e (eval) (hygiene guile-user))
In ice-9/boot-9.scm:
3935:20 14 (process-use-modules _)
222:17 13 (map1 (((yamlpp))))
3936:31 12 (_ ((yamlpp)))
3327:17 11 (resolve-interface (yamlpp) #:select _ #:hide _ #:prefix _ #:renamer _ # _)
In ice-9/threads.scm:
390:8 10 (_ _)
In ice-9/boot-9.scm:
3253:13 9 (_)
In ice-9/threads.scm:
390:8 8 (_ _)
In ice-9/boot-9.scm:
3544:20 7 (_)
2836:4 6 (save-module-excursion _)
3564:26 5 (_)
In unknown file:
4 (primitive-load-path "yamlpp" #<procedure 7f405e4fd560 at ice-9/boot-9.scm:35…>)
In yamlpp.scm:
65:1 3 (_)
In unknown file:
2 (load-extension "libguile-yamlpp" "init")
In system/foreign-library.scm:
190:25 1 (load-foreign-library _ #:extensions _ #:search-ltdl-library-path? _ # _ # _ # …)
In unknown file:
0 (dlopen "libguile-yamlpp.so" 1)

ERROR: In procedure dlopen:
In procedure dlopen: file "libguile-yamlpp.so", message "libguile-yamlpp.so: cannot open shared object file: No such file or directory"

Have a nice day,
Tomas

--
There are only two hard things in Computer Science:
cache invalidation, naming things and off-by-one errors.
-----BEGIN PGP SIGNATURE-----

iQJCBAEBCgAsFiEEt4NJs4wUfTYpiGikL7/ufbZ/wakFAmdEuMEOHH5Ad29sZnNk
ZW4uY3oACgkQL7/ufbZ/wanAZQ//X6YPkDpbrYK/OljWuxU70D6EC9+jQTkv1I4V
3mofSAWGP/D2PTFr5A+2lyLDKmzu68HqP+KNiRSjXBFwxr5hot50ZDNKPZdNc4My
elkVUgUmYYVzO33Zyu+nZYsXjZO4B7JzylMOsJ0QbxCSI3aOF9NPeP6h7TN+ReJi
B22XDz+gXOMJNFYBsUMSAK/ZvSyejenr8yTLQ1/EO+IVHV+dC8qeHSlMGPX2rm90
fCA0YHPlK5pEql4osigorvevsihONEyfKENCIZ0p2gg2MWsHAEHNteqy2KGFrwjB
WC9rQgtbekwvHJcEf1FSL7W/CQRCUc6Zrn1of4D0WQ1hoOS2HTyre9Peny8j453G
AYFDZw6Iq4KZG7Som4R0ME7sQNGoMpV1Il5JJcPEr2TFF2xpm4tGLPWBYKrBSa1M
FLU2vBzbI9GC0L3f3pKEojPI47eY3OjMp5nRYALr32S5xXOn/TrJQMMyXIUX0M7G
aip8e9l5UK0r76AgDaaou7Vqpx622JIVn8PvOZ5RfOsiJ0tXWGW6ZG2VV6Iv2/KY
hl+Ozars2cZXk/JAVgbA2HZ/9oi3CloFFfO6pKLkXfVo5Jl/Me2dcI2rPOeKAtnw
vC5UqsEjErXfjpI1CKtqaww5JoZM52dslbk8RzczbyUJN5HhNkuOG2sSXKI47kYb
A45WS50=
=LC0N
-----END PGP SIGNATURE-----

L
L
Ludovic Courtès wrote on 28 Nov 08:54 +0100
(address . 74532@debbugs.gnu.org)
877c8n94kl.fsf@gnu.org
Hi,

Tomas Volf <~@wolfsden.cz> skribis:

Toggle quote (6 lines)
> The documentation for `with-extensions' says:
>
>> In the same vein, sometimes you want to import not just pure-Scheme
>> modules, but also “extensions” such as Guile bindings to C libraries
>> or other “full-blown” packages.

It’s not just bindings but also pure Scheme libraries like Guile-JSON.

Toggle quote (4 lines)
> However it does not actually add those C libraries into
> (guile-extensions-path), which means that trying to actually use a
> library imported this way will lead to an error.

[...]

Toggle quote (7 lines)
> 190:25 1 (load-foreign-library _ #:extensions _ #:search-ltdl-library-path? _ # _ # _ # …)
> In unknown file:
> 0 (dlopen "libguile-yamlpp.so" 1)
>
> ERROR: In procedure dlopen:
> In procedure dlopen: file "libguile-yamlpp.so", message "libguile-yamlpp.so: cannot open shared object file: No such file or directory"

Usually, packages like these (guile-gnutls, guile-git, guile-ssh, etc.)
have their .so absolute file name hard-coded, which sidesteps this
problem entirely. I recommend doing that for guile-yamlpp as well.

That said, it would probably make sense to arrange for ‘with-extensions’
to set GUILE_EXTENSIONS_PATH.

Ludo’.

PS: Your MUA sets “Mail-Followup-To: bug-guix@gnu.org”, which is kinda
annoying because that’s the wrong address when replying to a bug.
:-)
T
T
Tomas Volf wrote on 3 Dec 00:40 +0100
(name . Ludovic Courtès)(address . ludo@gnu.org)(address . 74532@debbugs.gnu.org)
87plm93b7p.fsf@wolfsden.cz
Ludovic Courtès <ludo@gnu.org> writes:

Toggle quote (12 lines)
> Hi,
>
> Tomas Volf <~@wolfsden.cz> skribis:
>
>> The documentation for `with-extensions' says:
>>
>>> In the same vein, sometimes you want to import not just pure-Scheme
>>> modules, but also “extensions” such as Guile bindings to C libraries
>>> or other “full-blown” packages.
>
> It’s not just bindings but also pure Scheme libraries like Guile-JSON.

True, and for those it works well. However the text documentation
explicitly mentions "bindings to C libraries" as one of the use
cases. :)

Toggle quote (18 lines)
>
>> However it does not actually add those C libraries into
>> (guile-extensions-path), which means that trying to actually use a
>> library imported this way will lead to an error.
>
> [...]
>
>> 190:25 1 (load-foreign-library _ #:extensions _ #:search-ltdl-library-path? _ # _ # _ # …)
>> In unknown file:
>> 0 (dlopen "libguile-yamlpp.so" 1)
>>
>> ERROR: In procedure dlopen:
>> In procedure dlopen: file "libguile-yamlpp.so", message "libguile-yamlpp.so: cannot open shared object file: No such file or directory"
>
> Usually, packages like these (guile-gnutls, guile-git, guile-ssh, etc.)
> have their .so absolute file name hard-coded, which sidesteps this
> problem entirely. I recommend doing that for guile-yamlpp as well.

How it that usually done? I cannot do that *before* build, because then
tests would not run (the library is not yet installed into the absolute
path), and I cannot do it after, because I would need to rebuild the .go
files after patching the source code.

Assuming I have a guile library that creates a new .so library during
the build, and the .so library must be loadable by the other modules in
the library during the build (and for the tests), how should I approach
that?

I am pretty sure I cannot just patch the source code, since the library
would not be installed into the absolute path yet during the build.

Honestly, setting GUILE_EXTENSIONS_PATH via pre-inst-env seemed like
fairly elegant solution.

Toggle quote (4 lines)
>
> That said, it would probably make sense to arrange for ‘with-extensions’
> to set GUILE_EXTENSIONS_PATH.

That would be great. My current work-around is

(with-extensions (list guile-wolfsden)
(program-file
"audio-cycle-sinks"
#~(begin
;; Bug 74532: Native extensions are not added to the load path.
(eval-when (expand load eval)
(let ((ext-path (@ (system foreign-library) guile-extensions-path)))
;; Just a temporary hack, we can live with duplicates in the path.
(ext-path (cons #$(file-append guile-wolfsden
"/lib/guile/3.0/extensions")
(ext-path)))))
...)))

which is anything but elegant.

Toggle quote (7 lines)
>
> Ludo’.
>
> PS: Your MUA sets “Mail-Followup-To: bug-guix@gnu.org”, which is kinda
> annoying because that’s the wrong address when replying to a bug.
> :-)

Thanks for letting me know, I was not aware of that. After reading
(message)Mailing Lists bit more carefully, adjusting the Posting Styles
and sending a bug fix to the Emacs' bug tracker, I believe it should not
happen anymore. Sorry for the annoyance.

--
There are only two hard things in Computer Science:
cache invalidation, naming things and off-by-one errors.
-----BEGIN PGP SIGNATURE-----

iQJCBAEBCgAsFiEEt4NJs4wUfTYpiGikL7/ufbZ/wakFAmdORXoOHH5Ad29sZnNk
ZW4uY3oACgkQL7/ufbZ/walAqhAAjpE/KuhL/q5vv67k0zndvpQD3ExmofQYZTuq
NOTaYd6Y/1YfqChTbslTBU4W1J3NdJ7P1N/q0X8DhLg6mxYkakri2WJSGTP4H0nF
lo+RbDyas7aaIu9DrnlM4LzqWARbXFrbP5wMUhXBif9JsfO/AtRXZECUlQrYCYLo
t5nO354y0dhb4M0kRXnxbq6ray2HRWzar0SLDkRJIu9ChsJePta1z1IZbW1GpHhS
U9em2Tx84QTnM7S51wLPKGczgAiNc3vQZhxPX6R9ZuO4989Fl4zLuaaGKo34QY11
I5kuCuAO4sOoel562Rj2KXIJ0Bb/n9hXKHuhXrch+5hPobi7Yn4Eb96QW216KccW
JaZwy5fbqpG96jZm27PWuBDRUq+wz2rbb5PTkiSKj4ev+nbPelIEf7ULsilLk0vZ
6h0mEu/XHYpbbIEZls1vAUqP1pxjeF1VFDHWa/TL/HG/QGlakNWnHIPYbIAdXK3m
Gfymj8MfajZoiSNYans/ZQAb4QmxkoTfZEl6+AKzcgyrLjx6MqZQinCiWJyO/eQD
M5Nxj5jkJIvIe41tH541fb6In9t5+8rXF5DeWVgg9Tpd0Y1ep9Fiakx5sVBtI/F3
KCxtXsS52DuAGGfDTo0A8UAcyvqpZt3Ii0MAejM4Hbie764XKuJoRat9a+OtHFjC
OHP0wj4=
=RJ63
-----END PGP SIGNATURE-----

Z
(name . Tomas Volf)(address . ~@wolfsden.cz)
87y10x4g2w.fsf@iscas.ac.cn
Tomas Volf <~@wolfsden.cz> writes:

Toggle quote (41 lines)
> Ludovic Courtès <ludo@gnu.org> writes:
>
>> Hi,
>>
>> Tomas Volf <~@wolfsden.cz> skribis:
>>
>>> The documentation for `with-extensions' says:
>>>
>>>> In the same vein, sometimes you want to import not just pure-Scheme
>>>> modules, but also “extensions” such as Guile bindings to C libraries
>>>> or other “full-blown” packages.
>>
>> It’s not just bindings but also pure Scheme libraries like Guile-JSON.
>
> True, and for those it works well. However the text documentation
> explicitly mentions "bindings to C libraries" as one of the use
> cases. :)
>
>>
>>> However it does not actually add those C libraries into
>>> (guile-extensions-path), which means that trying to actually use a
>>> library imported this way will lead to an error.
>>
>> [...]
>>
>>> 190:25 1 (load-foreign-library _ #:extensions _ #:search-ltdl-library-path? _ # _ # _ # …)
>>> In unknown file:
>>> 0 (dlopen "libguile-yamlpp.so" 1)
>>>
>>> ERROR: In procedure dlopen:
>>> In procedure dlopen: file "libguile-yamlpp.so", message "libguile-yamlpp.so: cannot open shared object file: No such file or directory"
>>
>> Usually, packages like these (guile-gnutls, guile-git, guile-ssh, etc.)
>> have their .so absolute file name hard-coded, which sidesteps this
>> problem entirely. I recommend doing that for guile-yamlpp as well.
>
> How it that usually done? I cannot do that *before* build, because then
> tests would not run (the library is not yet installed into the absolute
> path), and I cannot do it after, because I would need to rebuild the .go
> files after patching the source code.

you can use substitute* to adjust source.
e.g.

(or (false-if-exception (load-extension "/path/to/lib-some-object-file.so"))
(load-extension "lib-some-object-file.so"))

Toggle quote (44 lines)
>
> Assuming I have a guile library that creates a new .so library during
> the build, and the .so library must be loadable by the other modules in
> the library during the build (and for the tests), how should I approach
> that?
>
> I am pretty sure I cannot just patch the source code, since the library
> would not be installed into the absolute path yet during the build.
>
> Honestly, setting GUILE_EXTENSIONS_PATH via pre-inst-env seemed like
> fairly elegant solution.
>
>>
>> That said, it would probably make sense to arrange for ‘with-extensions’
>> to set GUILE_EXTENSIONS_PATH.
>
> That would be great. My current work-around is
>
> (with-extensions (list guile-wolfsden)
> (program-file
> "audio-cycle-sinks"
> #~(begin
> ;; Bug 74532: Native extensions are not added to the load path.
> (eval-when (expand load eval)
> (let ((ext-path (@ (system foreign-library) guile-extensions-path)))
> ;; Just a temporary hack, we can live with duplicates in the path.
> (ext-path (cons #$(file-append guile-wolfsden
> "/lib/guile/3.0/extensions")
> (ext-path)))))
> ...)))
>
> which is anything but elegant.
>
>>
>> Ludo’.
>>
>> PS: Your MUA sets “Mail-Followup-To: bug-guix@gnu.org”, which is kinda
>> annoying because that’s the wrong address when replying to a bug.
>> :-)
>
> Thanks for letting me know, I was not aware of that. After reading
> (message)Mailing Lists bit more carefully, adjusting the Posting Styles
> and sending a bug fix to the Emacs' bug tracker, I believe it should not
> happen anymore. Sorry for the annoyance.
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEEfr6klGDOXiwIdX/bO1qpk+Gi3/AFAmdOdpcACgkQO1qpk+Gi
3/AJGw/8C1lFfLawGVgkxxSC9wDqqvLnhmkTuNgE088XfbvBWbL1T22yUT++X7rI
mqy8gDUf5m9Sjb3IWH31ghAcc6UN4yZNURWX/gktWQ++1X7tgic8HU+KHI4kp2YZ
bMSplp70yD91aAfqI/8kzqVaaaLIx2aq1x3HaD+Sq1nnZE4K7gbcXnAxSx9L8c8X
R0Xcn76R52IlhbZSjHtNcpGYKgldnS+DG70oQB2+yZBFo6WbIQGI2ZKoYfYp/Fin
LtUgU1b/MNSx3LNZU/p2e3HdvPzVFkk/0wh/0S3fBLRbVu/6eBysqKUAwAEe1KOi
t6irzc6AC+rkyd60Ua/uk2ejEAEiS8kV9tlNXvnmtQx6YBM0Y77TuzQTzz0qfui6
2FZROhmuPkAC2odSR5aoLjmXjALqKm6JzERzN57EDI5saLH7qpqg3HeECm7KnOQ4
sqpuzuFyQ8U2SJxLzdBIsJ6H5OvVWh4HexwDY18LRzvBpyjSPwLV4m/cqxbvTshI
Lz25LrF8CjtvTIsqI20OvF18oCBgbIWvRyJFmpQ5RQFW7Af55kBtyukGmXGzygpJ
xLDY1ZwricaVwmD1Srrq0F2W17fAgB9osFTgUR0ukV7WeMqAVWhn1jl4YW+7VvCq
GAoGErgqJ8Ljt35naE/gFl7fmCU7+1OvyqlZecZlWLU59P7YOC4=
=EYhI
-----END PGP SIGNATURE-----

T
T
Tomas Volf wrote on 13 Dec 17:44 +0100
(name . Z572)(address . zhengjunjie@iscas.ac.cn)
87o71flehy.fsf@wolfsden.cz
Hello,

Z572 <zhengjunjie@iscas.ac.cn> writes:

Toggle quote (12 lines)
>> How it that usually done? I cannot do that *before* build, because then
>> tests would not run (the library is not yet installed into the absolute
>> path), and I cannot do it after, because I would need to rebuild the .go
>> files after patching the source code.
>
> you can use substitute* to adjust source.
> e.g.
>
> (or (false-if-exception (load-extension "/path/to/lib-some-object-file.so"))
> (load-extension "lib-some-object-file.so"))
>

Thank you for the suggestion. I am not sure I like the
false-if-exception part, but temporary adjustment of the (@ (system
foreign-library) guile-extensions-path) should do the trick as well.

One thing I am curious about, I can see you have put the load from
absolute path as the first alternative. But if it fails, it still falls
back to lookup based on the guile-extensions-path. I wonder whether
putting it at the end of the list would not be better, that way you
could still replace the library in the spirit of LD_PRELOAD by setting
the appropriate environment variable. And if reproducibility is the
priority, then even the `or' might not make sense.

Any thoughts on that?

Thanks,
Tomas

--
There are only two hard things in Computer Science:
cache invalidation, naming things and off-by-one errors.
-----BEGIN PGP SIGNATURE-----

iQJCBAEBCgAsFiEEt4NJs4wUfTYpiGikL7/ufbZ/wakFAmdcZFkOHH5Ad29sZnNk
ZW4uY3oACgkQL7/ufbZ/wakTlg/9FoMOQ/oOx1tN0mrl3wwcTbbZh5MRX9XF5+v0
En5BCvWWuysmkC9nxS2YhS9GlEXV4qEc5pkfL8QbvcvcL2PYsxB/uIY5q+dJXVDl
5f+Be6e71ptlEz6Hk9/IWpPgj9/t+EixFfA4Q/XIsoxsy4b9KGrIlDJDQiX2R+h+
YM90uymr9gXj9lDZsn8J4gFEaQaVxLr6V7mCIRGVL2oobEVOPGnKwswAVarfhx6a
AdPGU3VCRezbn3D6NtFi2hrUXSfwpPNQ86VltBu6yS+2rBaYwI6f/fExJV+IZoDu
rekFf80wU9BEMwNJCNJPy5FvkAbqTNRRQ8ox9LnuDhlPTvFvYp9wjV7YVUqT1+1p
go/YUUyGu9Pko2WbW0oe0WbhEqWkFhMW39GteJ0P7C22KT9m/IY7E2kEp0+0rJ6B
bi1rZ862bvVQ0VQ8bIuVksCd5ZV5CsAnND4Y0gCv3QW/Uw2P7OjpG5g+puHOmwCH
tkuxB4kV+Qrpr+mY1sL6EQZqDWsdHzN0B1VKTI3MdGYnvUCoHibJcoYIhVe0aiWi
nIX+cyACJ8qNgluB9VM+9TqCLvnDuyJ0Lall+VZrfrybXoXAAlt+Snylm4iBPvb9
KrE7vzLEIGEMz3hvX3m/nG+qNI6vcdOL7MrE+JnWpwjMCwmMrxzeTsbshcbl3DmU
L4q8mgc=
=Jjva
-----END PGP SIGNATURE-----

L
L
Ludovic Courtès wrote on 17 Dec 14:55 +0100
(name . Tomas Volf)(address . ~@wolfsden.cz)
87bjxapg79.fsf@gnu.org
Hi,

Tomas Volf <~@wolfsden.cz> skribis:

Toggle quote (18 lines)
> Z572 <zhengjunjie@iscas.ac.cn> writes:
>
>>> How it that usually done? I cannot do that *before* build, because then
>>> tests would not run (the library is not yet installed into the absolute
>>> path), and I cannot do it after, because I would need to rebuild the .go
>>> files after patching the source code.
>>
>> you can use substitute* to adjust source.
>> e.g.
>>
>> (or (false-if-exception (load-extension "/path/to/lib-some-object-file.so"))
>> (load-extension "lib-some-object-file.so"))
>>
>
> Thank you for the suggestion. I am not sure I like the
> false-if-exception part, but temporary adjustment of the (@ (system
> foreign-library) guile-extensions-path) should do the trick as well.

I think you can just do:

(load-extension "/path/to/lib-some-object-file.so")

but you need to (1) do that in a post-install phase, and (2) re-run
‘make’ before ‘make install’ if necessary.

See ‘guile-gdbm-ffi’ as one example.

Ludo’.
?
Your comment

Commenting via the web interface is currently disabled.

To comment on this conversation send an email to 74532@debbugs.gnu.org

To respond to this issue using the mumi CLI, first switch to it
mumi current 74532
Then, you may apply the latest patchset in this issue (with sign off)
mumi am -- -s
Or, compose a reply to this issue
mumi compose
Or, send patches to this issue
mumi send-email *.patch