这个问题似乎以前经常被问到,但似乎没有一个解决方案适用于我的情况。
我处于 CMake/Linux 环境中,必须在 build 步骤期间运行可执行二进制文件(特别是
protoc
)。
此二进制文件需要一个库,但它未安装(并且不能)在标准目录(如
/usr
)中,因此无法找到该库。
不幸的是,我无法操纵
protoc
调用,因为它嵌入在第 3 方脚本中。
我现在可以在每个
LD_LIBRARY_PATH
之前设置 make
或在系统范围内设置它,但这非常不方便,尤其是在涉及进行构建的 IDE 或具有连续构建环境的分布式构建场景时。
我尝试通过
设置
LD_LIBRARY_PATH
set(ENV{LD_LIBRARY_PATH} "/path/to/library/dir")
但这似乎在构建步骤中没有效果。
所以我的问题是:我可以在 CMake 中设置构建期间使用的库搜索路径吗?
试试这个
SET(ENV{LD_LIBRARY_PATH} "/path/to/library/dir:$ENV{LD_LIBRARY_PATH}")
我还使用了这个肮脏的技巧来临时更改一些环境变量:
LD_LIBRARY_PATH="/path/to/library/dir:$LD_LIBRARY_PATH" cmake ...
执行此行后
LD_LIBRARY_PATH
在当前 shell 中不会发生更改。
此外,我认为在调用
LD_LIBRARY_PATH
之前更改 cmake
也不错:
export LD_LIBRARY_PATH=...
它不会改变系统范围内的任何内容,但它将用于您当前的 shell、当前的构建过程。 CI 构建也是如此。您可以保存变量并在
cmake
调用后恢复它:
MY_LD=$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=...
cmake...
export LD_LIBRARY_PATH=$MY_LD
我最近遇到了一个有点类似的问题。 我的解决方案是将源文件合并到每个命令中,以设置适当的环境。 例如,这个自定义命令:
add_custom_command(
OUTPUT some_output
COMMAND some_command
ARGS some_args
DEPENDS some_dependencies
COMMENT "Running some_command some_args to produce some_output"
)
会变成:
set(my_some_command_with_environment "source my_environment_script.sh && some_command")
add_custom_command(
OUTPUT some_output
COMMAND bash
ARGS -c "${my_some_command_with_environment} some_args"
DEPENDS some_dependencies
COMMENT "Running some_command some_args to produce some_output"
VERBATIM
)
显然,这有一些缺点:
它依赖于可用的 bash shell。
它为每个命令调用提供环境脚本(性能问题),您将必须更改依赖于该环境变量的所有命令调用。
它改变了命令跟随 COMMAND 且参数跟随 ARGS 的正常语法,因为现在“真实”命令是 ARGS 的一部分。
我的 CMake-Fu 已被证明不足以找到语法上更好的方法来执行此操作,但也许有人可以评论更好的方法。
对于第三方库提供的可执行文件,我也遇到了类似的问题。该二进制文件链接到发行版未提供的库,但所需的库包含在第三方库的 libs 目录中。
所以运行
LD_LIBRARY_PATH=/path/to/thirdparty/lib /path/to/thirdparty/bin/executable
有效。但是包配置脚本没有设置可执行文件来搜索运行时依赖项,因此当 CMake 尝试运行可执行文件时,CMake 会抱怨。我通过配置引导脚本并将
/path/to/thirdparty/lib
属性替换为配置的引导脚本来解决这个问题。
_thirdpartyExe.in
IMPORTED_LOCATION
CMakeLists.txt
#!/bin/bash
LD_LIBRARY_PATH=@_thirdpartyLibs@ @_thirdpartyExe_LOCATION@ "$@"
老实说,我认为这是一种黑客攻击和临时的权宜之计,直到我修复第三方库本身。但据我尝试过,这似乎适用于我使用过的所有 IDE,Eclipse、VSCode、Ninja、QtCreator,...等