Page MenuHomePhabricator

[cmake] Don't try creating an executable when detecting the linker
ClosedPublic

Authored by ldionne on May 17 2022, 12:08 PM.

Details

Summary

On most platforms, the linker detection command that we run ends up being
something like clang++ -Wl,-v or clang++ -Wl,--version. This usually
fails with a missing reference to _main because we don't have any input
file. However, when compiling for a target that is implicitly freestanding,
the invocation actually succeeds and a dummy a.out file is created in
the current working directory. This is extremely annoying because it
creates a a.out file at the root of the monorepo when running CMake
configuration from the root.

Diff Detail

Event Timeline

ldionne created this revision.May 17 2022, 12:08 PM
Herald added a project: Restricted Project. · View Herald TranscriptMay 17 2022, 12:08 PM
Herald added a subscriber: mgorny. · View Herald Transcript
ldionne requested review of this revision.May 17 2022, 12:08 PM
Herald added a project: Restricted Project. · View Herald TranscriptMay 17 2022, 12:08 PM

Note that I don't intend this to work on Windows -- I'm not too sure how to specify "no output file" in a generic manner that will work on all platforms.

I think this might potentially break cross-compilation on Windows. We're in a NOT WIN32 block here, but that means you're not targeting Windows; you could still be targeting e.g. Linux but building on a Windows machine. I think NUL is the Windows equivalent, and you could have a CMAKE_HOST_WIN32 block, but it'll depend on how CMake invokes an execute_process command. (I have a Windows machine handy and can experiment with that, if you'd like.) That being said

This is extremely annoying because it creates a a.out file at the root of the monorepo when running CMake configuration from the root.

I thought we forced out-of-tree builds (i.e. you needed to have a dedicated build directory and couldn't just run a CMake configuration from the source tree)? Having a separate build directory seems nicer in general, unless I'm misunderstanding what you meant.

smeenai requested changes to this revision.May 17 2022, 5:51 PM

Removing from my queue in the meantime

This revision now requires changes to proceed.May 17 2022, 5:51 PM

I think this might potentially break cross-compilation on Windows. We're in a NOT WIN32 block here, but that means you're not targeting Windows; you could still be targeting e.g. Linux but building on a Windows machine. I think NUL is the Windows equivalent, and you could have a CMAKE_HOST_WIN32 block, but it'll depend on how CMake invokes an execute_process command. (I have a Windows machine handy and can experiment with that, if you'd like.) That being said

Hmm, I just tried it out on a Windows machine and it seems to work.

I thought we forced out-of-tree builds (i.e. you needed to have a dedicated build directory and couldn't just run a CMake configuration from the source tree)? Having a separate build directory seems nicer in general, unless I'm misunderstanding what you meant.

We do force out of tree builds, however CMake can be invoked as cmake -S llvm -B <path-to-build>, in which case a.out will be generated in whatever directory you happen to be in.

ldionne updated this revision to Diff 430711.May 19 2022, 9:00 AM

Try to handle Windows hosts.

smeenai accepted this revision.May 19 2022, 10:43 AM

LGTM, thanks.

I think this might potentially break cross-compilation on Windows. We're in a NOT WIN32 block here, but that means you're not targeting Windows; you could still be targeting e.g. Linux but building on a Windows machine. I think NUL is the Windows equivalent, and you could have a CMAKE_HOST_WIN32 block, but it'll depend on how CMake invokes an execute_process command. (I have a Windows machine handy and can experiment with that, if you'd like.) That being said

Hmm, I just tried it out on a Windows machine and it seems to work.

To be clear, were you building for Windows on a Windows machine, or targeting some other platform? The NOT WIN32 above would have already taken care of the building for Windows on Windows case.

I thought we forced out-of-tree builds (i.e. you needed to have a dedicated build directory and couldn't just run a CMake configuration from the source tree)? Having a separate build directory seems nicer in general, unless I'm misunderstanding what you meant.

We do force out of tree builds, however CMake can be invoked as cmake -S llvm -B <path-to-build>, in which case a.out will be generated in whatever directory you happen to be in.

Ah, interesting. That's unfortunate, though I guess it makes sense.

This revision is now accepted and ready to land.May 19 2022, 10:43 AM
phosek accepted this revision.May 23 2022, 11:02 PM

LGTM

LGTM, thanks.

I think this might potentially break cross-compilation on Windows. We're in a NOT WIN32 block here, but that means you're not targeting Windows; you could still be targeting e.g. Linux but building on a Windows machine. I think NUL is the Windows equivalent, and you could have a CMAKE_HOST_WIN32 block, but it'll depend on how CMake invokes an execute_process command. (I have a Windows machine handy and can experiment with that, if you'd like.) That being said

Hmm, I just tried it out on a Windows machine and it seems to work.

To be clear, were you building for Windows on a Windows machine, or targeting some other platform? The NOT WIN32 above would have already taken care of the building for Windows on Windows case.

Ugh, yeah, then I guess my testing wasn't sound. Do you have a setup to target Linux from a windows host?

LGTM, thanks.

I think this might potentially break cross-compilation on Windows. We're in a NOT WIN32 block here, but that means you're not targeting Windows; you could still be targeting e.g. Linux but building on a Windows machine. I think NUL is the Windows equivalent, and you could have a CMAKE_HOST_WIN32 block, but it'll depend on how CMake invokes an execute_process command. (I have a Windows machine handy and can experiment with that, if you'd like.) That being said

Hmm, I just tried it out on a Windows machine and it seems to work.

To be clear, were you building for Windows on a Windows machine, or targeting some other platform? The NOT WIN32 above would have already taken care of the building for Windows on Windows case.

Ugh, yeah, then I guess my testing wasn't sound. Do you have a setup to target Linux from a windows host?

I think Android might be the easiest thing to target. You can download the Android NDK and target it with -DCMAKE_TOOLCHAIN_FILE=path_to_ndk/build/cmake/android.toolchain.cmake; I don't know how much of LLVM will build, but you should at least be able to test the CMake configure that way.

Okay, I just managed to try this command on Windows targeting the Android NDK, and the CMake build fails extremely early. However, when I move the check to a different place, it works as intended. In other words, if someone wants to target Android from Windows, it looks like LLVM's not going to cooperate -- however this patch won't make things worse.

This revision was landed with ongoing or failed builds.Wed, Jun 8, 11:37 AM
This revision was automatically updated to reflect the committed changes.