在CMake中设置构建的链接器搜索路径

时间:2016-03-07 16:20:22

标签: linux linker cmake executable

以前似乎经常会问这个问题,但似乎没有一个解决方案适用于我的情况。

我在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中设置库搜索路径吗?

3 个答案:

答案 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属性来解决此问题。

_thirdpartyExe.in
#!/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等。