上一篇Blog介绍了exe的生成,从C 到 exe可以通过“cl /c”来编译到“obj”,然后再“link”到exe。如果用到其他lib的话,还需要用“/I<dir> add to include search path”来添加相应的lib文件。
这里我们写了一个最精简的Pkg,里面有个最精简的UEFI app,用来探究C文件到EFI文件的过程。这个UEFI app 代码只有“Hello.inf”和“Hello.c”两个文件,使用了最少的lib,以方便看流程:
#include <Uefi.h>
EFI_STATUS
EFIAPI
Main (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
return EFI_SUCCESS;
}
用“build > log.txt”可以把build log记录下来分析,log里面跟这个app相关的命令有以下几条:
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Vc\bin\cl.exe" /Fod:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\OUTPUT\.\Hello.obj /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Id:\udk2017_25818\AppPkgSample\Hello /Id:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG /Id:\udk2017_25818\MdePkg /Id:\udk2017_25818\MdePkg\Include /Id:\udk2017_25818\MdePkg\Include\Ia32 d:\udk2017_25818\AppPkgSample\Hello\Hello.c
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Vc\bin\cl.exe" /Fod:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\OUTPUT\.\AutoGen.obj /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Id:\udk2017_25818\AppPkgSample\Hello /Id:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG /Id:\udk2017_25818\MdePkg /Id:\udk2017_25818\MdePkg\Include /Id:\udk2017_25818\MdePkg\Include\Ia32 d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG\AutoGen.c
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Vc\bin\lib.exe" /NOLOGO /LTCG /OUT:d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\OUTPUT\Hello.lib @d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\OUTPUT\object_files.lst
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Vc\bin\link.exe" /OUT:d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG\Hello.dll /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:_ModuleEntryPoint /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data @d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\OUTPUT\static_library_files.lst
"GenFw" -e UEFI_APPLICATION -o d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG\Hello.efi d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG\Hello.dll
这个过程就是EFI编译的过程,我们来分析每一步的意义,每一个命令接收了什么东西,产出了什么东西,都要搞清楚。
第一步:命令"cl.exe",输入:Hello.c,输出:Hello.obj. 主要参数:/Fo 生成obj文件,/c 只编译不链接,/I 设定搜索目录。如下:
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Vc\bin\cl.exe" /Fod:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\OUTPUT\.\Hello.obj /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Id:\udk2017_25818\AppPkgSample\Hello /Id:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG /Id:\udk2017_25818\MdePkg /Id:\udk2017_25818\MdePkg\Include /Id:\udk2017_25818\MdePkg\Include\Ia32 d:\udk2017_25818\AppPkgSample\Hello\Hello.c
第二步:命令"cl.exe",输入:AutoGen.c,输出:AutoGen.obj ,如下:
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Vc\bin\cl.exe" /Fod:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\OUTPUT\.\AutoGen.obj /nologo /arch:IA32 /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1b2 /GL /FIAutoGen.h /EHs-c- /GR- /GF /Id:\udk2017_25818\AppPkgSample\Hello /Id:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG /Id:\udk2017_25818\MdePkg /Id:\udk2017_25818\MdePkg\Include /Id:\udk2017_25818\MdePkg\Include\Ia32 d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG\AutoGen.c
第三步:命令"lib.exe",输入:Hello.obj&AutoGen (见objobject_files.lst),输出:Hello.lib。如下:
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Vc\bin\lib.exe" /NOLOGO /LTCG /OUT:d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\OUTPUT\Hello.lib @d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\OUTPUT\object_files.lst
其中,object_files.lst内容如下,可见用到了第一步的Hello.obj和第二步的AutoGen.obj:
d:/udk2017_25818/Build/AppPkgSample/RELEASE_VS2013x86/IA32/AppPkgSample/Hello/Hello/OUTPUT/Hello.obj
d:/udk2017_25818/Build/AppPkgSample/RELEASE_VS2013x86/IA32/AppPkgSample/Hello/Hello/OUTPUT/AutoGen.obj
第四步:命令"link.exe",输入:“static_library_files.lst”里面的lib文件,输出:Hello.dll。如下:
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Vc\bin\link.exe" /OUT:d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG\Hello.dll /NOLOGO /NODEFAULTLIB /IGNORE:4001 /IGNORE:4254 /OPT:REF /OPT:ICF=10 /MAP /ALIGN:32 /SECTION:.xdata,D /SECTION:.pdata,D /MACHINE:X86 /LTCG /DLL /ENTRY:_ModuleEntryPoint /SUBSYSTEM:EFI_BOOT_SERVICE_DRIVER /SAFESEH:NO /BASE:0 /DRIVER /MERGE:.rdata=.data @d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\OUTPUT\static_library_files.lst
其中,static_library_files.lst内容如下,可见用到了第三步生成的Hello.lib:
d:/udk2017_25818/Build/AppPkgSample/RELEASE_VS2013x86/IA32/MdePkg/Library/BaseMemoryLib/BaseMemoryLib/OUTPUT/BaseMemoryLib.lib
d:/udk2017_25818/Build/AppPkgSample/RELEASE_VS2013x86/IA32/MdePkg/Library/BasePcdLibNull/BasePcdLibNull/OUTPUT/BasePcdLibNull.lib
d:/udk2017_25818/Build/AppPkgSample/RELEASE_VS2013x86/IA32/MdePkg/Library/BaseLib/BaseLib/OUTPUT/BaseLib.lib
d:/udk2017_25818/Build/AppPkgSample/RELEASE_VS2013x86/IA32/MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull/OUTPUT/BaseDebugLibNull.lib
d:/udk2017_25818/Build/AppPkgSample/RELEASE_VS2013x86/IA32/MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib/OUTPUT/UefiBootServicesTableLib.lib
d:/udk2017_25818/Build/AppPkgSample/RELEASE_VS2013x86/IA32/MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint/OUTPUT/UefiApplicationEntryPoint.lib
d:/udk2017_25818/Build/AppPkgSample/RELEASE_VS2013x86/IA32/AppPkgSample/Hello/Hello/OUTPUT/Hello.lib
第五步:命令"GenFw",输入:Hello.dll,输出:Hello.efi。如下:
"GenFw" -e UEFI_APPLICATION -o d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG\Hello.efi d:\udk2017_25818\Build\AppPkgSample\RELEASE_VS2013x86\IA32\AppPkgSample\Hello\Hello\DEBUG\Hello.dll