Raku / doc

🦋 Raku documentation
https://docs.raku.org/
Artistic License 2.0
290 stars 291 forks source link

Special platform-independent handling of 'libraries/' resource hard to find #4343

Open dwarring opened 1 year ago

dwarring commented 1 year ago

Problem or new feature

There's a nifty feature regarding special platform-independent handling of resources within the libraries directory.

To quote from this 2016 advent post.

"If the first path part of the content-id is “libraries/” then any path under it will have its name mangled to whatever naming convention rakudo thinks is right for the OS it is running on. This can be useful for distributions that compile/generate libs at build time and expect to be named a certain way; libraries/mylib.dll on windows, libraries/libmylib.so on linux, and libraries/libmylib.1.so on OSX. This allows you to reference this library in a (probably NativeCall) module as %?RESOURCES instead of guessing if its %?RESOURCES or %?RESOURCES".

I can't see it clearly documented anywhere. I'd expect it to be document in NativeCall, or maybe Modules.

Suggestions

At a mention, and maybe an example to the nativecall documentation. There's some reasonable examples in the ecosystem, e.g. Digest::SHA1::Native.

See below

dwarring commented 1 year ago

Found Distribution::Resource, which describes the special handling of libraries and includes an example META6.

Possibly, the modules documentation, just needs to mention libraries for dynamic libraries and link to distribution resources for more explanation and an example.

coke commented 1 year ago

@ugexe, any pointers?

ugexe commented 1 year ago

libraries/ handling is based on $*VM.platform-libraryname(...). See the following script to see what a given name would translate to:

# MacOS
$ raku -e 'sub MAIN($name) { say $*VM.platform-library-name($name.IO) }' foo
"libfoo.dylib".IO

# Linux
$ raku -e 'sub MAIN($name) { say $*VM.platform-library-name($name.IO) }' foo
"libfoo.so".IO

# Windows
$ raku -e 'sub MAIN($name) { say $*VM.platform-library-name($name.IO) }' foo
"foo.dll".IO

So assume someone has libraries/foo in their META6.json resources. When one does %?RESOURCES<libraries/foo> it will reference whatever platform specific file is shown in the example above. This means you can write your make files to compile libraries and then move them to resources/libaries. When you want to reference them via something like is native(...) you can do is native(%?RESOURCES<libraries/foo>) instead of trying to figure out if you need to do is native(%?RESOURCES<libraries/libfoo.so>, is native(%?RESOURCES<libraries/foo.dll>), etc.

libraries/ is the only resources folder that behaves this way; other resources are accessed via the exact file name (extension and all).