KyleMayes / clang-sys

Rust bindings for libclang.
Apache License 2.0
128 stars 65 forks source link

Static Linking clang_sys on msvc/windows cannot find libraries, e.g. libclang.lib #184

Open Cody-Duncan opened 3 weeks ago

Cody-Duncan commented 3 weeks ago

I ran into a bunch of problems to get clang_sys statically linking with binaries built via msvc on Windows Documenting the found issues here for a future fix.


Process to get static linking on clang 18.1.7

Stage 1: cmake configuration

Configuring cmake on llvm using the generator "Visual Studio 17 2022", requires that LLVM_ENABLE_PIC also be turned off. Otherwise, it unsets LIBCLANG_BUILD_STATIC and builds shared DLL libraries. -DLIBCLANG_BUILD_STATIC=ON -DLLVM_ENABLE_PIC=OFF

Cmake configure command: cmake -G "Visual Studio 17 2022" -A x64 -T host=x64 -DLLVM_TARGETS_TO_BUILD=X86 -DLIBCLANG_BUILD_STATIC=ON -DLLVM_ENABLE_PIC=OFF -S <path/to/llvm-project>/llvm -B <build_dir>

Then built the binaries in configuration RelWithDebInfo|x64. devenv.com LLVM.sln /Build "RelWithDebInfo|x64"

Followed by cmake install command: cmake --install <build_dir> --prefix <install_dir> --config RelWithDebInfo

Stage 2: Environment Variables

Created .cargo/config.toml containing

[env]
LLVM_CONFIG_PATH = '<install_dir>/bin/llvm-config.exe'
#LIBCLANG_PATH = '<install_dir>/bin/libclang.dll'
LIBCLANG_STATIC_PATH = '<install_dir>/lib/libclang.lib'
CLANG_PATH = '<install_dir>/bin/clang.exe'

Stage 3: fixing build/static.rs link() to find libraries

Problem: Could not find libclang.lib

Fix: changed get_clang_libraries() to switch the glob based on platform.

Problem: Could not find clang.lib.

Fix: removed get_library_name() call in get_clang_libraries(). Replaced it so it returned the filename libclang.lib

Problem: Unresolved external symbols (huge list here)

Fix: added logic to get_clang_libraries() so it returned libclang.lib and any clang*.lib libraries in the <install>/lib directory.

Problem: Unresolved external symbol GetFileVersionInfoSizeW + 2 more.

Fix: Added the appropriate cargo:rustc-link-search=C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64 and cargo:rustc-link-lib=static=Version printlns at the end of link(). Caveat: I just hard-coded just to see if it will work. Need to find a more generic way to find Version.lib.

complete

And now it compiles and tests succeed with static linking.

Workflow Notes:

Need to compile using cargo test --features static -vv