Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NDK cmake toolchain overrides CMAKE_FIND_ROOT_PATH #912

Closed
aberaud opened this issue Feb 16, 2019 · 6 comments
Closed

NDK cmake toolchain overrides CMAKE_FIND_ROOT_PATH #912

aberaud opened this issue Feb 16, 2019 · 6 comments
Assignees
Milestone

Comments

@aberaud
Copy link

aberaud commented Feb 16, 2019

Since NDKr19b (#890), android.toolchain.cmake overrides CMAKE_FIND_ROOT_PATH to points to the NDK directory.

This prevents projects building multiple libraries depending on each other to find other built libraries using find_path, find_library etc.

Indeed, CMAKE_FIND_ROOT_PATH is used to prefix every other cmake search path, so find_library would only be able to find libraries under the NDK path.

It's possible to specify multiple root paths, so instead of overriding, the NDK might set itself as the first root path ?

set(CMAKE_FIND_ROOT_PATH "${ANDROID_NDK};${CMAKE_FIND_ROOT_PATH}")

or something similar.

@aberaud aberaud added the bug label Feb 16, 2019
@DanAlbert
Copy link
Member

That won't do because we do need to make sure that the host system isn't being searched (which is why this changed, causing this new bug), but if the user is supposed to be able to override that then obviously the r19b approach isn't working either.

I'll need to play with this a bit to see what we can do. Could you give me an example of how you use CMAKE_FIND_ROOT_PATH? I don't use CMake much myself, and this is a corner I'm rather unfamiliar with. I want to get a test case added to make sure we don't regress, but I don't know what that test case looks like. I was under the impression that CMAKE_MODULE_PATH and whatnot were the right things to override from the user side.

@DanAlbert DanAlbert added this to the r19c milestone Feb 16, 2019
@DanAlbert DanAlbert self-assigned this Feb 16, 2019
@aberaud
Copy link
Author

aberaud commented Feb 16, 2019

We use CMAKE_FIND_ROOT_PATH to point to the cross-compilation root, where built libraries are installed.
This allows cmake to find other installed headers and built libraries with find_path, find_library etc.

According to the cmake documentation this is what CMAKE_FIND_ROOT_PATH is meant for:

This variable is most useful when cross-compiling. CMake uses the paths in this list as alternative roots to find filesystem items with find_package(), find_library() etc.

I think CMAKE_MODULE_PATH is specific to CMake modules and unrelated. CMAKE_PREFIX_PATH and al are simply appended to CMAKE_FIND_ROOT_PATH so they don't allow to find stuff outside of the root paths.

Test case

A project that builds two libraries:

  • Library A, installed to some arbitrary rootpath $(PREFIX) (might just be some header file include/test.h)
  • Library B, depends on A, uses CMake to find A with CMAKE_FIND_ROOT_PATH set to the rootpath where A is installed.

CMakeLists.txt of library B:

find_path(test_INCLUDE test.h)

if (test_INCLUDE)
    message(STATUS "Found test include at: ${test_INCLUDE}")
else ()
    message(FATAL_ERROR "Failed to locate test dependency.")
endif ()

Library B configured with:

cmake . -DCMAKE_TOOLCHAIN_FILE=$(ANDROID_NDK)/build/cmake/android.toolchain.cmake \
		-DANDROID_PLATFORM=$(ANDROID_API) \
		-DANDROID_ABI=$(ANDROID_ABI) \
		-DCMAKE_FIND_ROOT_PATH=$(PREFIX) \
		-DCMAKE_INSTALL_PREFIX=$(PREFIX)

I guess a full testcase might also make library B depend on some system library..

Possible solutions

By default, CMAKE_FIND_ROOT_PATH is empty. If set to any value, the host system won't be searched. This means the proposed solution of appending the NDK path instead of overriding would likely work fine. In that case the project would look in priority in the NDK directory and fallback to the project rootpath, if set.

The NDK might also set CMAKE_SYSROOT and let projets set CMAKE_FIND_ROOT_PATH themself. Not certain but this seems like the intended use of CMake (sysroot for system headers/libraries, root path for the project). This means more work for projects, but that's what projects already do for cross-compiling for other platforms.

@DanAlbert
Copy link
Member

By default, CMAKE_FIND_ROOT_PATH is empty. If set to any value, the host system won't be searched. This means the proposed solution of appending the NDK path instead of overriding would likely work fine. In that case the project would look in priority in the NDK directory and fallback to the project rootpath, if set.

Yeah, given the explanation I think you're right. I'll make sure all our existing tests pass with that change and then see if I can work up a test case that makes use of CMAKE_FIND_ROOT_PATH so we don't regress (such a test will be... complicated in our infrastructure, but I'll give it a shot).

@DanAlbert
Copy link
Member

DanAlbert commented Feb 20, 2019

https://android-review.googlesource.com/c/platform/ndk/+/907834 doesn't break any of our existing tests and does seem to fix the problem. For the moment I've only added a trivial test to make sure that we don't clobber user input, but it may be worth trying to build a more complete test at some point.

Thanks for the report and suggestions on this!

@aberaud
Copy link
Author

aberaud commented Feb 20, 2019

Many thanks !

@DanAlbert
Copy link
Member

Merged into r19c.

disigma pushed a commit to wimal-build/ndk that referenced this issue Feb 22, 2019
If we set this option here we will clobber anything the user has
provided on the command line. Despite the name, this is actually a
list. All we need to ensure is that the variable is not empty, so
appending to the list is sufficient to avoid the host's libraries.

Test: ./checkbuild.py && ./run_tests.py
Bug: android/ndk#912
Change-Id: I683a99c556e619e8fec86cbb89450407562e40b9
(cherry picked from commit fa4b2ee)
grendello added a commit to grendello/xamarin-android that referenced this issue Mar 21, 2019
Upstream [changes][0]:

 * [Issue 912][1]: Prevent the CMake toolchain file from clobbering a user
   specified `CMAKE_FIND_ROOT_PATH`.
 * [Issue 920][2]: Fix clang wrapper scripts on Windows.

[0]: https:/android-ndk/ndk/wiki/Changelog-r19#r19c
[1]: android/ndk#912
[2]: android/ndk#920
grendello added a commit to grendello/xamarin-android that referenced this issue Mar 21, 2019
Upstream [changes][0]:

 * [Issue 912][1]: Prevent the CMake toolchain file from clobbering a user
   specified `CMAKE_FIND_ROOT_PATH`.
 * [Issue 920][2]: Fix clang wrapper scripts on Windows.

[0]: https:/android-ndk/ndk/wiki/Changelog-r19#r19c
[1]: android/ndk#912
[2]: android/ndk#920
jonpryor pushed a commit to dotnet/android that referenced this issue Mar 22, 2019
Upstream [changes][0]:

  * [Issue 912][1]: Prevent the CMake toolchain file from clobbering
    a user specified `CMAKE_FIND_ROOT_PATH`.
  * [Issue 920][2]: Fix clang wrapper scripts on Windows.

[0]: https:/android-ndk/ndk/wiki/Changelog-r19#r19c
[1]: android/ndk#912
[2]: android/ndk#920
mehulagg pushed a commit to mehulagg/superproject that referenced this issue Dec 21, 2019
* Update ndk from branch 'ndk-release-r19'
  to 88cb7b0879e33f1f1801f58b6d7cc91bc8d1ae85
  - Merge "Allow users to set their own CMAKE_FIND_ROOT_PATH." into ndk-release-r19
  - Allow users to set their own CMAKE_FIND_ROOT_PATH.
    
    If we set this option here we will clobber anything the user has
    provided on the command line. Despite the name, this is actually a
    list. All we need to ensure is that the variable is not empty, so
    appending to the list is sufficient to avoid the host's libraries.
    
    Test: ./checkbuild.py && ./run_tests.py
    Bug: android/ndk#912
    Change-Id: I683a99c556e619e8fec86cbb89450407562e40b9
    (cherry picked from commit fa4b2ee3dbd1c8e5548c087682a9fea01636b15c)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants