revision testet --------------- The version tested was: openembedded-core a8debddd6cbdd70db74e096d72f97fbee008ee63 But it is also unchanged the master-branch. Overview -------- With the toolchain's version of cmake, it is not possible to find packages other than in the toolchain itself. While in general this is intended behavior for toolchain isolation, it is a required feature if 2 (or more) cmake-projects are build with the toolchains-cmake, where the 2. project depends on the 1. one. This behavior is forced by meta/recipes-devtools/cmake/cmake/OEToolchainConfig.cmake and the two following lines set( CMAKE_FIND_ROOT_PATH $ENV{OECORE_TARGET_SYSROOT} ) set( CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY ) The variable CMAKE_FIND_ROOT_PATH can not be set when cmake is called, because it will be overwritten by the specifications of OEToolchainConfig.cmake. Extending the variable from within the CMakeLists.txt of the 2. project is possible, but not feasible for a larger set of packages that depend on each other, because it would require every project to be changed. Steps to Reproduce ------------------ - Build a cmake library foo and install it to a artifact folder. - Build another cmake library bar, which contains find_package(foo) in its CMakeLists.txt, which is designated to the same artifact folder. Actual Result ------------- Build of libraries that contain find_package against libraries that where build with the same toolchain and installed in the same artifact folder, cannot be found. Expected Results ---------------- All libraries are found bei cmake. Possible (dirty) workaround --------------------------- Since we use the toolchain only in a controlled way, where we know that CMAKE_INSTALL_PREFIX is set to a folder that only contain libraries build with this toolchain, we extent CMAKE_FIND_ROOT_PATH with CMAKE_INSTALL_PREFIX. However this is probably not a generic solution. To be precice, we currently install OEFindArtifactToolchain.cmake to ${D}${datadir}/cmake/OEToolchainConfig.cmake.d/ with the following content: if( NOT "${CMAKE_INSTALL_PREFIX}" STREQUAL "/" AND NOT "${CMAKE_INSTALL_PREFIX}" MATCHES "/usr/local.*" ) SET( CMAKE_FIND_ROOT_PATH ${CMAKE_INSTALL_PREFIX} ${CMAKE_FIND_ROOT_PATH} ) endif()
Thanks for the clear description but at the moment we don't have anyone on hand to work on it. Are you willing to do so? Richard Purdie though the work-around would prevent things from being re-locatable so post an email before beginning work to understand the requirements for a fix.
Yes I can work on it. It would be great when you could provide me with your requirements for a fix or point out which way you want it to be implemented.
Thanks Tobias! The team usually carries out such discussion on the email lists so please write a brief proposal or a list of design options and send it to: openembedded-core@lists.openembedded.org and include: richard.purdie@linuxfoundation.org to the To: list. You can label it as an RFC if you like to make it clear that you're looking for comments.
There was a discussion on the mailing list. For the benefit of the bug, the issues are in the SDK and the desire to install libraries to locations other than the SDK sysroot, then use these in other builds alongside the sysroot. We don't support multiple sysroots in the SDK and can't in a build tool independent way, it just doesn't scale. Instead I suggested hardlinking a tree of sysroot files as we do in the main buildsystem.
As I was looking deeper into CMake and its toolchain file setup, I think if found a different possible solution for this problem. CMake has a variable called CMAKE_STAGING_PREFIX https://cmake.org/cmake/help/latest/variable/CMAKE_STAGING_PREFIX.html which in case of cross-compiling can be set to point to an alternative build and lookup dir in case your primary sysroot is read-only or meant to be kept clean. The variable is not set by default, and in all openembedded-core code, it is never used or set. AFAIK, CMake would include this variable in the CMAKE_FIND_ROOT_PATH, as it puts built artefacts there to keep the sysroot pristine when specified and needs to find them in the build. Due to the lines set( CMAKE_SYSROOT $ENV{OECORE_TARGET_SYSROOT} ) set( CMAKE_FIND_ROOT_PATH $ENV{OECORE_TARGET_SYSROOT} ) in OEToolchainConfig.cmake, this behaviour is overridden. While cmake would set the CMAKE_FIND_ROOT_PATH to the SYSROOT anyway, this explicitly excludes the CMAKE_STAGING_DIR from the find path. Changing these 2 lines to: set( CMAKE_SYSROOT $ENV{OECORE_TARGET_SYSROOT} ) if(DEFINED CMAKE_STAGING_PREFIX) set( CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT};${CMAKE_STAGING_PREFIX}) else() set( CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) endif() It would not change the behaviour for all users using the standard workflow at all but allows users who explicitly specify CMAKE_STAGING_PREFIX in their call to cmake to find packages built there correctly. It is quite possible that simply removing these lines (except the first, which specifies the sysroot) would have the same effect, as we most likely emulate cmake default behaviour here. If it is of interest, I can dive into the cmake source code to look up the exact default behaviour and see whether it matches.
Since this comment I had a deeper look and make will automatically consider the staging prefix as part of the root environment, except that due to make bug https://gitlab.kitware.com/cmake/cmake/-/merge_requests/6644 this doesn't work until 3 months ago. So the addition of the CMAKE_STAGING_PREFIX is not necessary. In fact while I worked through the cmake source code, the line set( CMAKE_FIND_ROOT_PATH $ENV{OECORE_TARGET_SYSROOT} ) is completely pointless as CMAKE always add the CMAKE_SYSROOT (as specified above) to the the CMAKE_FIND_ROOT_PATH. So backporting the fix above into the cmake version in openembedded and setting the CMAKE_STAGING_PREFIX already works and solves the original problem here. Removing CMAKE_FIND_ROOT_PATH $ENV{OECORE_TARGET_SYSROOT} ) can be done additionally as this statement has no effect and is misleading, but is not necessary.