Provide absolute paths to dependencies with `CMAKE_FIND_ROOT_PATH` search (during cross-compilation, wasm)

Was trying to rework cmake file to use find_package configs instead of providing paths to each dependency with explicit DEPENDENCY_INCLUDE variables and I’ve stumbled upon issue when using those cmake-configs during cross-compilation (emscripten in particular).

During cross-compilation emscripted is completely disabling sarch by usual PATH and replacing it with root-path search, bases on roots provided in CMAKE_FIND_ROOT_PATH.

Before cross-compilation I was just providing dependencies installations paths to -DCMAKE_PREFIX_PATH, but with root path mode it’s not an option anymore.

Searching similar discussions, I’ve found one issue on emscripten (find_package not works in emcmake · Issue #13310 · emscripten-core/emscripten · GitHub) and basic options that I’ve found are:

  • install dependency to the provided emscripten sysroot
  • link dependency folder to sysroot, but then also need to add dependency folder name to CMAKE_PREFIX_PATH, so it will be combined with root during search
  • wrap every find_package with some root-path-hack macro (e.g. doset(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER) before search and then restore original value).

And both are a bit messsy, if I want to keep dependencies separately (each to have it’s own folder) and avoid linking them to some new root for build too succeed.

And investigating I’ve found two ways to do it - basically to either hack prefix or to hack root path:

  • If previously you provided list of dependencies to CMAKE_PREFIX_PATH, now you can just use the same list but send it to CMAKE_FIND_ROOT_PATH. Caveat is that you need to also add // to your CMAKE_PREFIX_PATH, so root itself is also will be searched.

    The advantage is that it will have a low chance to accidentally pick up dependencies that use different architecture.
    The disadvantages - in case if some search destined to fail, it might search enourmous amount of paths for nothing (combining each root with each prefix from path).
    Another possible problem is that it’s relying on // - in theory / would work for this too, but it’s discarded by cmake (see code), so it might be fragile thing to rely on in the future - if cmake will add path normalization in this case and will discard // too.

    # Before cross-compilation.
    cmake .. -DCMAKE_PREEFIX_PATH=/path/to/dep/
    # With cross-compilation
    cmake .. -DCMAKE_FIND_ROOT_PATH=/path/to/dep/ -DCMAKE_PREFIX_PATH=//
    
  • You can keep using CMAKE_FIND_ROOT_PATH and provide / as additional CMAKE_FIND_ROOT_PATH. Which defeats the whole purpose of using root-path search in the first place, but it might work if you’re sure that all dependencies are provided in the CMAKE_PREFIX_PATH.

    cmake .. -DCMAKE_FIND_ROOT_PATH=/ -DCMAKE_PREFIX_PATH=/path/to/dep/
    

Any other workarounds that’s typically used during cross-compilation?