This is an archive of the discontinued LLVM Phabricator instance.

[clang] [MinGW] Guess the right ix86 arch name spelling as sysroot
ClosedPublic

Authored by mstorsjo on Oct 16 2021, 1:19 PM.

Details

Summary

For x86, most contempory mingw toolchains use i686 as 32 bit
x86 arch target.

As long as the target triple is set to the right form, this works
fine, either as the compiler's default target, or via e.g.
a triple prefix like i686-w64-mingw32-clang.

However, if the unprefixed toolchain targets x86_64, but the user
tries to switch it to target 32 bit by adding the -m32 option, the
computeTargetTriple function in Clang, together with
Triple::get32BitArchVariant, sets the arch to i386. This causes
the right sysroot to not be found.

When targeting an arch where there are potential spelling ambiguities
with respect to the sysroots (i386 and arm), check if the driver can
find a sysroot with the arch name - if not, try a couple other
candidates.

Other design ideas considered: It would fit in better with the design
to do this kind of arch name fixups in computeTargetTriple (it
already has a couple other OS/arch specific cases), but the
heuristics for detecting the potential right choice ties in quite
closely with how the toolchain looks for the implicit sysroot to use,
so I'd prefer to keep that logic in the toolchain::MinGW class/file.

This is done as a wrapper function before invoking the toolchain::MinGW()
constructor, because the MinGW() constructor can't run code of its own
until the superclass ToolChain() constructor returns. The fixups need to
be done before the ToolChain() constructor, because it uses the Triple
for per-target runtime directories.

Diff Detail

Event Timeline

mstorsjo created this revision.Oct 16 2021, 1:19 PM
mstorsjo requested review of this revision.Oct 16 2021, 1:19 PM
Herald added a project: Restricted Project. · View Herald TranscriptOct 16 2021, 1:19 PM

I guess a downside of this solution, is that if an i686 sysroot exists next to the clang binary, it becomes practically impossible to test codegen differences when you run it with various -target iX86-w64-mingw32 options, as they'd all be corrected back to i686. (This wouldn't be an issue if the autodetection was done in computeTargetTriple only when the -m32/-m64 options are used though.)

I guess a downside of this solution, is that if an i686 sysroot exists next to the clang binary, it becomes practically impossible to test codegen differences when you run it with various -target iX86-w64-mingw32 options, as they'd all be corrected back to i686. (This wouldn't be an issue if the autodetection was done in computeTargetTriple only when the -m32/-m64 options are used though.)

Ok, it turned out to not be that bad to move the fixup into computeTargetTriple to this location after all, it looks fairly neat and not that much out of line compared to the existing triple tweaks done there.

mstorsjo updated this revision to Diff 381795.Oct 24 2021, 12:29 PM

Moved the fixup into computeTargetTriple, so it's only done after applying the -m32/-m64 options.

mstorsjo updated this revision to Diff 382801.Oct 27 2021, 2:33 PM

Rebased after renaming SysrootName to SubdirName.

MaskRay added inline comments.Oct 27 2021, 4:09 PM
clang/lib/Driver/ToolChains/MinGW.h
63

Use functionName for newer functions. (It's unfortunate that Clang has much inconsistency but we should do the right thing for new methods.)

clang/test/Driver/mingw-sysroot.cpp
49

Changing PATH seems unreliable for some test environments.

Any alternative way to test this?

--target= is preferred over -target for driver options. -target is legacy but we probably need to keep indefinitely for its wide usage.

linux-cross.cpp has some nice tests which may inspire this file ? :)

mstorsjo updated this revision to Diff 382946.Oct 28 2021, 1:11 AM
mstorsjo marked an inline comment as done.

Fixed the naming of the new function, using --target= in the newly added test lines, fixed a case of missed clang-format.

mstorsjo added inline comments.Oct 28 2021, 7:09 AM
clang/lib/Driver/ToolChains/MinGW.h
63

Sure, will change it.

clang/test/Driver/mingw-sysroot.cpp
49

Using PATH isn't very nice, no, but it's at least reliable enough to run on the current testing setups?

I don't see any good input for testing this in linux-cross.cpp - that file uses explicit --sysroot= parameters all over the place, while this test file is mostly about how to best implicitly deduce the sysroot when one isn't specified.

This file (both the old and the newly added tests) relies on checking what directories it finds in <clang-executable>/../<triple>, so it requires fake-installing the clang binary by symlinking into a test toolchain tree.

I guess it could be possible to execute that fake-installed clang binary by specifying the direct path to it, instead of adding it to PATH - but it's an important usecase to make sure that it works when the literal path isn't spelled out in argv[0] too.

I can change to use --target= in the added lines, but the rest of the file uses the other spelling anyway (and I don't think it's on topic to do such rewrites as part of this patch).

MaskRay accepted this revision.Oct 28 2021, 9:48 AM
This revision is now accepted and ready to land.Oct 28 2021, 9:48 AM