Cmake C在windows上交叉编译时生成find_package()搜索路径
我正在尝试使用cmake在windows上使用arm none eabi gcc进行交叉编译,出于某种原因,find_package()正在搜索$PATH中所有目录的版本,而不是工具链文件中提供的cmake_find_ROOT_路径。具体而言,在工具链文件中,我有以下几行:Cmake C在windows上交叉编译时生成find_package()搜索路径,cmake,Cmake,我正在尝试使用cmake在windows上使用arm none eabi gcc进行交叉编译,出于某种原因,find_package()正在搜索$PATH中所有目录的版本,而不是工具链文件中提供的cmake_find_ROOT_路径。具体而言,在工具链文件中,我有以下几行: SET(CMAKE_INSTALL_PREFIX "C:/toolchains/cm0p_root" CACHE PATH "Cmake install prefix") set(CMAKE_FIND_ROOT_PATH $
SET(CMAKE_INSTALL_PREFIX "C:/toolchains/cm0p_root" CACHE PATH "Cmake install prefix")
set(CMAKE_FIND_ROOT_PATH ${CMAKE_INSTALL_PREFIX})
...
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
我使用相同的工具链编译并安装了我的库,所有内容都正确地安装到了cmp0_根目录中
My projects CMakeLists.txt文件中包含以下内容:
find_package(myLIB REQUIRED)
target_link_libraries(testProject PUBLIC myLIB::myLIB)
而find_package()找不到库。如果我将这两个版本中的任何一个添加了提示或路径,它就会成功
find_package(myLIB REQUIRED HINTS /)
find_package(myLIB REQUIRED PATHS "C:/toolchains/cm0p_root")
使用命令行选项-D CMAKE\u FIND\u DEBUG\u MODE=ON
我可以看到它正在搜索以下路径:
Checking prefix [C:/toolchains/cm0p_root/git-sdk-64/mingw64/]
Checking prefix [C:/toolchains/cm0p_root/Users/myname/]
Checking prefix [C:/toolchains/cm0p_root/Program Files/ConEmu/]
Checking prefix [C:/toolchains/cm0p_root/Python/Python36-32/]
Checking prefix [C:/toolchains/cm0p_root/Python/Python36-32/Scripts/]
Checking prefix [C:/toolchains/cm0p_root/Windows/]
Checking prefix [C:/toolchains/cm0p_root/LLVM/]
Checking prefix [C:/toolchains/cm0p_root/Program Files (x86)/IAR Systems/Embedded Workbench 8.0/common/]
Checking prefix [C:/toolchains/cm0p_root/Program Files (x86)/IAR Systems/Embedded Workbench 8.0/avr/]
Checking prefix [C:/toolchains/cm0p_root/Program Files (x86)/IAR Systems/Embedded Workbench 8.2/arm/]
Checking prefix [C:/toolchains/cm0p_root/Program Files (x86)/MSBuild/12.0/Bin/]
还有更多,但很明显,CMake将FIND_ROOT_路径作为前缀添加到所有windows$PATH变量的开头!列表要长得多,但它从不搜索C:/toolschains/cm0p\u root/
,这正是我所需要的(我猜为什么这个提示有效)
如何让CMake不搜索所有这些目录?我正在交叉编译,据我所知,它应该只搜索我的“假”根目录,因为CMAKE\u FIND\u root\u PATH\u MODE\u PACKAGE
设置为only
根据Tsyvarev的评论创建答案
变量CMAKE\u FIND\u ROOT\u PATH
表示要搜索的根目录,但实际前缀是通过将目录附加到根目录来计算的。这方面的具体实现可在中找到
相关步骤为前两步(来自CMake文档):
\u ROOT
CMake变量和\u ROOT
环境变量中指定的路径,其中
是要查找的包。包根变量作为堆栈进行维护,因此如果从find模块中调用,父级find模块的根路径也将在当前包的路径后进行搜索。如果没有传递包根路径,或者通过设置
-DVAR=value
。这些值被解释为分号分隔的列表。如果传递了NO\u CMAKE\u PATH
,或者通过将CMAKE\u FIND\u USE\u CMAKE\u PATH
设置为FALSE
,则可以跳过此操作:
MAKE_PREFIX_PATH
CMAKE\u框架\u路径
CMAKE\u APPBUNDLE\u路径
CMAKE\u SYSTEM\u PREFIX\u PATH
中的值,例如:
SET(CMAKE_INSTALL_PREFIX "C:/toolchains/cm0p_root" CACHE PATH "Cmake install prefix")
set(CMAKE_FIND_ROOT_PATH ${CMAKE_INSTALL_PREFIX})
set(CMAKE_SYSTEM_PREFIX_PATH /)
...
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
关于是否应执行此操作的注释:这项技术并没有真正奏效。这很难维护,因为对于每个不兼容的编译选项组合,都需要单独的“sysroot”。相反,至少现在,我使用缓存和使用预编译的依赖项。对于较小的东西,我只使用它作为本机CMake模块的良好包装变量
CMake_FIND_ROOT_PATH
表示要搜索的根目录,但实际前缀是通过在根目录中附加一些子目录来计算的。您可以在中找到计算前缀的算法。默认情况下,CMake不会在/
子目录下搜索,因此CMake不会将根目录解释为搜索前缀。您将/
添加到变量CMAKE\u PREFIX\u PATH
,因此您的根路径也将被视为前缀。我混淆了CMAKE\u FIND\u root\u PATH
,认为根路径在文档中的搜索路径中用作前缀。在你的评论之后重新阅读它,它会更有意义。因此,一个更好的工具链片段会添加一行:set(CMAKE\u SYSTEM\u PREFIX\u PATH/)
?我使用了CMAKE\u-SYSTEM\u-PREFIX\u-PATH
,因为它似乎更适合于工具链文件,文档说CMAKE\u-PREFIX\u-PATH
应该在项目中设置。嗯,我不确定变量CMAKE\u-SYSTEM\u-PREFIX\u-PATH
的预期用途是什么,但根据其文档,它看起来就像是一个工具链。顺便问一下,为什么你要把你的程序安装到根目录中?这就像你在C://
中安装了一样。通常,在Windows上,C:/Program Files/
用作安装前缀。您交叉编译的操作系统是什么?我不是直接安装到根目录中,而是使用GNUInstallDirs模块。因此,头被放入C:/toolschains/cm0p\u root/include
,库被放入C:/toolschains/cm0p\u root/lib
,cmake配置文件被放入C:/toolschains/cm0p\u root/share/*/
等等。我正在交叉编译裸臂皮质和AVR。我希望使用一个“sysroot”,在那里我可以安装软件包,这样我就不需要巨大的单片源代码树。例如,我使用的一个简单的实时调度器需要在每个源代码树中复制,但最好在每个体系结构中编译并“安装”它一次。set(CMAKE\u SYSTEM\u NAME Generic)
和set(CMAKE\u SYSTEM\u PROCESSOR cortex-m0plus)
应该将CMAKE\u交叉编译
设置为true。但同样,不是为linux编译,只是一个裸机设备。除非显式地将is设置为linux,否则可能在内部以windows方式构造前缀。这似乎是个坏主意,因为据我所知,大多数裸机工具链都使用gnu文件夹结构(甚至在windows上)。