为什么cmake在64位系统上找到32位库而不是64位库?

时间:2016-03-16 18:32:01

标签: c++ c linux build cmake

问题描述

我正在努力将几个代码库从Red Hat 5移植到6,我遇到了一个cmake问题,我完全被这个问题困扰了。

Cmake始终在/usr/lib下找到32位版本的库而不是RHEL6系统上/usr/lib64下的64位版本,同时它正确检测RHEL5系统上的lib64版本

最小示例

例如,我有一个非常小的CMakeLists.txt文件:

cmake_minimum_required(VERSION 2.8)

find_library(XTEST X11)
message("Found X11 at ${XTEST}")

在RHEL6系统上,运行cmake会导致:

$ cmake ..
-- The C compiler identification is GNU 4.4.7
-- The CXX compiler identification is GNU 4.4.7
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
Found X11 at /usr/lib/libX11.so
-- Configuring done
-- Generating done
-- Build files have been written to: $HOME/software/64bit_problem/build

(这里的关键部分是Found X11 at /usr/lib/libX11.so行)

但是,如果我在RHEL5系统上执行相同操作,它会正确检测/usr/lib64/版本:(请注意,我正在清除运行期间的CMakeCache.txt和其他临时cmake文件。)

$ cmake ..
-- The C compiler identification is GNU 4.1.2
-- The CXX compiler identification is GNU 4.1.2
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
Found X11 at /usr/lib64/libX11.so
-- Configuring done
-- Generating done
-- Build files have been written to: $HOME/software/64bit_problem/build

故障排除信息

两个系统上都存在/usr/lib64个版本的库。以下是RHEL6系统的列表:

$ ls /usr/lib64/libX11.so*
/usr/lib64/libX11.so.6  /usr/lib64/libX11.so.6.3.0

在RHEL5系统上:

$ ls /usr/lib64/libX11.so*
/usr/lib64/libX11.so.6  /usr/lib64/libX11.so.6.3.0

只是为了确认/usr/lib确实是32位版本(同样,它不是指向另一个位置的符号链接):

$ file /usr/lib/libX11.so*
/usr/lib/libX11.so:       symbolic link to `libX11.so.6.3.0'
/usr/lib/libX11.so.6:     symbolic link to `libX11.so.6.3.0'
/usr/lib/libX11.so.6.3.0: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped

$ file /usr/lib64/libX11.so*
/usr/lib64/libX11.so.6:     symbolic link to `libX11.so.6.3.0'
/usr/lib64/libX11.so.6.3.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, stripped

这可能是由于某个地方的环境设置,但我有点难过到哪里。我没有设置LD_LIBRARY_PATHLD_RUN_PATHLDFLAGSCFLAGSCXXFLAGS也是如此。我的用户环境应该是相同的,因为我的$ HOME是两个机器上相同的NFS共享。

/usr/lib不在我的$PATH中,无论如何,将我的路径限制为最小子集似乎没有帮助:

$ export PATH=/bin:/usr/bin:$HOME/local/bin

$ cmake ..
<snip>
Found X11 at /usr/lib/libX11.so
-- Configuring done
<snip>

@SergyA有一个很好的建议,即使用ltrace检查访问哪些环境变量。 strace没有发现我能看到的任何诊断信息,但是ltrace很好地显示了环境变量访问。这是一个快速摘要:

$ ltrace -o ltrace_output cmake ..

$ grep getenv ltrace_output
getenv("PWD")                                                    = "$HOME/software/64bit_problem"
getenv("PATH")                                                   = "/bin:/usr/bin:$HOME/local/bin"
getenv("CMAKE_ROOT")                                             = NULL
getenv("MAKEFLAGS")                                              = NULL
getenv("VERBOSE")                                                = NULL
getenv("CFLAGS")                                                 = NULL
getenv("LDFLAGS")                                                = NULL
getenv("LDFLAGS")                                                = NULL
getenv("LDFLAGS")                                                = NULL
getenv("CXXFLAGS")                                               = NULL
getenv("LDFLAGS")                                                = NULL
getenv("LDFLAGS")                                                = NULL
getenv("LDFLAGS")                                                = NULL

cmake - 特定的故障排除

两台机器上的cmake版本是相同的(事实上,它是相同的可执行文件,原因我省略了简洁):

$ cmake --version
cmake version 2.8.11.2

$ which cmake
$HOME/local/bin/cmake

我已尝试明确启用FIND_LIBRARY_USE_LIB64_PATHS,但这似乎没有什么区别:

cmake_minimum_required(VERSION 2.8)

set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS ON)

find_library(XTEST X11)
message("Found X11 at ${XTEST}")

正如@Ravi所提到的,这更可能是由于CMAKE_LIBRARY_PATH的某些问题,但它没有设置,并且将其更改为环境变量或cmake变量似乎没有帮助。但是,我完全承认我基本上不了解各种cmake配置变量,所以很可能我在这里遗漏了一些明显的东西。

我最近意识到的一件事是它不是所有的库......例如:

cmake_minimum_required(VERSION 2.8)

find_library(PNGTEST png)
message("Found libpng at ${PNGTEST}")

查找/usr/lib64/libpng.so而不是/usr/lib/libpng.so

这让我觉得它无论如何都是特定于cmake的东西。

find_package代替find_library

鉴于我上面提到的特定于库的问题,我想尝试找到整个X11包而不是单个库(这正是我正在使用的代码库应该做的事情)。

然而,我得到的结果更令人困惑......似乎是在检测64位和32位库的混合?例如:

cmake_minimum_required(VERSION 2.8)

FIND_PACKAGE(X11 REQUIRED)

message("X11_LIBRARIES: ${X11_LIBRARIES}")

我们会得到:

$ cmake ..
<snip>
-- Looking for XOpenDisplay in /usr/lib/libX11.so;/usr/lib/libXext.so
-- Looking for XOpenDisplay in /usr/lib/libX11.so;/usr/lib/libXext.so - not found
<snip>
-- Found X11: /usr/lib/libX11.so
X11_LIBRARIES: /usr/lib64/libSM.so;/usr/lib64/libICE.so;/usr/lib/libX11.so;/usr/lib/libXext.so
-- Configuring done
<snip>

但是,如果我们看一下X11_LIBRARIES中的这些特定库,它们就是32位和64位版本的混合!

$ file /usr/lib64/libSM.so.6.0.1
/usr/lib64/libSM.so.6.0.1: ELF 64-bit LSB shared object, x86-64, <snip>

$ file /usr/lib64/libICE.so.6.3.0
/usr/lib64/libICE.so.6.3.0: ELF 64-bit LSB shared object, x86-64, <snip>

$ file /usr/lib/libX11.so.6.3.0
/usr/lib/libX11.so.6.3.0: ELF 32-bit LSB shared object, Intel 80386, <snip>

$ file /usr/lib/libXext.so.6.4.0
/usr/lib/libXext.so.6.4.0: ELF 32-bit LSB shared object, Intel 80386, <snip>

总之,我还应该尝试什么?

我是否缺少特定于cmake或特定于X11的配置选项?

2 个答案:

答案 0 :(得分:1)

你可以尝试:

list(INSERT 0 CMAKE_SYSTEM_LIBRARY_PATH / usr / lib64)

find_library使用的完整变量列表可在文档中找到:https://cmake.org/cmake/help/v3.5/command/find_library.html

答案 1 :(得分:1)

事实证明,root问题是RHEL6端的版本后缀和缺少符号链接到/usr/lib64/libX11.so

cmake专门针对libX11.so而非libX11.so.6或其他特定版本的变种。

在这种情况下,使符号链接不是一个选项,但我可以通过首先列出文件名来优先选择特定版本:

cmake_minimum_required(VERSION 2.8)

find_library(XTEST NAMES libX11.so.6 X11)
message("Found X11 at ${XTEST}")

然而,毫无疑问,有更好的方法可以解决这个问题,如果有人有更好的方法,我会非常有兴趣听听它们。