CMake falsely executes commands inside of if

Issue

I wanted to build LLVM from source with LibXml2 on Windows.
The easiest option for LibXml2 was to use vcpkg.
I am using a pull request (see Reproduction), which integrates LibXml2 upstream CMake support.
The problem that I am currently facing is that configuring of LLVM fails with the following error:

CMake Error at E:/git/vcpkg/installed/x64-windows-static/share/libxml2/vcpkg-cmake-wrapper.cmake:41 (target_link_libraries):
  Cannot specify link libraries for target "LibXml2::LibXml2" which is not
  built by this project.
Call Stack (most recent call first):
  E:/git/vcpkg/scripts/buildsystems/vcpkg.cmake:815 (include)
  E:/git/llvm-project/clang/CMakeLists.txt:207 (find_package)


-- Configuring incomplete, errors occurred!
See also "E:/git/llvm-project/build/CMakeFiles/CMakeOutput.log".
See also "E:/git/llvm-project/build/CMakeFiles/CMakeError.log".

The problem indicates that detecting LibXml2 by Clang (a submodule of LLVM) fails. The weird thing is that LibXml2 was correctly detected by the LLVM CMakeLists.

The code that failes looks like this:

if(TARGET LibXml2::LibXml2)
   target_link_libraries(LibXml2::LibXml2 INTERFACE ${ICONV_LIBRARIES})

This tells me that there is probably a bug in CMake, because CMake executes target_link_libraries although the target LibXml2::LibXml2 doesn’t exist.
I build CMake from source and wanted to debug this situation, but I didn’t got really far. I only found out that for the if command from above the call to cmMakefile::ExecuteCommand directly returns, because IsFunctionBlocked returns true. And then in cmTargetLinkLibrariesCommand the second statement from above produces the errormessage from above, because it cant find the target, although the if condition above was OK.

Reproduction

  • Checkout this branch somewhere
  • Inside run .\bootstrap-vcpkg.bat and .\vcpkg.exe install libxml2:x64-windows-static
  • Checkout llvm-project somewhere
  • Run cmake -B build -DVCPKG_TARGET_TRIPLET=x64-windows-static -DCMAKE_TOOLCHAIN_FILE="<VCPKG_ROOT>/scripts/buildsystems/vcpkg.cmake" -DLLVM_ENABLE_PROJECTS=clang -DLLVM_ENABLE_LIBXML2=FORCE_ON llvm-project/llvm replace <VCPKG_ROOT> with the location, where you cloned the vcpkg branch from above

I assume that you’re using find_package(LibXml2). This does create a LibXml2::LibXml2 target. It’s IMPORTED, but it exists. That conditional should be fixed to either only run when the vendored libxml2 was built or, if that is difficult, check if it is an IMPORTED target or not.

The LibXml2::LibXml2 is always an IMPORTED Target. This doesn’t seem to be a problem, since I don’t get this error when configuring LLVM (which also calls this script and code). This only errors when I also configure clang.

This really sounds like a problem in the clang codebase, not in CMake itself. Just because a target exists does not mean that target_link_libraries on it will succeed (because it may be IMPORTED or even add_custom_target).