[libcxx-commits] [PATCH] D112112: [libunwind] Link with -unwindlib=none

Martin Storsjö via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Wed Oct 20 03:48:03 PDT 2021


mstorsjo added a comment.

In D112112#3074613 <https://reviews.llvm.org/D112112#3074613>, @hvdijk wrote:

> In D112112#3074591 <https://reviews.llvm.org/D112112#3074591>, @mstorsjo wrote:
>
>> Actually, I remembered I had an unupstreamed patch regarding this locally... It turns out that testing `check_c_compiler_flag(-unwindlib=none)` doesn't work, as the tested flag is added the the compile command (but not to the link command), so the link part of the test command still fails.
>
> The `libunwind/src/CMakeLists.txt` change sets up the link flag;

Yes, that's necessary for taking it into use when compiling the project. But the flag is also needed when CMake probes for other things during the build system, and without it, all those tests fail. That's why you add it to `CMAKE_REQUIRED_FLAGS`.

In my case, with my other workarounds removed and this patch applied, I'm getting this from CMake:

  -- Performing Test LIBUNWIND_SUPPORTS_NOSTDLIBXX_FLAG
  -- Performing Test LIBUNWIND_SUPPORTS_NOSTDLIBXX_FLAG - Failed
  -- Performing Test LIBUNWIND_SUPPORTS_UNWINDLIB_EQ_NONE_FLAG
  -- Performing Test LIBUNWIND_SUPPORTS_UNWINDLIB_EQ_NONE_FLAG - Failed
  -- Performing Test LIBUNWIND_SUPPORTS_NODEFAULTLIBS_FLAG
  -- Performing Test LIBUNWIND_SUPPORTS_NODEFAULTLIBS_FLAG - Failed

If inspecting `CMakeFiles/CMakeError.log` to see what happened when testing the `-unwindlib=none` flag, I find this:

  Performing C SOURCE FILE Test LIBUNWIND_SUPPORTS_UNWINDLIB_EQ_NONE_FLAG failed with the following output:
  Change Dir: /build/llvm-project/libunwind/build-i686-shared/CMakeFiles/CMakeTmp
  
  Run Build Command(s):/usr/bin/ninja cmTC_94016 && [1/2] Building C object CMakeFiles/cmTC_94016.dir/src.c.obj
  [2/2] Linking C executable cmTC_94016.exe
  FAILED: cmTC_94016.exe
  : && /opt/llvm-mingw/bin/i686-w64-mingw32-clang   CMakeFiles/cmTC_94016.dir/src.c.obj -o cmTC_94016.exe -Wl,--out-implib,libcmTC_94016.dll.a -Wl,--major-image-version,0,--minor-image-version,0  -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && :
  lld: error: unable to find library -lunwind
  lld: error: unable to find library -lunwind
  clang-13: error: linker command failed with exit code 1 (use -v to see invocation)
  ninja: build stopped: subcommand failed.

During this particular test, CMake does apply the tested flag, `-unwindlib=none`, when compiling the test object (`CMakeFiles/cmTC_94016.dir/src.c.obj`) although that's not visible in the log. But it's not applying that flag when it does linking of the test executable. See e.g. https://gitlab.kitware.com/cmake/cmake/-/issues/15934 for discussion on that issue.

If we just blindly add the flag to `CMAKE_REQUIRED_FLAGS` as I do in D112126 <https://reviews.llvm.org/D112126>, it will get included when doing tests, both when compiling and linking the test objects, making the tests succeed.

So instead of this:

  check_c_compiler_flag(-unwindlib=none CONDITION)
  if (CONDITION)
    set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS -unwindlib=none"}
  endif()

I do this:

  set(CMAKE_REQUIRED_FLAGS_ORIG "${CMAKE_REQUIRED_FLAGS}")
  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -unwindlib=none")
  check_c_compiler_flag("" CONDITION)
  if (NOT CONDITION)
    set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS_ORIG}")
  endif()

I'm curious to know how it succeeds in your case, if it's linking in `-lunwind` explicitly when linking the final libunwind library, but not while trying the `check_c_compiler_flag()`. Is it a case where `-lunwind` is added implicitly only when linking as C++ but not C? (As far as I've read the clang driver, if it adds it implicitly for either of them, it should add it for both.)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D112112/new/

https://reviews.llvm.org/D112112



More information about the libcxx-commits mailing list