Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Actually eliminate the shell32.dll/ole32.dll dependency when LLVM is enabled #18108

Open
squeek502 opened this issue Nov 24, 2023 · 0 comments
Open
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase.

Comments

@squeek502
Copy link
Collaborator

squeek502 commented Nov 24, 2023

Follow up to #18091

Unfortunately, LLVMSupport.lib has its own dependencies on shell32's SHGetKnownFolderPath/SHFileOperationW and ole32's CoTaskMemFree:

which means that when building Zig with LLVM enabled, we inherit those dependencies and the slow process initialization returns, even if the shell32/ole32 functions aren't called. So, there's no actual gain in process initialization at all in status-quo Zig.

In the meantime, there is a potential avenue to explore with regards to -delayload which is what LLVM uses to avoid the process initialization cost of the shell32/ole32 dependency. I haven't put much effort into investigating this or if/how it could be utilized by Zig, but it might be possible. My naive attempt at building LLVM from source with MSVC and then building Zig with that didn't seem to get the -delayload to carry over, but again I didn't look too closely/try much of anything.

The -delayload approach can definitely work. I've got a proof-of-concept LLVM-enabled compiler without shell32.dll/ole32.dll dependencies built by doing the following:

  • Generating shell32.lib / ole32.lib via dlltool as outlined here: https://github.com/AustinWise/delay-load-mingw
    • shell32.def:
      EXPORTS
       SHGetKnownFolderPath
       SHFileOperationW
      
      • dlltool --input-def shell32.def --output-delaylib shell32.lib --dllname shell32.dll
    • ole32.def:
      EXPORTS
       CoTaskMemFree
      
      • dlltool --input-def ole32.def --output-delaylib ole32.lib --dllname ole32.dll
  • zig build -p stage4-debug -Denable-llvm -Dno-lib --verbose-link
    • Took the giant lld-link invocation and copied it into a .bat file
      • note: this relies on there being no spaces in any of the .lib paths; if any of the .lib filepaths have spaces you'll have to quote them
    • Replaced the path to shell32.lib and ole32.lib with the path to the .lib files generated by dlltool
    • Added -delayload:ole32.dll -delayload:shell32.dll to the command
    • Replaced the -OUT: path with a path outside of the cache directory, e.g. -OUT:C:\Users\Ryan\Programming\Zig\zig\build\zig-delayload.exe
  • Ran the batch file with lld-link in my PATH

The result:

No shell32.dll / ole32.dll

> dumpbin /DEPENDENTS /nologo ".\zig-delay.exe"

  Image has the following dependencies:

    ADVAPI32.dll
    KERNEL32.dll
    msvcrt.dll
    ntdll.dll
    WS2_32.dll
    CRYPT32.dll
    VERSION.dll

However, I have a feeling this might explode if the shell32/ole32 functions are called from within LLVM, as I think delayimp needs to be linked and it's not being linked currently. I was able to get the test in https://github.com/AustinWise/delay-load-mingw confirmed to work with clang and lld-link via:

clang -o testdelay-clang.exe testdelay.c -ldelayimp -lversion -Wl,-delayload:version.dll -fuse-ld=lld

but I think it's using delayimp.lib from MSVC.


Things that need to be figured out:

  • Need to confirm that the delayed loading part actually works, i.e. the shell32/ole32 functions within LLVM need to actually be called to ensure that the dlls get loaded properly and everything still works.
    • Need to figure out a way to get LLVM to call the relevant functions, or will need to write some custom code that calls e.g. home_directory
    • Alternatively, if it can be proven that the code paths in LLVM that call the shell32/ole32 functions cannot be reached from the Zig compiler, then we could scrap delayload and go with a simpler route of providing dummy symbols for the functions
  • Need to remove the dependency on dlltool to generate the .lib files
  • Need to support -delayload linker flags properly and use them when building the Zig compiler
  • Need to check that this solution works for both the gnu and msvc ABI targets, or make it work for both ABI targets
@squeek502 squeek502 added the enhancement Solving this issue will likely involve adding new logic or components to the codebase. label Nov 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase.
Projects
None yet
Development

No branches or pull requests

1 participant