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

How to find the 32 bit version of zlib with CMake

我想为我的用户提供在 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++ 不同。

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

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

  • 设置CMAKE_LIBRARY_PATH环境变量为目录列表,包含 32 位库。所以这些目录将在其他目录之前被搜索。

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

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

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

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

虽然这种方式确实有助于找到所需的库版本,但它比其他方法更针对特定目标。