如何从 CMake 工具链文件设置LD_LIBRARY_PATH?



在Linux上,我想创建一个用于交叉编译的CMake工具链文件。

编译器需要一些位于非标准目录中的共享库,因此我必须在调用它之前设置LD_LIBRARY_PATH。这在从命令行调用编译器时有效,但在从 CMake 调用编译器时无效。

我尝试通过工具链文件中的set(ENV{LD_LIBRARY_PATH} "${CMAKE_CURRENT_LIST_DIR}/<shared library directory>")设置LD_LIBRARY_PATH。但是,编译器抱怨找不到共享库。

目录:

  1. 在工具链文件中设置它不会做你想要的。

  2. 我不确定为什么在调用构建系统之前设置LD_LIBRARY_PATH对您不起作用。

  3. CMake 中有一种更惯用的方式来做你想做的事。

在工具链文件中设置它不会做你想要的

我很确定您询问如何采取的方法行不通,因为set(ENV)只设置了一个环境变量,该变量仅在配置阶段(而不是构建阶段)被 CMake 知道。下面是一个最小的可重现示例:

CMakeLists.txt:

cmake_minimum_required(VERSION 3.23)
project(Foo)
set(ENV{FOO} "hello world!")
message("$ENV{FOO} at configure time: $ENV{FOO}")
add_custom_target(echo
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_SOURCE_DIR}/echo.cmake"
VERBATIM
)

echo.cmake:

cmake_minimum_required(VERSION 3.23)
message("$ENV{FOO} at build time: $ENV{FOO}")

运行以下命令:

$ cmake -S . -B build --fresh
<...>
$ENV{FOO} at configure time: hello world!
<...>
$ cmake --build build/ --target echo
$ENV{FOO} at build time: 

由于环境变量是"向下传递"到子进程而不是向上传递的,因此当您执行set(ENV)时,这只是在执行配置步骤的 CMake 进程中设置它(上面示例中由cmake -S ...命令调用的那个)。如示例所示,CMake 不会做任何花哨的事情来在构建时将这些环境变量告知生成的构建系统。

我不确定为什么在调用构建系统之前设置LD_LIBRARY_PATH对您不起作用

所以我必须在调用它之前设置LD_LIBRARY_PATH。它在从命令行调用编译器时有效,但不能从 CMake 调用。

只要您导出变量以使其可用于 shell 的子进程(使用适用于您正在使用的任何 shell 的正确机制),这应该可以工作。一个最小的可重现示例将在此处有所帮助。

CMake 中有一种更惯用的方式来做你想做的事

尝试使用find_library()命令。它执行其名称所说的在配置时(而不是构建时)执行的操作。如果你使用它,你还将获得你的构建系统更加跨平台的好处。

它有几种调整搜索库的方式。您可以在官方文档中准确了解它的工作原理。

对于此处的情况,指导库搜索的合适配置点之一是CMAKE_LIBRARY_PATH变量,尽管正如您将读到的,您还可以使用其他配置点。

最新更新