[00:27] *** Sgeo joined
[01:17] <apogee_ntv> Notcurses::Native done! Wow that was pain.

[01:53] *** kylese left
[01:53] *** hulk joined
[01:59] *** kybr joined
[01:59] <kybr> m: <0 1 2 3 4>.Set (-) <1 2 3>.Set

[01:59] <evalable6> kybr, rakudo-moar ab6efcab1: OUTPUT: «WARNINGS for /tmp/7ZDFvQH2Ht:␤Useless use of "(-)" in expression ".Set (-) <1 2 3>.Set" in sink context (line 1)␤»

[02:03] <kybr> m: say <0 1 2 3 4>.Set (-) <1 2 3>.Set

[02:03] <evalable6> kybr, rakudo-moar ab6efcab1: OUTPUT: «Set(0 4)␤»

[02:03] <kybr> m: say (^5).List.Set (-) <1 2 3>.Set

[02:03] <evalable6> kybr, rakudo-moar ab6efcab1: OUTPUT: «Set(0 1 2 3 4)␤»

[02:04] <kybr> m: say (^5).List.Set == <0 1 2 3 4>.Set

[02:04] <evalable6> kybr, rakudo-moar ab6efcab1: OUTPUT: «True␤»

[02:05] <kybr> what am i missing? why do the first two m: above have different answers?

[02:05] <apogee_ntv> Selkie now builds with no C compile chain on MacOS/Linux/Windows. Need glibc 2.35 for that to work on Linux.

[02:07] <apogee_ntv> (or higher)

[02:09] <kybr> m: <0 1 2 3 4>.Set.pick.WHAT

[02:09] <evalable6> kybr, rakudo-moar ab6efcab1: OUTPUT: «»

[02:10] <kybr> m: say <0 1 2 3 4>.Set.pick.WHAT

[02:10] <evalable6> kybr, rakudo-moar ab6efcab1: OUTPUT: «(IntStr)␤»

[02:10] <kybr> m: say (^5).List.Set.pick.WHAT

[02:10] <evalable6> kybr, rakudo-moar ab6efcab1: OUTPUT: «(Int)␤»

[02:15] *** hulk left
[02:15] *** kylese joined
[02:47] *** orangebot joined
[03:07] *** lichtkind__ joined
[03:10] *** lichtkind_ left
[03:18] *** orangebot left
[03:18] <apogee_ntv> And Vips::Native done.

[03:24] *** apogee_ntv left
[03:26] *** vasko4535586 left
[03:27] *** apogee_ntv joined
[03:32] *** vasko4535586 joined
[04:07] *** topnep left
[04:08] *** sibl joined
[04:08] *** topnep joined
[05:14] *** Aedil left
[05:18] *** Aedil joined
[06:12] *** topnep left
[06:13] *** topnep joined
[06:26] *** kybr left
[06:30] *** soverysour joined
[06:30] *** soverysour left
[06:30] *** soverysour joined
[06:30] *** abraxxa joined
[06:56] *** sibl left
[06:56] *** sibl joined
[07:00] *** Sgeo left
[07:20] *** soverysour left
[07:24] <patrickb> apogee_ntv: Do you have knowledge of how native library dependencies work on Windows?

[07:24] <patrickb> If so I'd like to have a chat.

[07:36] <apogee_ntv> patrickb: Some idea yes, I dont use Win but I build for it often

[07:45] *** sibl left
[07:45] *** sibl joined
[07:46] <patrickb> I've been pondering building a binaries store on top of vcpkg. 

[07:47] <patrickb> The vcpkg guys say, that it's a pretty bad idea. I'm still in the phase of gathering understanding of the problem domain.

[07:48] <patrickb> https://irclogs.raku.org/moarvm/2026-04-04.html#20:57

[07:48] <patrickb> This is my latest set of questions I'm wondering about.

[07:51] <patrickb> Libraries can depend on each other, so they form a graph. One can't have colliding symbols in a process. Is there a way to separate symbols in libraries I load? If so, then the issue of colliding symbols is not so big anymore.

[07:52] <patrickb> I've never heard of this issue in the context of native call yet. But I' kinda expect the issue to show up whenever I use multiple non trivial native call libraries on Windows, because each lib is usually provided with all dependencies included, so collisions should happen often.

[07:56] *** soverysour joined
[07:56] <patrickb> The answer to these questions influences how a vcpkg binary sore would be structured.

[07:56] <patrickb> The answer to these questions influences how a vcpkg binary sore would be structured. 

[07:58] <patrickb> Should the graph of all libraries (and their dependencies) be free of duplicates? Are multiple versions of the same dependency prohibited in the graph?

[08:00] *** soverysour left
[08:05] *** soverysour joined
[08:12] *** dakkar joined
[08:14] *** librasteve_ joined
[08:16] *** soverysour left
[08:18] <lizmat> m: dd <1 2 3>, (1,2,3)

[08:18] <evalable6> lizmat, rakudo-moar ab6efcab1: OUTPUT: «(IntStr.new(1, "1"), IntStr.new(2, "2"), IntStr.new(3, "3"))␤(1, 2, 3)␤»

[08:18] <lizmat> kybr ^^ that's what you're missing

[08:20] *** soverysour joined
[08:20] <librasteve_> kybr: I guess you have answered your own question on the behaviour of Set compare (which uses .WHICH to do the compare, like the `===` value identity operator

[08:20] <tellable6> librasteve_, I'll pass your message to kybr

[08:22] <librasteve_> oh and that angle bracket number literals `<>` make lovely Allomorphs like IntStr

[08:23] <disbot2> <librasteve> ah - seems that I was too late ;-)

[08:38] *** sp1983_ joined
[08:47] *** sibl left
[09:03] *** soverysour left
[09:06] *** soverysour joined
[09:13] *** sibl joined
[09:26] <apogee_ntv> patrickb: I've been mostly building on msys2 to be honest, the compile chain is much nicer to run.

[09:27] <apogee_ntv> If you look at the GitHub Actions for Notcurses::Nativecall, the build process is absolutely cursed.

[09:27] <apogee_ntv> But it works.

[09:27] <apogee_ntv> Notcurses::Native

[09:31] *** Guest66 joined
[09:31] *** Guest66 left
[09:33] <apogee_ntv> For your question about symbol collision, you have the general broad strokes right yes but there's a lot of nuance. Each DLL has its own namespace, so if you have i.e. two SSL dlls exporting 'do_ssl_handshake', the loader won't confuse those because in one place you're calling GetProcAddress('openssl', 'do_ssl_handshake') and in the other you're calling GetProcAddress('libressl', 'do_ssl_handshake').

[09:35] <Geth> ¦ CCR/main: 900bc7574a | (Elizabeth Mattijsen)++ | 2 files

[09:35] <Geth> ¦ CCR/main: Collect and conserve Tom Browder's own blog

[09:35] <Geth> ¦ CCR/main: review: https://github.com/Raku/CCR/commit/900bc7574a

[09:35] *** sibl left
[09:36] *** sibl joined
[09:39] <apogee_ntv> The issue comes when you try to load 2 DLLs with the same name on the same search path. You can avoid it by making sure your DLLs have different names and are called by name (i.e. 'openssl-2.0.0.dll' and 'openssl-2.1.3.dll' will not have namespace collisions) or you can create per module sibling directory (Windows DLLs automatically look for siblings in same folder so i.e. you'd have

[09:39] <apogee_ntv> %PATH%\GTK-Simple\lib and %PATH\OpenSSL\lib each with their own openssl.dll and they wont collide).

[09:39] <apogee_ntv> If you look at Notcurses::Native and Vips::Native build process this is how I solve it, using sibling detection.

[09:43] <apogee_ntv> The way Linux solves this is via .so.6.2.1 vs .so.6.6.7 naming convention, the same underlying problem exists but there are stronger standard practices. dlopen is actually worse in some ways because you can flatten symbol imports with RTLD_GLOBAL as an aside.

[09:45] <apogee_ntv> Hope that helps.

[09:47] <apogee_ntv> (if you use MSYS2, it uses linux-style naming convention which also helps for disambiguation)

[09:47] *** sp1983_ left
[09:48] *** sp1983_ joined
[10:05] *** sibl left
[10:23] *** topnep left
[10:26] *** topnep joined
[10:40] *** sibl joined
[10:43] *** sp1983_ left
[10:48] *** soverysour left
[10:52] *** librasteve_ left
[10:53] *** sp1983_ joined
[10:53] <patrickb> That helps a lot, thanks!

[10:54] <patrickb> I'm exclusively aiming for Windows at the moment, because on Linux distros go a long way already. 

[10:54] <apogee_ntv> No problem, if you run into any issues feel free to ping me but definitely check the build process for Notcurses::Native and Vips::Native because I use those together and they ship some of the same dlls and no issues.

[10:55] <patrickb> So an actually working approach would be to isolate each vcpkg package and bundle the full dependency tree in each.

[10:55] <patrickb> That would sidestep all of that hard problems at once.

[10:55] <apogee_ntv> tbh Windows isn't necessarily worse than Linux for this, it's just different. Yeah you would isolate each and make sure the DLLs are siblings. Windows resolves dependencies sibling-first so if they're all in the same folder for a given package they will resolve the correct deps.

[10:56] <apogee_ntv> Thats how Steam works

[10:56] <apogee_ntv> A lot of games ship the same DLLs at different versions, each game has its own lib directory.

[10:56] <patrickb> Wow. I didn't expect the solution to be this straight forward.

[10:57] <apogee_ntv> I have writing a NativeCall for non-C Devs book on my TODOs lol.

[10:57] <apogee_ntv> I use it a lot with complex dependency chains.

[10:57] <patrickb> So whenever an update happens to any package in vcpkg, I just rebuilt that package and all dependees and I'm done.

[10:58] <patrickb> Thank you very much!

[10:58] <apogee_ntv> Yeah you would remove %APPDATA%/Your Package Manager/Module-0.1.1 and create %APPDATA%/Your Package Manager/Module-0.1.2 (or wherever you decide to install to).

[11:00] <apogee_ntv> And the module would need to know where to resolve to.

[11:03] <apogee_ntv> I install everything to %*ENV<XDG_DATA_HOME>/{{moduleName}}/$binary-tag/lib".IO because zef doesn't guarantee sibling DLLs and that can cause an issue if i.e. you vendor ffmpeg and there's ffmpeg DLLs on the system search path which aren't ABI-compatible.

[11:05] <apogee_ntv> i.e. Notcurses links against ffmpeg, so my Nativecall isn't resolving it directly (I'm not binding ffmpeg). So notcurses has to see those DLLs as siblings to avoid system search path.

[11:05] <apogee_ntv> zef renames all your DLLs which breaks this lookup.

[11:06] <apogee_ntv> https://github.com/m-doughty/Notcurses-Native/blob/9e8b89245b87ed2dc547a27739a3c82bba952114/Build.rakumod#L117 So I just do this which is a fairly common pattern outside of Raku.

[11:07] <apogee_ntv> https://github.com/m-doughty/Notcurses-Native/blob/9e8b89245b87ed2dc547a27739a3c82bba952114/lib/Notcurses/Native.rakumod#L40 And then this on the loading side.

[11:15] <patrickb> Understood! Actually I had always planned to create a vcpkg binary package store / installer independent of Raku. So I'd have installed the module to a separate place in any case.

[11:15] <patrickb> I didn't put much thought into how to make raku actually find those libs. I just guessed that this is probably only a simple matter of programming.

[11:16] <apogee_ntv> Yeah I dont know much about vcpkg to be honest, that part's outside my domain of knowledge.

[11:16] <apogee_ntv> Your Raku packages would need to know to check the dir you install DLLs to.

[11:18] <patrickb> That's fine. It's basically theost complete and maintained collection of native libraries packaged for Windows (via build recepes)

[11:18] <patrickb> *the most

[11:18] <apogee_ntv> Ah OK, yeah I use msys2 and its repository extensively for windows

[11:19] <patrickb> They don't provide binary packages though. 

[11:19] <apogee_ntv> They do but you need to rebuild as static linked to whatever dep you're relying on.

[11:19] <apogee_ntv> They provide dynamic linked binaries because they're smaller.

[11:20] <apogee_ntv> I use Github actions to build statically linked binaries

[11:20] <patrickb> "They" refers to msys2, correct?

[11:20] <apogee_ntv> Yes

[11:20] <apogee_ntv> https://github.com/m-doughty/Notcurses-Native/blob/master/.github/workflows/build-binaries.yml

[11:22] <apogee_ntv> https://github.com/m-doughty/Notcurses-Native/blob/9e8b89245b87ed2dc547a27739a3c82bba952114/.github/workflows/build-binaries.yml#L337 I install windows binaries from msys2 here.

[11:25] <apogee_ntv> https://github.com/m-doughty/Notcurses-Native/blob/9e8b89245b87ed2dc547a27739a3c82bba952114/.github/workflows/build-binaries.yml#L38 Define build tags here to build static

[11:25] <apogee_ntv> (Build type release)

[11:26] <apogee_ntv> https://github.com/m-doughty/Notcurses-Native/blob/9e8b89245b87ed2dc547a27739a3c82bba952114/.github/workflows/build-binaries.yml#L367 And then this bundles everything.

[11:32] <apogee_ntv> ldd on clang64 msys2 on aarch64 is flaky so it's absolutely cursed

[11:33] <patrickb> Yeah, I've seen the workarounds you put in place.

[11:33] <apogee_ntv> on x64 that build process is much simpler

[11:33] <apogee_ntv> Its purely aarch64 that makes it complicated

[11:34] *** sp1983_ left
[11:40] *** oodani left
[11:41] *** oodani joined
[11:41] *** oodani left
[11:42] *** oodani joined
