This is an archive of the discontinued LLVM Phabricator instance.

[cmake] [libcxxabi] Fix find_path() problems when cross compiling
ClosedPublic

Authored by hintonda on Dec 28 2017, 9:34 PM.

Details

Summary

When CMAKE_SYSROOT or CMAKE_FIND_ROOT_PATH is set, cmake
recommends setting CMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY
globally which means find_path() always prepends CMAKE_SYSROOT or
CMAKE_FIND_ROOT_PATH to all paths used in the search.

However, these find_path() invocations are looking for paths in
the libcxx and libunwind projects on the host system, not the
target system, which can be done by passing
NO_CMAKE_FIND_ROOT_PATH.

Event Timeline

hintonda created this revision.Dec 28 2017, 9:34 PM
hintonda retitled this revision from [cmake] Fix path problems when cross compiling. to [cmake] [libcxxabi] Fix path problems when cross compiling..Dec 28 2017, 9:37 PM

I think that it might be better to handle this as a single global change:

if(CMAKE_FIND_ROOT_PATH)
  set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER)
endif()
compnerd requested changes to this revision.Dec 29 2017, 3:34 PM
This revision now requires changes to proceed.Dec 29 2017, 3:34 PM

I think that it might be better to handle this as a single global change:

if(CMAKE_FIND_ROOT_PATH)
  set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER)
endif()

When I cross compile on Darwin and target Linux, I set sysroot and only want look for headers and libs in the new sysroot, not the host system. However, in this case, I want to look for the just built headers. This change helps support this.

As for global settings, this is what I'm setting in my toolchain file:

SET(CMAKE_FIND_ROOT_PATH "${sysroot}" CACHE STRING "" FORCE)
# adjust the default behavior of the FIND_XXX() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER CACHE STRING "" FORCE)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY CACHE STRING "" FORCE)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY CACHE STRING "" FORCE)

Unless there's any further comment, I plan to commit these patches tomorrow.

Isn't NO_DEFAULT_PATH more appropriate here? That's what libc++ uses as well.

Isn't NO_DEFAULT_PATH more appropriate here? That's what libc++ uses as well.

Unfortunately no.

When cross compiling, it's important to look for headers in CMAKE_SYSROOT and/or CMAKE_FIND_ROOT_PATH, or you'll end up finding for headers on the host, not the target. To make sure this works as expected, cmake recommends using set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -- see https://cmake.org/Wiki/CMake_Cross_Compiling for details.

With CMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY and CMAKE_SYSROOT set, all find_XXX() commands will add the CMAKE_SYSROOT prefix to all the paths used in the search. So, if you are trying to look in a local source directory, you'll never find it, because find_XXX() will actually use ${CMAKE_SYSROOT}/<my local path>, which is always the wrong place.

These find_path() invocations are looking in specific places which exist on the host system, not the target system.

Isn't NO_DEFAULT_PATH more appropriate here? That's what libc++ uses as well.

Unfortunately no.

When cross compiling, it's important to look for headers in CMAKE_SYSROOT and/or CMAKE_FIND_ROOT_PATH, or you'll end up finding for headers on the host, not the target. To make sure this works as expected, cmake recommends using set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -- see https://cmake.org/Wiki/CMake_Cross_Compiling for details.

With CMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY and CMAKE_SYSROOT set, all find_XXX() commands will add the CMAKE_SYSROOT prefix to all the paths used in the search. So, if you are trying to look in a local source directory, you'll never find it, because find_XXX() will actually use ${CMAKE_SYSROOT}/<my local path>, which is always the wrong place.

These find_path() invocations are looking in specific places which exist on the host system, not the target system.

Btw, I'm not saying don't use NO_DEFAULT_PATH where appropriate, just that NO_CMAKE_FIND_ROOT_PATH is also required in this case.

hintonda retitled this revision from [cmake] [libcxxabi] Fix path problems when cross compiling. to [cmake] [libcxxabi] Fix find_path() problems when cross compiling.Jan 22 2018, 10:51 AM
hintonda edited the summary of this revision. (Show Details)
This revision was not accepted when it landed; it landed in state Needs Revision.Jan 22 2018, 11:44 AM
This revision was automatically updated to reflect the committed changes.