This is an archive of the discontinued LLVM Phabricator instance.

[MSVC] If unable to find link.exe from a MSVC installation, look for link.exe next to cl.exe
ClosedPublic

Authored by mstorsjo on Apr 1 2019, 1:20 PM.

Details

Summary

Previously, if the MSVC installation isn't detected properly, clang will later just fail to execute link.exe.

This improves using clang in msvc mode on linux, where one intentionally might not want to point clang to the MSVC installation itself (which isn't executable as such), but where a link.exe named wine wrapper is available in the path next to a cl.exe named wine wrapper.

Diff Detail

Repository
rC Clang

Event Timeline

mstorsjo created this revision.Apr 1 2019, 1:20 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 1 2019, 1:20 PM
amccarth added inline comments.
lib/Driver/ToolChains/MSVC.cpp
492

The comment above explains one reason why we shouldn't use link.exe on the path.

If it is an appropriate fallback, modify the comment or add another one here explaining why this is better than failing. I think you hit on it in the patch summary, but it should be captured in the code.

rnk added inline comments.Apr 1 2019, 4:43 PM
lib/Driver/ToolChains/MSVC.cpp
492

Right, and this code block is inside some crazy getenv check for USE_PATH_LINK, so I think we don't want to do a path search here. Then again, I bet someone added that because they wanted clang to just do a path search. I guess, there's your workaround.

mstorsjo marked an inline comment as done.Apr 1 2019, 11:32 PM
mstorsjo added inline comments.
lib/Driver/ToolChains/MSVC.cpp
492

Sorry for the confusion - the getenv USE_PATH_LINK thingie there isn't present upstream, it's my other initial hack to get around this issue; I should have reordered the patches before making this diff.

So that getenv hack is an ugly but convenient (for me) way around the issue. Another alternative is to use -fuse-ld=link.exe (which happens to miss the Linker.equals_lower("link") check).

Prior to switching to lld, how did chromium do this? I presume the cross compilation setup did exist already before lld. Although in practice I guess most people don't use (clang-)cl for linking but just invoke link directly so maybe it didn't matter at all.

Another approach (which also works fine for me) is to look for $(dirname $(which cl))/link.exe.

FWIW, to add a bit of context about why (since normally, few people actually do link via the (clang-)cl interface); CMake does during some of its tests.

I'd like to bring it to a point so that CC=clang-cl CXX=clang-cl cmake ... would work, while I currently either need my env var hack, or e.g. CC="clang-cl -fuse-ld=link.exe" ... (or -fuse-ld=lld-link). Doing that is not hard, but it's a bit of a nuisance as I tend to forget it.

rnk added inline comments.Apr 4 2019, 1:38 PM
lib/Driver/ToolChains/MSVC.cpp
492

I think it's worth implementing $(dirname $(which cl))/link.exe because /usr/bin/link exists on Linux and in many Unix shell environments for Windows.

mstorsjo updated this revision to Diff 194926.Apr 12 2019, 11:48 AM
mstorsjo retitled this revision from [MSVC] If unable to find link.exe relative to MSVC, look for link.exe in the path to [MSVC] If unable to find link.exe from a MSVC installation, look for link.exe next to cl.exe.
mstorsjo edited the summary of this revision. (Show Details)

Updated to not look blindly for link(.exe) in the PATH, but look for cl.exe and look for link.exe next to it.

mstorsjo updated this revision to Diff 194928.Apr 12 2019, 11:49 AM

Removed other local experiments from the patch context.

rnk accepted this revision.Apr 19 2019, 11:30 AM

lgtm

This revision is now accepted and ready to land.Apr 19 2019, 11:30 AM
This revision was automatically updated to reflect the committed changes.