如何使用 CMake 查找 32 位版本的 zlib
How to find the 32 bit version of zlib with CMake
我想为我的用户提供在 32 位和 64 位版本之间进行选择的选项,并使用一个选项在它们之间切换。如果设置了选项,我将 -m32
添加到 CMAKE_C_FLAGS
、CMAKE_CXX_FLAGS
和 CMAKE_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 安装目录的变量。
虽然这种方式确实有助于找到所需的库版本,但它比其他方法更针对特定目标。
我想为我的用户提供在 32 位和 64 位版本之间进行选择的选项,并使用一个选项在它们之间切换。如果设置了选项,我将 -m32
添加到 CMAKE_C_FLAGS
、CMAKE_CXX_FLAGS
和 CMAKE_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 安装目录的变量。
虽然这种方式确实有助于找到所需的库版本,但它比其他方法更针对特定目标。