<div dir="ltr"><div class="gmail_default" style="font-size:small">Thanks for the detailed explanation.  Makes sense now.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Jan 28, 2021 at 5:43 PM Nate DeSimone <<a href="mailto:nathaniel.l.desimone@intel.com">nathaniel.l.desimone@intel.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi There,<br>
<br>
First of all, welcome!<br>
<br>
So, “NULL” library classes are conceptually an "anonymous library". It enables one to statically link code into a module even if the module doesn't directly call functions in that library. All libraries, both regular libraries with a declared LibraryClass as well as these anonymous libraries, can publish both a constructor and a destructor. The EDK II build system will automatically generate a small amount of C code that invokes all library constructors before the entry point for the module is invoked, and all destructors after the entry point returns. This is useful for building statically linked plug-ins.<br>
<br>
I think my favorite example of this in-action is the UEFI Shell, here is what a typical DSC declaration for the UEFI Shell looks like:<br>
<br>
ShellPkg/Application/Shell/Shell.inf {<br>
  <PcdsFixedAtBuild><br>
    gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE<br>
  <LibraryClasses><br>
    NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf<br>
    NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf<br>
    NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf<br>
    NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf<br>
    NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf<br>
    NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf<br>
    NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf<br>
    NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf<br>
    ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf<br>
    HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf<br>
    BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf<br>
    ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf<br>
    ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf<br>
}<br>
<br>
If you take a look at ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf, you will see that the constructor for that anonymous library is named ShellLevel1CommandsLibConstructor(). Now, let's go and look at the definition for ShellLevel1CommandsLibConstructor() in ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.c and note the following code snippet:<br>
<br>
ShellCommandRegisterCommandName(L"stall",  ShellCommandRunStall   ...<br>
ShellCommandRegisterCommandName(L"for",    ShellCommandRunFor     ...<br>
ShellCommandRegisterCommandName(L"goto",   ShellCommandRunGoto    ...<br>
ShellCommandRegisterCommandName(L"if",     ShellCommandRunIf      ...<br>
ShellCommandRegisterCommandName(L"shift",  ShellCommandRunShift   ...<br>
ShellCommandRegisterCommandName(L"exit",   ShellCommandRunExit    ...<br>
ShellCommandRegisterCommandName(L"else",   ShellCommandRunElse    ...<br>
ShellCommandRegisterCommandName(L"endif",  ShellCommandRunEndIf   ...<br>
ShellCommandRegisterCommandName(L"endfor", ShellCommandRunEndFor  ...<br>
<br>
This library is installing new commands into the UEFI shell during its initialization procedure. This allows one to add custom commands to the shell as statically linked built-ins. A typical use case would be implementing platform specific diagnostic/recovery utilities.<br>
<br>
Hope that helps!<br>
Nate<br>
<br>
> From: <a href="mailto:devel@edk2.groups.io" target="_blank">devel@edk2.groups.io</a> <<a href="mailto:devel@edk2.groups.io" target="_blank">devel@edk2.groups.io</a>> On Behalf Of <a href="mailto:wonderfly@waymo.com" target="_blank">wonderfly@waymo.com</a><br>
> Sent: Thursday, January 28, 2021 10:22 AM<br>
> To: <a href="mailto:devel@edk2.groups.io" target="_blank">devel@edk2.groups.io</a><br>
> Subject: [edk2-devel] What is a "NULL" library class?<br>
> <br>
> Hi,<br>
> <br>
> I am super new to EDK2 development so excuse my ignorance.  While browsing the code base I find a lot places where the keyword "NULL" is used in place of a LibraryClass, specifically in DSC files.  For example,<br>
> in edk2/UefiPayloadPkg/UefiPayloadPkgIa32.dsc:                                                                       <br>
>   MdeModulePkg/Core/Dxe/DxeMain.inf {<br>
>     <LibraryClasses><br>
>       NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf<br>
>   }<br>
> <br>
> What does this mean?  Does it mean that the LzmaCustomDecompressLib.inf library instance is unconditionally linked for this package?<br>
> <br>
<br>
<br>
<br>
<br>
<br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div>Best,</div><div>Daniel</div></div></div>


 <div width="1" style="color:white;clear:both">_._,_._,_</div> <hr> Groups.io Links:<p>   You receive all messages sent to this group.    <p> <a target="_blank" href="https://edk2.groups.io/g/devel/message/70921">View/Reply Online (#70921)</a> |    |  <a target="_blank" href="https://groups.io/mt/80192232/1813853">Mute This Topic</a>  | <a href="https://edk2.groups.io/g/devel/post">New Topic</a><br>    <a href="https://edk2.groups.io/g/devel/editsub/1813853">Your Subscription</a> | <a href="mailto:devel+owner@edk2.groups.io">Contact Group Owner</a> |  <a href="https://edk2.groups.io/g/devel/unsub">Unsubscribe</a>  [edk2-devel-archive@redhat.com]<br> <div width="1" style="color:white;clear:both">_._,_._,_</div>