如何使用CMake找到32位版本的zlib

时间:2016-10-12 08:37:31

标签: cmake 32bit-64bit zlib

我想为我的用户提供在32位和64位构建之间进行选择的选项,并使用选项在它们之间进行切换。如果设置了该选项,我会将-m32添加到CMAKE_C_FLAGSCMAKE_CXX_FLAGSCMAKE_EXE_LINKER_FLAGS。我也打电话给set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS OFF)。到目前为止,这工作正常,但现在我试图找到库zlib并始终获得64位版本导致链接器失败。

我找到this old thread,它有同样的问题,但没有适用于我的解决方案。和Glenn Coombs一样,我不想让我的用户了解他们如何调用cmake来获得32位版本,所以CC="gcc -m32" cmake对我不起作用。

修改 事实证明,这甚至不能与电子邮件线程中提出的解决方案一起使用。这是一个小例子:

main.cpp中:

#include <iostream>
#include "zlib.h"

int main() {
    std::cout << ZLIB_VERSION << std::endl;
    std::cout << "pointer size: " << sizeof(void*) << std::endl;
    return 0;
}

的CMakeLists.txt:

cmake_minimum_required(VERSION 2.8.3)

project(usezlib32)
add_executable(usezlib32 main.cpp)

find_package(ZLIB)
if (ZLIB_FOUND)
    include_directories(${ZLIB_INCLUDE_DIRS})
    target_link_libraries(usezlib32 ${ZLIB_LIBRARIES})
endif()

调用g++ -m32 main.cpp -lz会生成一个有效的二进制文件,但调用CC="gcc -m32" CXX="g++ -m32" cmake && make时会出现以下错误:

/opt/anaconda/lib/libz.so: error adding symbols: File in wrong format

我想问题是为什么CMake看起来与g ++不同。

1 个答案:

答案 0 :(得分:2)

CMake命令find_library执行搜索时仅考虑文件名,它不会对找到的文件执行其他检查。

因此,找到32位库而不是64位库的唯一方法是使用32位库的目录之前搜索64位:

  • 设置属性FIND_LIBRARY_USE_LIB64_PATHS可以禁用搜索64位库的某些路径。它仅适用于包含“64”或“lib64”的路径(有关详细信息,请参阅find_library的算法)。

由于您的路径/opt/anaconda/lib/libz.so不符合此规则,因此该属性对您没有帮助。

  • CMAKE_LIBRARY_PATH CMake缓存变量设置为包含32位库的目录列表。因此,这些目录将在其他目录之前进行搜索。

在您的情况下,您可以执行以下操作:

set(CMAKE_LIBRARY_PATH "/usr/lib/i386-linux-gnu" CACHE PATH "<desc>")

或者,可以使用cmake选项将此变量传递给-D

  • CMAKE_LIBRARY_PATH 环境变量设置为包含32位库的目录列表。因此,这些目录将在其他目录之前进行搜索。

在您的情况下,您可以执行以下操作:

set(ENV{CMAKE_LIBRARY_PATH} "/usr/lib/i386-linux-gnu")

可能是其他非系统库的路径也存储在此变量中。因此在更改时要小心:您可能会破坏对项目所需的其他库的搜索。

  • 设置CMake或环境变量CMAKE_PREFIX_PATH,或影响特定包的find_package(XXX)的其他变量。例如,对于zlib,可以设置指向zlib安装目录的ZLIB_ROOT变量。

虽然这种方式肯定有助于找到所需的库版本,但它比其他方法更具针对性。