我正在尝试使用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
答案 0 :(得分:0)
从Tsyvarev的评论中创建答案
变量CMAKE_FIND_ROOT_PATH
表示要搜索的根目录,但是实际前缀是通过将目录附加到根目录来计算的。确切的实现方式可以在find package search procedure documentation中找到。
相关步骤是前两个步骤(来自CMake文档):
- 在
可以跳过<PackageName>_ROOT
CMake变量和<PackageName>_ROOT
环境变量中指定的搜索路径,其中<PackageName>
是要查找的程序包。包的根变量将作为堆栈进行维护,因此,如果从查找模块中调用根包,则还将在当前包的路径之后搜索父级查找模块的根路径。如果通过NO_PACKAGE_ROOT_PATH
或通过设置- 在特定于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模块的不错包装