C++ 为什么cmake在64位系统上查找32位库而不是64位库? 问题描述

C++ 为什么cmake在64位系统上查找32位库而不是64位库? 问题描述,c++,c,linux,build,cmake,C++,C,Linux,Build,Cmake,我正在将几个代码库从Red Hat 5移植到Red Hat 6,我遇到了一个cmake问题,我完全被它难住了 Cmake始终在RHEL6系统上查找/usr/lib下的32位版本的库,而不是/usr/lib64下的64位版本,同时在RHEL5系统上正确检测lib64版本 最小示例 例如,我有一个非常小的CMakeLists.txt文件: cmake_minimum_required(VERSION 2.8) find_library(XTEST X11) message("Found

我正在将几个代码库从Red Hat 5移植到Red Hat 6,我遇到了一个cmake问题,我完全被它难住了

Cmake始终在RHEL6系统上查找
/usr/lib
下的32位版本的库,而不是
/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
(这里的关键部分是在/usr/lib/libX11.so行中找到的
X11)

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

故障排除信息 两个系统上都有
/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位版本(而且,它不是指向其他位置的符号链接):

这可能是由于某个地方的环境设置,但我有点不知道在哪里。我没有设置
LD\u库路径
LD\u运行路径
,或
LDFLAGS
。同样适用于
CFLAGS
cxflags
。我的用户环境应该是相同的,因为我的$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>
cmake
-特定Trobleshooting 两台机器上的cmake版本是相同的(事实上,它是相同的可执行文件,为了简洁起见,我将省略):

我已尝试显式启用
查找库\u使用\u LIB64\u路径
,但这似乎没有什么区别:

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}")
cmake_minimum_required(VERSION 2.8)

FIND_PACKAGE(X11 REQUIRED)

message("X11_LIBRARIES: ${X11_LIBRARIES}")
查找
/usr/lib64/libpng.so
而不是
/usr/lib/libpng.so

这让我觉得这是一个cmake特定的东西,无论如何

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

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

cmake_minimum_required(VERSION 2.8)

find_library(PNGTEST png)
message("Found libpng at ${PNGTEST}")
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>
总之,我还应该尝试什么? 我是否缺少特定于cmake或X11的配置选项?

您可以尝试:

列表(插入0 CMAKE\u SYSTEM\u LIBRARY\u PATH/usr/lib64)


find_library使用的变量的完整列表可在文档中找到:

事实证明,根本问题是版本后缀和缺少指向特定
/usr/lib64/libX11的符号链接

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}")

然而,毫无疑问,有很多更好的方法来处理这个问题,如果有人有更好的方法,我会非常感兴趣地听取他们的意见。

你检查过你的$PATH吗?它可能有/usr/lib吗?很好!不幸的是,我的路径中没有/usr/lib,因此这不是修复方法,但无论如何,我应该将该信息添加到问题中。此时,我将尝试使用strace/ltrace-可能它会给您一个提示。没有必要,但总比没有强。例如,如果它正在读取某个模糊的env变量,您将在ltrace输出中看到
getenv
调用。这是一个好主意。我不会想到用ltrace/strace来做这个。。。它肯定会给我比现在更多的信息@虽然我不一定不同意,但你知道有更好的工具吗?手动键入Makefile是不可能的,配置是一件麻烦事。好建议。遗憾的是,它没有改变找到哪个库(仍然在查找
/usr/lib/libX11.so
)。然而,我想,这确实让我找到了正确的方向。我只是在寻找其他东西时偶然发现了这一点。我对Linux编程的经验很少,但我想知道:如果应用程序正在寻找
libX11.so.6
,CMake Find模块不也应该这样做吗?我想这里的答案可能包括修复Find模块。
$ 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>
$ 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_minimum_required(VERSION 2.8)

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