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

setuptools.msvc: set host_dir correctly on ARM64 hosts #4786

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

swt2c
Copy link

@swt2c swt2c commented Jan 3, 2025

Summary of changes

This corrects the setting of the host directory name on ARM64 hosts so that EnvironmentInfo.return_env()['path'] includes the correct path to CL.EXE. Currently, it returns the X64 directory. See below; note HostX64 in first listed path.

$ python
Python 3.13.1 (tags/v3.13.1:0671451, Dec  3 2024, 20:04:37) [MSC v.1942 64 bit (ARM64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import setuptools.msvc
>>> ei = setuptools.msvc.EnvironmentInfo('arm64')
>>> ei.return_env()['path']
'C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.42.34433\\bin\\HostX64\\arm64;C:\\Program Files (x86)\\Windows Kits\\10\\Bin\\arm64;C:\\Program Files (x86)\\Windows Kits\\10\\Bin\\10.0.22621.0\\arm64;C:\\Users\\talbert\\.blah_env\\Scripts;C:\\Program Files\\Git\\clangarm64\\bin;C:\\Program Files\\Git\\usr\\bin;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0;C:\\Windows\\System32\\OpenSSH;C:\\Program Files\\Git\\cmd;C:\\Users\\talbert\\AppData\\Local\\Programs\\Python\\Python313-arm64\\Scripts;C:\\Users\\talbert\\AppData\\Local\\Programs\\Python\\Python313-arm64;C:\\Users\\talbert\\AppData\\Local\\Programs\\Python\\Launcher;C:\\Users\\talbert\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Program Files\\Git\\usr\\bin\\vendor_perl;C:\\Program Files\\Git\\usr\\bin\\core_perl'

Pull Request Checklist

Comment on lines 1041 to 1049
host_dir = (
r'bin\HostX86%s' if self.pi.current_is_x86() else r'bin\HostX64%s'
r'bin\HostX86%s'
if self.pi.current_is_x86()
else (
r'bin\HostARM64%s'
if self.pi.current_cpu == 'arm64'
else r'bin\HostX64%s'
)
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a maintainer here, but personally I find if-else chains to be much more readable and concise than nested ternaries:

            if self.pi.current_is_x86():
                host_dir = r'bin\HostX86%s'
            elif self.pi.current_cpu == 'arm64':
                host_dir = r'bin\HostARM64%s'
            else:
                host_dir = r'bin\HostX64%s'

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

@swt2c swt2c force-pushed the fix_msvc_host_dir_arm64 branch from 5ef90ee to cf436b4 Compare January 4, 2025 03:23
Copy link
Member

@jaraco jaraco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this PR isn't linked to any issue, can you update the PR description to elaborate on the issue? In particular, answer questions like: Why does it matter? How did you encounter it? Under what conditions is it relevant (e.g. does it affect all users of Setuptools on ARM, or some subset)?

I see lots of other places in this module where the assumption is that there is x86 and x64. I'm not sure it makes sense to add ARM support here, but not elsewhere. What's the value in fixing just this issue and not other parts in the module that deal with processor architecture?

Comment on lines 1041 to 1046
if self.pi.current_is_x86():
host_dir = r'bin\HostX86%s'
elif self.pi.current_cpu == 'arm64':
host_dir = r'bin\HostARM64%s'
else:
host_dir = r'bin\HostX64%s'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even better than an if/else statement would be something like:

Suggested change
if self.pi.current_is_x86():
host_dir = r'bin\HostX86%s'
elif self.pi.current_cpu == 'arm64':
host_dir = r'bin\HostARM64%s'
else:
host_dir = r'bin\HostX64%s'
host_dir = os.path.join('bin', f'Host{self.host_id.upper()}%s')

And then of course implement the property host_id to reflect the correct string to insert. In general, it's good practice to DRY - avoid repeating the assignment and prefix and suffix of the value.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a property for something that's only used once seemed a bit of overkill. Let me know if what I did works.

)
if self.pi.current_is_x86():
host_dir = r'bin\HostX86%s'
elif self.pi.current_cpu == 'arm64':
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this comparison is no longer symmetrical with the check for 'x86'. Better would be to be consistent. Either use self.pi.current_cpu == 'x86' inline or implement a new self.pi.current_is_arm64() method.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed.

@swt2c
Copy link
Author

swt2c commented Jan 5, 2025

Since this PR isn't linked to any issue, can you update the PR description to elaborate on the issue? In particular, answer questions like: Why does it matter? How did you encounter it? Under what conditions is it relevant (e.g. does it affect all users of Setuptools on ARM, or some subset)?

I see lots of other places in this module where the assumption is that there is x86 and x64. I'm not sure it makes sense to add ARM support here, but not elsewhere. What's the value in fixing just this issue and not other parts in the module that deal with processor architecture?

I thought the description was pretty clear about what the problem was (it really is just about the path item as returned by EnvironmentInfo.return_env(), but I added a Python interpreter run that shows the exact output that you currently get. This issue affects anyone who is using EnvironmentInfo.return_env() on an ARM64 Windows system and relying on the path that is returned.

This is the only problem that I'm actually aware of with setuptools.msvc on Windows ARM64. I just did another look through the file and while yes, there are a lot of cases where it assumes there is only x86 and x64, I didn't see any cases where it is actually doing the wrong thing on ARM64. The rest of the output of EnvironmentInfo.return_env() looks fine.

@swt2c swt2c force-pushed the fix_msvc_host_dir_arm64 branch from cf436b4 to b8f9800 Compare January 5, 2025 18:18
@swt2c swt2c force-pushed the fix_msvc_host_dir_arm64 branch from b8f9800 to e1d81b8 Compare January 5, 2025 18:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants