问题描述
我正在将几个代码库从Red Hat 5迁移到6,并且遇到了一个完全让我困惑的cmake问题。
在RHEL6系统上,Cmake始终在/usr/lib
下找到32位版本的库,而不是64位版本的库/usr/lib64
,而它在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_PATH
、LD_RUN_PATH
或LDFLAGS
,CFLAGS
和CXXFLAGS
也是如此。我的用户环境应该是相同的,因为我的$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的配置选项?
getenv
调用。 - SergeyA/usr/lib
是指向lib32
或lib64
的符号链接。你的链接有没有指向错误的目录的可能性? - callyalater