This is an archive of the discontinued LLVM Phabricator instance.

Fix FindZ3.cmake's version detection mechanism
AbandonedPublic

Authored by Naville on Aug 23 2022, 12:40 AM.

Details

Summary
  • Fix the issue that when the test program is not executed (Ex: Can't run due to missing dependency library), on Windows the error message of missing DLLs is used to parse version info
  • Z3 has bumped its versioning to two digits (4.11.0) which old regex can't recognize. (4.11.0 got identified as 4.1.0, which is an error)

Diff Detail

Event Timeline

Naville created this revision.Aug 23 2022, 12:40 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 23 2022, 12:40 AM
Naville requested review of this revision.Aug 23 2022, 12:40 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 23 2022, 12:40 AM
Naville edited the summary of this revision. (Show Details)Aug 23 2022, 12:47 AM
Naville edited the summary of this revision. (Show Details)Aug 23 2022, 1:08 AM
Naville updated this revision to Diff 454733.EditedAug 23 2022, 1:14 AM

Obviously {1,2} is not supported in CMake, updated to use +

Naville edited the summary of this revision. (Show Details)Aug 23 2022, 1:15 AM

LGTM, but prior approval I'll get a second pair of eyes.
I'm not using windows.

Naville added a comment.EditedSep 4 2022, 11:08 PM

LGTM, but prior approval I'll get a second pair of eyes.
I'm not using windows.

It's not strictly Windows, the output is obviously meaningless if the test program failed to execute, which we detect with Z3_RETURNCODE

CMake Reference

steakhal accepted this revision.Sep 6 2022, 8:27 AM

Let's land this. Thanks for your patience. Also thanks for fixing this.

This revision is now accepted and ready to land.Sep 6 2022, 8:27 AM
steakhal requested changes to this revision.Sep 6 2022, 8:40 AM

Oh, @Godin called my attention to a detail. Now, I'm no longer comfortable approving this unless I get some clarification.

llvm/cmake/modules/FindZ3.cmake
85

Why did you remove the CMAKE_CROSSCOMPILING?

This revision now requires changes to proceed.Sep 6 2022, 8:40 AM
Naville added a comment.EditedSep 6 2022, 12:12 PM

i>>! In D132441#3772196, @steakhal wrote:

Oh, @Godin called my attention to a detail. Now, I'm no longer comfortable approving this unless I get some clarification.

Hi:

In the Windows example (similar reasoning elsewhere):

  • The linked test program failed to execute because it's missing a specific version of CRT (I remember it was Debug version of CRT vs. Release version of CRT)
  • In this case the program still failed to execute, but it's definitely not cross-compiling since we are still targeting x64 Windows

EDIT 01:
In my understanding, cross-compiling -> failed to execute -> catched by the Z3_RETURNCODE patch -> fallback to header regex path.

Though, I don't cross-compile LLVM myself so I can't personally confirm the implementation is correct w.r.t. cross-compiling. But the logic seems to be right? I think?

EDIT02:
While we are at it, it'll be even better if LLVM's builtbot could test this patch for cross-compiling

Ping @steakhal is there any issue with my clarification?

Godin added a comment.Sep 9 2022, 12:36 AM

Hi @Naville ,

Please excuse for the delay with the response, I think @steakhal wanted to see the response from me, but it was a day off for me yesterday.

The linked test program failed to execute because it's missing a specific version of CRT (I remember it was Debug version of CRT vs. Release version of CRT)

Isn't it the root of the problem that should be fixed instead? To my taste, it sounds a bit weird for the non-cross-compiling mode to let the build process continue after the failure to run the test program due to such a mismatch - isn't this opening a door for a failure to link Z3 with Clang later?
I'm also not on Windows, but we have a CI at work that builds Clang with Z3, and I saw such a mismatch only in cases when z3 will fail to link with Clang, so I'm curious if can reproduce your case in order to better understand it - could you please share how do you build Z3 and Clang?

Hi @Naville ,

Please excuse for the delay with the response, I think @steakhal wanted to see the response from me, but it was a day off for me yesterday.

The linked test program failed to execute because it's missing a specific version of CRT (I remember it was Debug version of CRT vs. Release version of CRT)

Isn't it the root of the problem that should be fixed instead? To my taste, it sounds a bit weird for the non-cross-compiling mode to let the build process continue after the failure to run the test program due to such a mismatch - isn't this opening a door for a failure to link Z3 with Clang later?
I'm also not on Windows, but we have a CI at work that builds Clang with Z3, and I saw such a mismatch only in cases when z3 will fail to link with Clang, so I'm curious if can reproduce your case in order to better understand it - could you please share how do you build Z3 and Clang?

Hi:
I think Z3 was built with VCPKG with triplet `x64-windows`, unfortunately can't reproduce the exact environment since it's been a while and we have switch to static built z3 since.
But I do remember at one time I need to add `%Path%=.....` to add Z3.dll and its dependencies to the DLL search path for the test program to work, even without CRT version mismatch

Naville added a comment.EditedSep 9 2022, 12:48 AM

Browsed through my catalog and found one.
Basically, vcpkg put libZ3.dll in its own "exported toolchain folder", and then you use it with `-DCMAKE_TOOLCHAIN_FILE=vcpkg/...../vcpkg.cmake XXXXX`.
In this case, libZ3.dll is not copied into the same directory with the built test program, nor is it in system DLL path, hence broke current FindZ3.cmake in another completely different way

EDIT01:
Plus, I see no reason why we can't always use the regex path as the final fallback plan

EDIT02:

for a failure to link Z3 with Clang later?

This will not broke in the case mentioned above, because CMake guides the linker to link the "stub library" instead, and only requires the .dll when actually running

Godin resigned from this revision.Sep 13 2022, 8:38 AM

Sorry, but I'm not familiar with vcpkg

why we can't always use the regex path as the final fallback plan

and I don't feel that I'm the right person to answer this question and take a decision about this, so have to resign from the reviewer here.

But to me personally this doesn't sound right, because if I understood you correctly it didn't result in link failure in this case, but might result in a runtime failure.

All other changes look good to me. So maybe will be better to leave them only and revert vcpkg-related changes here, especially since you also don't rely on it anymore.

Godin added a subscriber: Godin.Sep 13 2022, 8:40 AM

Sorry, I just saw this patch...

Part of it was just merged in D134261.

May I ask you to rebase?

@stilriv is this related to what you plan next?

Not really. I want to split try_run into try_compile (both cross and native) and try_run (native or when CROSSCOMPILING_EMULATOR is specified) or fallback to header parsing in cross build (when there is no CROSSCOMPILING_EMULATOR). The reasoning is that try_run without emulator always causes a configuration error unless explicit Z3RETURNCODE (or something) and Z3TRYRUN_OUTPUT (or something) are passed through command line which is very inconvenient keepind in mind this machinery is meant to detect version without user input.

Browsed through my catalog and found one.
Basically, vcpkg put libZ3.dll in its own "exported toolchain folder", and then you use it with `-DCMAKE_TOOLCHAIN_FILE=vcpkg/...../vcpkg.cmake XXXXX`.
In this case, libZ3.dll is not copied into the same directory with the built test program, nor is it in system DLL path, hence broke current FindZ3.cmake in another completely different way

EDIT01:
Plus, I see no reason why we can't always use the regex path as the final fallback plan

EDIT02:

for a failure to link Z3 with Clang later?

This will not broke in the case mentioned above, because CMake guides the linker to link the "stub library" instead, and only requires the .dll when actually running

You are describing problem with the toolchain here, not with LLVM's cmakes. And, IMO, this should be fixed on the toolchain side (in your case by adding directory with libZ3.dll to the PATH variable). The advantage of try_run path is that it is clearly diagnose problems with [broken] toolchain during configuration phase, so instead of getting broken LLVM libs after compilation you get early configuration error.

You are describing problem with the toolchain here, not with LLVM's cmakes. And, IMO, this should be fixed on the toolchain side (in your case by adding directory with libZ3.dll to the PATH variable). The advantage of try_run path is that it is clearly diagnose problems with [broken] toolchain during configuration phase, so instead of getting broken LLVM libs after compilation you get early configuration error.

I wouldn't describe it as a problem, since relying on cmake to download the dependencies is becoming common.

If it also works for cross-compilation, it could simplify the findz3.cmake considerably.

Also, I think it should only download the static z3 lib, right? Otherwise, we could have problems when running clang.

Godin removed a subscriber: Godin.Sep 27 2022, 6:29 AM
Naville abandoned this revision.Nov 9 2022, 2:02 AM