Skip to content

clang-cl on Windows still needs PreferredToolArchitecture #131473

Closed
@chris-eibl

Description

@chris-eibl

I hoped I fixed it in 263870d, but it turned out, that this is not enough, see astral-sh/python-build-standalone#549 (comment).

Digging in deeper, I now know more, but do not have an ideal fix, yet.

First, for Hacl_Hash_Blake2b_Simd256.c

<AdditionalOptions>/arch:AVX2</AdditionalOptions>

is missing %(AdditionalOptions). Likewise, Hacl_Hash_Blake2s_Simd128.c. Then, both will "see" the -m32/ -m64 defined in

<AdditionalOptions Condition="'$(Platform)' == 'Win32'">-m32 %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Platform)' == 'x64'">-m64 %(AdditionalOptions)</AdditionalOptions>

This will fix regular release or debug builds (#131475), since they do not have to link against anything from clang.

But unfortunately, for PGO builds, clang-cl needs to link against clang_rt.profile.lib:

  • <VS install path>\Community\VC\Tools\Llvm\lib\clang\<clang major version>\lib\windows\clang_rt.profile-i386.lib
  • <VS install path>\Community\VC\Tools\Llvm\x64\lib\clang\<clang major version>\lib\windows\clang_rt.profile-x86_64.lib

This is not found correctly without setting PreferredToolArchitecture (or LLVMInstallDir).
The reason stems from <VS install path>\Community\MSBuild\Microsoft\VC\v160\Microsoft.Cpp.ClangCl.Common.props:

    <_DefaultLLVMInstallDir Condition="'$(_DefaultLLVMInstallDir)' == '' AND '$(PreferredToolArchitecture)' == 'arm64'">$(VsInstallRoot)\VC\Tools\Llvm\ARM64</_DefaultLLVMInstallDir>
    <_DefaultLLVMInstallDir Condition="'$(_DefaultLLVMInstallDir)' == '' AND '$(PreferredToolArchitecture)' == 'x64'">$(VsInstallRoot)\VC\Tools\Llvm\x64</_DefaultLLVMInstallDir>
    <_DefaultLLVMInstallDir Condition="'$(_DefaultLLVMInstallDir)' == '' AND '$(PreferredToolArchitecture)' != 'x64'">$(VsInstallRoot)\VC\Tools\Llvm</_DefaultLLVMInstallDir>
    <LLVMInstallDir Condition="'$(LLVMInstallDir)' == ''">$(_DefaultLLVMInstallDir)</LLVMInstallDir>

This means, if PreferredToolArchitecture is not given on the command line, for a 64bit build the LLVMInstallDir is chosen to be the "32bit clang installation". Even though this one will happily "cross-compile" getting the -m64 switch, it will fail in the link step, because the 64bit libs are "in the 64bit clang installation directory".

See also https://learn.microsoft.com/en-us/cpp/build/reference/msbuild-visual-cpp-overview?view=msvc-170#preferredtoolarchitecture-property:

The PreferredToolArchitecture property determines whether the 32-bit or 64-bit compiler and tools are used in the build.

I am unsure what to do here:

  • try to fix that somewhere in pyproject-clangcl.props: not so easy, because "too late": LLVMInstallDir will always be set here, either because
    • given on the command line, i.e. custom clang installation
    • or Microsoft.Cpp.ClangCl.Common.props will already have set it to the bundled clang installation based on PreferredToolArchitecture
  • ask Microsoft to fix that? There are some hits about this behaviour in the net ...
  • document (again, but this time I have more background knowledge) that the user is responsible to either
    • set PreferredToolArchitecture correctly when using the bundled version
    • set LLVMInstallDir to a 32bit installation for 32bit builds and similarily for 64bit builds.

See here, why I personally anyways always set PreferredToolArchitecture (spoiler: I do not like the _freeze_module to be compiled as 32bit, for exactly the same reason: if PreferredToolArchitecture is missing, it defaults to 32bit). Most probably an unwanted side effect of https://github.com/python/cpython/pull/28491/files or the lesser evil :)

ISTM, I returned to this habit too quickly, and so I missed that rabit hole - but now I've dug deeper.

FTR, this will also be needed when someone wants to do ASAN, UBSAN, FUZZER, etc, builds using clang-cl on Windows, because in all those cases the correct libs are needed.

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    OS-windowsbuildThe build process and cross-buildtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions