【问题标题】:How do I instruct CMake to look for libraries installed by MacPorts?如何指示 CMake 查找 MacPorts 安装的库?
【发布时间】:2009-09-28 15:37:20
【问题描述】:

我正在尝试在 MacOS X 上构建我们的一些软件,这些软件旨在仅在 Linux 上运行。我们正在使用 CMake,并且我安装了 MacPorts,因此我可以轻松获取 CMake 以及一些第三方库我们依赖。

现在的问题是,默认情况下 CMake 似乎不会从 MacPorts 中查找库,因此我们的几个目标被禁用,因为它无法找到所有位于 /opt/local 中的依赖项.

如何指示 CMake 也从 MacPorts 中查找包含和库?

【问题讨论】:

  • 您是否考虑过简单地将您的项目添加到 MacPorts 存储库中?这样所有正确的标志都是从 MacPorts 传入的。

标签: macos cmake macports


【解决方案1】:

将 /opt/local/lib 和任何其他可能的安装路径添加到 cmake 在 CMakeLists.txt 文件中搜索的路径集:

set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} /opt/local/lib)

这会将 /opt/local/lib 附加到 cmake 搜索库的路径集。设置变量后,此CMAKE_LIBRARY_PATH 技术将影响所有find_library 命令。

对于更外科的、逐库的方法,请修改各个 find_library 命令:

find_library(Foo foo
    PATHS /opt/local/lib)

请注意,这不是硬编码 /opt/local/lib 作为查找库的唯一位置。相反,它只是将 /opt/local/lib 附加到要搜索库的位置集。我经常最终添加许多这样的路径,涵盖在我所知道的所有机器上观察到的位置。有关此主题的更多变体,请参阅find_library documentation

您可能还希望更改CMAKE_INCLUDE_PATH,这会影响find_file()find_path() 命令的行为。

【讨论】:

  • 为了更好的语法:list(APPEND CMAKE_LIBRARY_PATH /opt/local/lib)
  • 您可能还想记录 NO_DEFAULT_PATH,因为您可能想专门使用 macports 位置的 lib,而不是搜索常规的。
  • 这个答案浪费了我很多时间 - cmake 似乎很乐意忽略这个变量(或者它可能用于完全不同的目的)。只是想警告人们,因为实际(正确)答案是(令人困惑)较少赞成票的答案:使用link_directories
【解决方案2】:

我为“Darwin”添加了一个工具链文件,它添加了必要的包含和库路径。我希望有一些更自动化的东西,但至少它解决了问题。

darwin.cmake

SET(CMAKE_SYSTEM_NAME Darwin)

# Add MacPorts
INCLUDE_DIRECTORIES(/opt/local/include)
LINK_DIRECTORIES(/opt/local/lib)

【讨论】:

  • 不要硬编码 /opt/local。这可以是用户将 MacPorts 安装到的任何目录。
  • 通常不是一个好主意。让您的 PATH 找到您需要包含的库并专门添加库名称要好得多。那么每个 UNIX 平台都是不同的。
  • 我同意,但这不是最佳解决方案,但这是我能想到的唯一可行的解​​决方案。
  • @Nerdling,您能否提供一种动态方式来检索适当的 MacPorts 前缀,而无需对其进行硬编码?
【解决方案3】:

CMake 需要尊重DYLD_LIBRARY_PATH 环境变量,它相当于Linux 上的LD_LIBRARY_PATH 环境变量。您的 DYLD_LIBRARY_PATH 需要有正确的路径才能找到 MacPorts 安装的库。

【讨论】:

  • LD_LIBRARY_PATH 应该只用于调试和测试。值得注意的是,如果您的可执行文件是 setuid 或 setgid,它将被忽略。构建信息需要与项目文件中的其他构建信息保持一致。
【解决方案4】:

根据@Nerdling 的“不要硬编码” 对已接受解决方案的评论,这是检测 MacPorts 前缀路径的建议。

MyModule.cmake

# Detect if the "port" command is valid on this system; if so, return full path
EXECUTE_PROCESS(COMMAND which port RESULT_VARIABLE DETECT_MACPORTS OUTPUT_VARIABLE MACPORTS_PREFIX ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)

IF (${DETECT_MACPORTS} EQUAL 0)
    # "/opt/local/bin/port" doesn't have libs, so we get the parent directory
    GET_FILENAME_COMPONENT(MACPORTS_PREFIX ${MACPORTS_PREFIX} DIRECTORY)

    # "/opt/local/bin" doesn't have libs, so we get the parent directory
    GET_FILENAME_COMPONENT(MACPORTS_PREFIX ${MACPORTS_PREFIX} DIRECTORY)

    # "/opt/local" is where MacPorts lives, add `/lib` suffix and link
    LINK_DIRECTORIES(${LINK DIRECTORIES} ${MACPORTS_PREFIX}/lib)

    MESSAGE("WINNING!: ${MACPORTS_PREFIX}/lib")
ENDIF()

# Recommendation, also add a "brew --prefix" custom command to detect a homebrew build environment

【讨论】:

    【解决方案5】:

    使用 MacPorts 安装 cmakepkgconfig

    port install cmake pkgconfig
    

    使用 pkgconfig 查找库的 CMake 构建文件将使用 MacPorts 安装的 pkgconfig,当然它会为 MacPorts 安装的库提供正确的搜索路径。

    假设 CMake 构建文件使用 FindPkgConfig 模块。例如,我在一个项目中有一个FindLibuv.cmake 模块,它的开头是这样的。

    find_package (PkgConfig)
    pkg_check_modules (PC_Libuv QUIET libuv)
    

    【讨论】:

      猜你喜欢
      • 2011-02-13
      • 2015-07-17
      • 1970-01-01
      • 2015-06-09
      • 2015-07-03
      • 1970-01-01
      • 2011-06-26
      • 2013-05-28
      • 2015-07-12
      相关资源
      最近更新 更多