【问题标题】:CMake FIND_PACKAGE succeeds but returns wrong pathCMake FIND_PACKAGE 成功但返回错误的路径
【发布时间】:2012-04-14 10:58:40
【问题描述】:

我正在尝试使用我的 CMakeLists.txt 中的以下代码将 CMake 2.8.6 链接到 boost::program_options

FIND_PACKAGE(Boost COMPONENTS program_options REQUIRED)
INCLUDE_DIRECTORIES (${Boost_INCLUDE_DIR})

ADD_EXECUTABLE (segment segment.cpp)
TARGET_LINK_LIBRARIES (segment ${Boost_LIBRARIES})

find 命令似乎成功了,但将错误的目录传递给了链接器。包实际上在:

`/usr/lib64/libboost_program_options-mt.so.5`

CMakeFiles/segment.dir/link.txt 列出了以下内容:

/cm/shared/apps/gcc/4.4.6/bin/c++       CMakeFiles/segment.dir/segment.cpp.o  -o segment -rdynamic /usr/lib64/lib64/libboost_program_options-mt.so.5 -lpthread -lrt -Wl,-rpath,/usr/lib64/lib64

注意路径中额外的lib64。此外,路径前面的 -l 标志似乎丢失了。

运行 CMake 时,它​​报告它正确找到了包,并且 {$Boost_LIBRARIES} 变量似乎列出了正确的库:

Boost  found.
Found Boost components:
   program_options
${Boost_LIBRARIES} - optimized;boost_program_options-mt-shared;debug;boost_program_options-mt-shared-debug

生成的 CMakeCache.txt 文件开头为:

//The directory containing a CMake configuration file for Boost.
Boost_DIR:PATH=/usr/lib64/boost

//Boost include directory
Boost_INCLUDE_DIR:FILEPATH=/usr/include

这似乎是正确的。但是当运行 make 它使用上面 link.txt 中的路径时,我得到了错误:

make[2]: *** No rule to make target `/usr/lib64/lib64/libboost_program_options-mt.so.5', needed by `segment'.  Stop.
make[1]: *** [CMakeFiles/segment.dir/all] Error 2
make: *** [all] Error 2

什么可能导致将子目录额外注入到路径中?什么可能导致以这种方式生成 link.txt?我该如何修复它(或解决它)?

【问题讨论】:

  • 您能否在 CMakeLists.txt 中的 FIND_PACKAGEFIND_PACKAGE 之后添加 SET(Boost_DEBUG 1)MESSAGE("\${Boost_LIBRARIES} - ${Boost_LIBRARIES}")。然后删除您的 CMakeCache.txt,运行 CMake 并将输出粘贴为您的问题的编辑。
  • @Fraser 似乎找到了正确的库,这里是输出(也包括在上面):${Boost_LIBRARIES} - optimized;boost_program_options-mt-shared;debug;boost_program_options-mt-shared-debug
  • 作为一种解决方法,如何手动设置链接路径?

标签: c++ boost cmake


【解决方案1】:

当使用带有 cmake-2.8.6-rc2 或更高版本的某些旧版本的 boost 时会出现此问题,其中 boost 包查找代码已更改。

可以通过在 cmake 命令行中指定 -DBoost_NO_BOOST_CMAKE=ON 来解决此问题。

实际引入这个问题的commit是7da796d1fdd7cca07df733d010cd343f6f8787a9,可以是viewed here

【讨论】:

    【解决方案2】:

    问题在于 boost-devel 分布式文件:/usr/lib64/boost/Boost-relwithdebinfo.cmake

    cmake-2.6 包根本不使用这个文件,因为 FindBoost.cmake 文件返回(正确的)完整路径来提升库。 cmake28-2.8.8 FindBoost.cmake 文件返回类似“boost_date_time-mt-shared”的库字符串,它们是在 /usr/lib64/boost/Boost-relwithdebinfo.cmake 中定义的目标。

    在 /usr/lib64/boost/Boost-relwithdebinfo.cmake 的最顶部,从 cmake 文件本身的位置定义了一个名为 _IMPORT_PREFIX 的变量,然后像这样使用:

    #----------------------------------------------------------------
    # Generated CMake target import file for configuration "RelWithDebInfo".
    #----------------------------------------------------------------
    
    # Commands may need to know the format version.
    SET(CMAKE_IMPORT_FILE_VERSION 1)
    
    # Compute the installation prefix relative to this file.
    GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
    GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
    
    # Import target "boost_date_time-static" for configuration "RelWithDebInfo"
    SET_PROPERTY(TARGET boost_date_time-static APPEND PROPERTY IMPORTED_CONFIGURATIONS RELWITHDEBINFO)
    SET_TARGET_PROPERTIES(boost_date_time-static PROPERTIES
      IMPORTED_LOCATION_RELWITHDEBINFO "${_IMPORT_PREFIX}/lib64/libboost_date_time.a"
      )
    

    这会将 _IMPORT_PREFIX 设置为“/usr/lib64”,它与另一个包含 /lib64/ 的字符串连接。我发现如果我只是将文件更改为包含第三个 GET_FILENAME_COMPONENT 调用,它就可以正常工作。像这样:

    #----------------------------------------------------------------
    # Generated CMake target import file for configuration "RelWithDebInfo".
    #----------------------------------------------------------------
    
    # Commands may need to know the format version.
    SET(CMAKE_IMPORT_FILE_VERSION 1)
    
    # Compute the installation prefix relative to this file.
    GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
    GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
    GET_FILENAME_COMPONENT(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
    
    # Import target "boost_date_time-static" for configuration "RelWithDebInfo"
    SET_PROPERTY(TARGET boost_date_time-static APPEND PROPERTY IMPORTED_CONFIGURATIONS RELWITHDEBINFO)
    SET_TARGET_PROPERTIES(boost_date_time-static PROPERTIES
      IMPORTED_LOCATION_RELWITHDEBINFO "${_IMPORT_PREFIX}/lib64/libboost_date_time.a"
      )
    

    【讨论】:

    • cmake 比大多数 autohell 更好的原因是什么?在我读完这篇文章之前,我已经浪费了数周的时间来拔头发。
    【解决方案3】:

    这似乎是 CentOS 上 CMake 2.8.6 的问题。对 2.6.4 或 2.8.3 执行相同操作时,它可以正常工作。在 OS X 上使用 2.8.7 时,它也可以正常工作。

    【讨论】:

      【解决方案4】:

      我在使用 CentOS 64 位 6.2 的预编译 cmake 版本 2.8.8 上也看到了问题

      【讨论】:

      • 并且退回到 2.8.3 也修复了它。
      【解决方案5】:

      我在带有 boost-1.41.0-18.el6.x86_64 的 cmake 版本 2.8.11.2 上注意到了这个问题

      批准的答案似乎并不令人满意,因为将此定义附加到我得到的 cmake 运行时:

      CMake 警告: 项目未使用手动指定的变量:

      Boost_NO_BOOST_CMAKE
      

      由于没有充分参与 stackoverflow,我似乎无法发表评论或投反对票。这是先有鸡还是先有蛋的问题!

      我似乎也不赞成 Kai Meyer 的解释。但是,我认为这确实解释了问题。

      从我收集的信息看来,总而言之,CMake 提供的 FindBoost.cmake 似乎突然找不到 Boost,因此查找代码现在正在通过为 cmake 提供的 boost 脚本进行搜索,而该脚本又具有一个错误,似乎没有返回正确的路径。

      【讨论】:

        【解决方案6】:

        从 AUR 构建包时,以下前缀有助于找到 Boost

        BOOST_ROOT=/usr
        

        示例:

        BOOST_ROOT=/usr makepkg -si
        

        【讨论】:

          猜你喜欢
          • 2018-09-23
          • 1970-01-01
          • 1970-01-01
          • 2021-10-02
          • 2011-11-24
          • 1970-01-01
          • 2020-01-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多