Beautiful discussion - this is one of the few things I find really awful about LabVIEW, and a thing I really really hope will change.
For deployment LVLIBP can work, but not for dev tools (which I do most of involving libs) as they need to be cross-platform and cross-version. LLBs are out of the question for me because they're so arcane. Everybody has mentioned all the pros and cons of these files except for one thing: Security.
I use LVLIBs for three features, here in the order of importance (for me):
2) Security against someone else replacing my code.
I wish LVLIBs also had this fourth feature:
4) Single file on disk.
Generally I can't get manual namespaces to work. The teams I work in aren't structured enough to adhere to one convention, and they are typically those middle-of-the-road programmers that have enough experience to boost their self confidence but not enough to make them put their egos aside and stick to the plan. Something like that. I want namespaces in LabVIEW, and I hate that I have to stick my VIs into a library to get that - or I hate what I must lug around as well when I just want namespaces.
Namespacing through the physical file name also has its advantages - one being that you can identify a VI's purpose without the context of its library. But namespacing in file names create long file names, and it creates long paths due to all the duplicate information (the file name being almost the sum of folders leading into the file location). And we have some limitation to maximum path length in characters when we build executables and load VIs dynamically (~230 chars IIRC).
For many applications it's unsafe if someone external to the dev team can just replace a file in your deployment and either change functionality or snoop into your code. Thus it's a great thing that libraries bind their members so tightly that this isn't possible.
I don't use this as much in LVLIBs, but I do in LVCLASSes.
But what about the load everything feature?
Besides the physical distrib size, the load time, and the mem usage issues, there is another really bad consequence of this: the "Only one file in memory with any given file name" feature.
I feel the "contract" that LabVIEW imposes on us that a library will be loaded into memory, always together with all its members, is the single thing that stands in the way of two distinct modules appending functions from the same namespace (LVLIB) into memory. This issue:
- You have A.lvlib that owns a.vi, b.vi, and 100 other VIs.
- Someone has built a source distrib, Module X, that uses a.vi of A.lvlib.
- Someone else has built another source distrib, Module Y, that uses b.vi of A.lvlib.
- Since both source distrib builders wanted their modules to be as small as possible they made their build script such that unused lib member functions were stripped from their build.
Now you make an application that must load Module X and Module Y, but it can't. Your app loads Module Y first, and Module Y loads A.lvlib into memory. This version of A.lvlib only has one VI in it, namely b.vi. Now your app attempts to load Module X, but Module X fails to load, as it can't load its own dependency a.vi. It's not allowed to do anything with its own copy of A.lvlib that references a.vi, as there is already a file called A.lvlib loaded.
I'd guess that everybody here has experienced the above and works around it on a regular basis. If LVLIBs weren't so atomic this issue could be fixed by allowing gradual loading of library member functions. Then Module Y would just load b.vi, and Module X would later load a.vi and merge the namespace. If on-request loading was supported that would already be built in. Of course there would need to be certain checksums etc, but you wouldn't have to jump through hoops to make several source distributions actually work together, with a potential rebuild of ALL modules when you add a new module.
Does it even matter for smaller reuse tools?
The opinion that the issues we're discussing here are only relevant for 8000 VI applications, and that we don't run into them on a daily basis, was aired (Neil perhaps?). I think this issue is an armed grenade from the first library we make - it might well first blow up later, but eventually we reuse something or stuff our lib into an executable that loads two modules, and then we're presented with two options, both of which cause tremendous headache: either 1) careful design and re-design of the application as it evolves, or 2) total redesign of our reuse components (and how much reuse is that?).
Case in point;
We (GPower) has a bunch of reuse libs for public download. They are GPArray.lvlib, GPMath.lvlib, GPString.lvlib, GPError.lvlib etc. These libs are used by many people around the world, so need namespacing as they are quite low-level and common. They are reuse tools that support a large number of LabVIEW datatypes, so they are also full of polyVIs with many many instances of almost identical functions just with different datatypes for inputs and outputs (also slight variations in realization, but that's not the heavy part). Not too big a deal on a lib by lib case, you hardly notice this in the IDE, even though some of the libs have maybe 200 VIs in them (they are small).
Now we've made a new toolset, Expression Parser, which uses ~10 of our own libs. When you drop the first VI from the Expression Parser toolset into your block diagram, LabVIEW loads almost 1200 VIs from disk! Why the h*** is it designed to do that? Expression Parser is also heavily inlined and recursive, so on most dev machines you notice - let's be frank. Afterwards everything is fine, but it's not necessary to load all that before you need it. Often times you won't even need 30 of those VIs. Building the VIP for Expression Parser takes around 20 minutes. Building an executable containing Expression Parser will never get below ~10 minutes. For those reasons. That is totally unecessary.
So, I use LVLIBS, but I hate them. I can't live with the alternatives currently though, so I jush push at NI all I'm able to, to get some of this moving in a slightly different direction. I hope it eventually will.