我正在努力将几个代码库从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_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的配置选项?
答案 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}")
然而,毫无疑问,有更好的方法可以解决这个问题,如果有人有更好的方法,我会非常有兴趣听听它们。