以前似乎经常会问这个问题,但似乎没有一个解决方案适用于我的情况。
我在CMake / Linux环境中,必须在构建步骤(特别是protoc
)中运行可执行二进制文件。
这个二进制文件需要一个库,但未安装(并且不能)在/usr
等标准目录中,因此无法找到库。
不幸的是,我无法操纵protoc
调用,因为它嵌入在第三方脚本中。
我现在可以在每个LD_LIBRARY_PATH
之前设置make
或者在系统范围内设置LD_LIBRARY_PATH
,但这非常不方便,尤其是涉及构建发生的IDE或具有连续构建环境的分布式构建方案时。
我尝试通过
设置set(ENV{LD_LIBRARY_PATH} "/path/to/library/dir")
if (Database.Exists(connectionString))
{
// do something
}
else
{
// do something else
}
但这似乎在构建步骤中没有效果。
所以我的问题是:我可以在构建过程中使用的CMake中设置库搜索路径吗?
答案 0 :(得分:0)
试试这个
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
答案 1 :(得分:0)
我最近碰到了一个类似的问题。 我的解决方案是将一个将适当环境设置的文件合并到每个命令中。 例如,此自定义命令:
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,因为现在'real'命令是ARGS的一部分。
我的CMake-Fu已经证明不足以找到一种语法上更好的方法,但也许有人可以用更好的方式发表评论。
答案 2 :(得分:0)
我对第三方库提供的可执行文件有类似的问题。二进制文件链接到发行版未提供的库,但所需的库包含在第三方库的libs目录中。
因此运行LD_LIBRARY_PATH=/path/to/thirdparty/lib /path/to/thirdparty/bin/executable
是可行的。但是,程序包配置脚本未将可执行文件设置为在/path/to/thirdparty/lib
中搜索运行时相关程序,因此,当CMake尝试运行可执行文件时,CMake会抱怨。
我通过配置引导脚本并用配置的引导脚本替换IMPORTED_LOCATION
属性来解决此问题。
#!/bin/bash
LD_LIBRARY_PATH=@_thirdpartyLibs@ @_thirdpartyExe_LOCATION@ "$@"
CMakeLists.txt
find_package(ThirdPartyLib)
get_target_property(_component ThirdPartyLib::component LOCATION)
get_filename_component(_thirdpartyLibs ${_component} DIRECTORY)
get_target_property(_thirdpartyExe_LOCATION ThirdPartyLib::exe IMPORTED_LOCATION)
configure_file(
${CMAKE_CURRENT_LIST_DIR} _thirdpartyExe.in
${CMAKE_BINARY_DIR}/thirdpartyExeWrapper @ONLY
)
set_target_properties(ThirdPartyLib::exe PROPERTIES IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/thirdpartyExeWrapper)
老实说,在我修复第三方库本身之前,我将其视为黑客行为和临时停止漏洞。但是据我所试,这似乎可以在我扔给它的所有IDE上正常运行,例如Eclipse,VSCode,Ninja,QtCreator等。