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

Respect CMAKE_FIND_ROOT_PATH in package.tools.cmake when cross compiling #2037

Closed
xq114 opened this issue Feb 8, 2022 · 10 comments
Closed

Comments

@xq114
Copy link
Contributor

xq114 commented Feb 8, 2022

你在什么场景下需要该功能?

xmake-io/xmake-repo#987

https://github.com/xmake-io/xmake-repo/runs/5105301674?check_suite_focus=true

-- Found ZLIB: D:/a/_temp/msys64/mingw64/lib/libz.dll.a (found version "1.2.11") 

在交叉编译mingw-macos时,cmake无法正常找到zlib;在交叉编译mingw-msys2时,cmake找到的zlib是mingw自带的zlib而不是xmake安装的zlib

描述可能的解决方案

找不到原因是没注意CMAKE_FIND_ROOT_PATH变量的使用。根据cmake文档以及源代码

https://github.com/Kitware/CMake/blob/201d8c429843e9e57f833fcca8794f532e6d3028/Source/cmFindCommon.cxx#L255-L277

当设置CMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY时(目前xmake会在cross-compiling时这样设置),CMAKE_PREFIX_PATH以及其他各种搜索路径都会以CMAKE_FIND_ROOT_PATH作为基准,原有的路径中"/"会被替换为CMAKE_FIND_ROOT_PATH,替换完之后的路径压根不存在,这样cmake自然也就找不到了。因此要让cmake正确找到cross-compiling的第三方库,应该在cross compiling的时候把原来的CMAKE_PREFIX_PATH中所有路径改成相对于CMAKE_FIND_ROOT_PATH的路径,而不能沿用系统绝对路径。

举例,如果CMAKE_FIND_ROOT_PATH为/usr/toolchains/mingw/,原本的一个第三方依赖library安装在/home/.xmake/packages/...,那么应该设置-DCMAKE_PREFIX_PATH=/../../../home/.xmake/packages/...,这样替换完的搜索目录就是/usr/toolchains/mingw/../../../home/.xmake/packages/...,刚好回到原来的目录。这里CMAKE_PREFIX_PATH根据文档既可设置为环境变量,也可设置为cmake变量从命令行传入。

在windows下cmake这个机制会把盘符也替换,因此不在同一个盘的文件肯定找不到。这个时候只能在CMAKE_FIND_ROOT_PATH里面加上C:\Users\<name>\.xmake\packages然后把CMAKE_PREFIX_PATH中所有路径改成相对于C:\Users\<name>\.xmake\packages的路径才能解决,可以先不考虑windows上的cross compiling

描述你认为的候选方案

https://github.com/xmake-io/xmake-repo/blob/f600b7bae6b4d9f817325ec24397c9bc2dce8d5a/packages/a/assimp/xmake.lua#L65-L76

类似这样去手动patch每一个cmake文件,确实也可以用,但太麻烦

@waruqi
Copy link
Member

waruqi commented Feb 8, 2022

走相对路径也不太通用,而且 --mingw/--sdk 不一定会被设置,比如 mingw 工具链已经在 path 中了,CMAKE_FIND_ROOT_PATH 有可能是空的

还有你说的 win 跨盘符问题

我忘了之前为啥设置 only 模式了,但应该有用,你可以改成其他模式试试

等回头有空看看 有没有更好地处理方式

@xq114
Copy link
Contributor Author

xq114 commented Feb 8, 2022

我忘了之前为啥设置 only 模式了,但应该有用,你可以改成其他模式试试

这个肯定要设置的,否则cmake会找到本系统的库,这个库交叉工具链没法用。问题就是设置成only之后不仅排除了系统库,xmake的库也一并被排除了

@xq114
Copy link
Contributor Author

xq114 commented Feb 8, 2022

把XMAKE_PKG_INSTALLDIR加入CMAKE_FIND_ROOT_PATH中应该可以解决这个问题,毕竟xmake安装的package都是相对于XMAKE_PKG_INSTALLDIR的。我回头看看conan怎么解决的这个问题

@xq114
Copy link
Contributor Author

xq114 commented Feb 8, 2022

https://github.com/conan-io/conan/blob/HEAD/conan/tools/cmake/toolchain.py#L445-L463

看起来conan直接把CMAKE_FIND_ROOT_PATH_MODE_LIBRARY这些全设成BOTH了,他们应该是相信cmake会先找到他们自己的包,而不是系统上非交叉编译的包

@waruqi
Copy link
Member

waruqi commented Feb 8, 2022

要么你也先本地改成 both 试试,看看有效么。

@waruqi
Copy link
Member

waruqi commented Feb 8, 2022

把XMAKE_PKG_INSTALLDIR加入CMAKE_FIND_ROOT_PATH中应该可以解决这个问题,毕竟xmake安装的package都是相对于XMAKE_PKG_INSTALLDIR的。我回头看看conan怎么解决的这个问题

这样,CMAKE_PREFIX_PATH 里面还是要改,得去掉根目录,弄成相对的,还有 mingw 等工具链自带的一些 /mingw64/lib 下的库就找不到了吧。。

@waruqi
Copy link
Member

waruqi commented Feb 8, 2022

https://github.com/conan-io/conan/blob/HEAD/conan/tools/cmake/toolchain.py#L445-L463

看起来conan直接把CMAKE_FIND_ROOT_PATH_MODE_LIBRARY这些全设成BOTH了,他们应该是相信cmake会先找到他们自己的包,而不是系统上非交叉编译的包

我 mac/mingw 上本地试了下,both 确实是找到了 xmake-repo 的 zlib 而不是系统的 zlib

@waruqi
Copy link
Member

waruqi commented Feb 8, 2022

我暂时先切到 both 了,你先试试,回头有问题,再继续改进

@xq114
Copy link
Contributor Author

xq114 commented Feb 9, 2022

先这样吧,如果之后碰到问题再改

@xq114 xq114 closed this as completed Feb 9, 2022
@waruqi
Copy link
Member

waruqi commented Mar 1, 2022

备注:

改成 both 虽然问题不大,但多少还有有点不可靠,如果 add_deps 没加,系统库又存在,就会找到系统库去。。按理 add_deps,也不应该找系统库,顶多报 库找不到。xmake-io/xmake-repo#1023 (comment)

尽管问题不大,补上 add_deps ,或者禁用相关依赖,就能解,就是对用户做包,不太好排查问题。。

不过如果 add_deps 加了,查找顺序倒是的确优先 add_deps ,然后系统库。。

先这么用了,后期可以看看有没有更好更可靠的方案

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