在Windows上交叉编译时CMake find_package()搜索路径

时间:2019-03-08 00:49:23

标签: cmake

我正在尝试使用cmake在Windows上与arm-none-eabi-gcc交叉编译,由于某种原因,find_package()正在搜索$ PATH中所有目录的版本,而 not 我在工具链文件中提供的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_root目录。

我的项目CMakeLists.txt文件中包含以下内容:

find_package(myLIB REQUIRED)
target_link_libraries(testProject PUBLIC myLIB::myLIB)

和find_package()无法找到该库。如果我将两个版本中的任何一个都带有HINTS或PATHS,则会成功

find_package(myLIB REQUIRED HINTS /)
find_package(myLIB REQUIRED PATHS "C:/toolchains/cm0p_root")

并使用命令行选项-D CMAKE_FIND_DEBUG_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在所有Windows $ PATH变量的开头都添加了FIND_ROOT_PATH前缀!列表更长了,但是它从来没有搜索C:/toolchains/cm0p_root/,这正是我所需要的(我想为什么提示会起作用)。

如何使CMake不搜索所有这些目录?我正在交叉编译,据我所知,由于CMAKE_FIND_ROOT_PATH_MODE_PACKAGE设置为ONLY

,它应该只搜索我的“伪”根目录。

1 个答案:

答案 0 :(得分:0)

从Tsyvarev的评论中创建答案

变量CMAKE_FIND_ROOT_PATH表示要搜索的根目录,但是实际前缀是通过将目录附加到根目录来计算的。确切的实现方式可以在find package search procedure documentation中找到。

相关步骤是前两个步骤(来自CMake文档):

  1. <PackageName>_ROOT CMake变量和<PackageName>_ROOT环境变量中指定的搜索路径,其中<PackageName>是要查找的程序包。包的根变量将作为堆栈进行维护,因此,如果从查找模块中调用根包,则还将在当前包的路径之后搜索父级查找模块的根路径。如果通过NO_PACKAGE_ROOT_PATH或通过设置
  2. 可以跳过
  3. 在特定于cmake的缓存变量中指定的搜索路径。这些旨在与-DVAR=value一起在命令行上使用。这些值将解释为以分号分隔的列表。如果通过NO_CMAKE_PATH或通过将CMAKE_FIND_USE_CMAKE_PATH设置为FALSE可以跳过此操作:
    • MAKE_PREFIX_PATH
    • CMAKE_FRAMEWORK_PATH
    • CMAKE_APPBUNDLE_PATH

我们关心的变量是MAKE_PREFIX_PATH,它的初始化值是CMAKE_SYSTEM_PREFIX_PATH

用分号分隔的目录列表,这些目录指定将由find_package(),find_program(),find_library(),find_file()和find_path()命令搜索的安装前缀。每个命令都会添加其自己的文档中指定的相应子目录(如bin,lib或include)。

为此,一个更好的工具链将清除CMAKE_SYSTEM_PREFIX_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”。相反,至少到目前为止,我正在使用Conan缓存和使用预编译的依赖项。对于较小的事情,我只使用CPM,它是原生CMake FetchContent模块的不错包装