【问题标题】:Statically linking boost in cmake undefined zlib issuescmake undefined zlib 问题中的静态链接 boost
【发布时间】:2019-09-04 12:00:35
【问题描述】:

我正在尝试将大型 cmake 项目与最新的 boost 1.70(不使用 cmake 包)静态链接,但是我得到了一个未定义的 zlib 引用。这适用于动态链接,但我特别需要静态链接。

我尝试移动我的 boost 组件的顺序,特别是添加 zlib 作为目标库和一些我在网上阅读的配置选项,但没有乐趣!

CMAKE 文件

cmake_minimum_required(VERSION 3.10)
project(dummy)
# =========================== Make Flag Setup ============================
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS          "-static -Wall -Wno-deprecated-declarations -fPIC ")
set(CMAKE_CXX_FLAGS_DEBUG    "-O0 -g")
set(CMAKE_CXX_FLAGS_RELEASE  "-O3 -fpermissive")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# ========================== Third Party Deps ============================
set(Boost_NO_BOOST_CMAKE     ON)
set(Boost_USE_MULTITHREADED  ON)
set(Boost_USE_STATIC_RUNTIME ON)
set(Boost_USE_STATIC_LIBS    ON)
find_package(Boost 1.70.0 REQUIRED COMPONENTS locale exception serialization system timer regex
                                              thread program_options chrono filesystem iostreams)
include_directories(${Boost_INCLUDE_DIRS} SYSTEM)
include_directories(.)
include_directories(src)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/proto)

# ============================== Build Exe ==============================
file(GLOB_RECURSE all_src src/**.cpp)
add_executable(dummy ${all_src})
target_link_libraries(dummy ${Boost_LIBRARIES} pthread maxminddb crypto ssl pthread xerces-c cdb aerospike proto z)

ld 错误

usr/lib/libboost_iostreams.a(zlib.o): In function `boost::iostreams::detail::zlib_base::after(char const*&, char*&, bool)':
zlib.cpp:(.text+0x108): undefined reference to `crc32'
/usr/lib/libboost_iostreams.a(zlib.o): In function `boost::iostreams::detail::zlib_base::reset(bool, bool)':
zlib.cpp:(.text+0x181): undefined reference to `deflateReset'
zlib.cpp:(.text+0x196): undefined reference to `inflateEnd'
zlib.cpp:(.text+0x1a9): undefined reference to `inflateReset'
zlib.cpp:(.text+0x1c1): undefined reference to `deflateEnd'
/usr/lib/libboost_iostreams.a(zlib.o): In function `boost::iostreams::detail::zlib_base::do_init(boost::iostreams::zlib_params const&, bool, void* (*)(void*, unsigned int, unsigned int), void (*)(void*, void*), void*)':
zlib.cpp:(.text+0x3c4): undefined reference to `inflateInit2_'
zlib.cpp:(.text+0x412): undefined reference to `deflateInit2_'
/usr/lib/libboost_iostreams.a(zlib.o): In function `boost::iostreams::detail::zlib_base::xdeflate(int)':
zlib.cpp:(.text+0x154): undefined reference to `deflate'
/usr/lib/libboost_iostreams.a(zlib.o): In function `boost::iostreams::detail::zlib_base::xinflate(int)':
zlib.cpp:(.text+0x164): undefined reference to `inflate'
collect2: error: ld returned 1 exit status

更新 1

与我尝试使用 findzlib.cmake 包的评论建议一样,我什至下载并编译了最新版本的 zlib (1.2.11),因为也许这可能与我拥有的 boost 版本 (1.70) 一起工作得更好

find_package(ZLIB REQUIRED)
message(ZLIB_INCLUDE   - [${ZLIB_INCLUDE_DIRS}])
message(ZLIB_FOUND     - [${ZLIB_FOUND}])
message(ZLIB_LIBRARIES - [${ZLIB_LIBRARIES}])
...
target_link_libraries(dummy ${Boost_LIBRARIES} pthread maxminddb crypto ssl pthread xerces-c cdb aerospike proto ${ZLIB_LIBRARIES})
-- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.2.11") 
ZLIB_INCLUDE   - [/usr/include]
ZLIB_FOUND     - [TRUE]
ZLIB_LIBRARIES - [/usr/lib/x86_64-linux-gnu/libz.so]

我仍然得到相同的链接器错误,它找到的库是一个共享对象,并且 cmake 包似乎没有静态库选项的选项。

【问题讨论】:

  • CMake 附带了一个FindZLib.cmake。你可能想把它添加到你的依赖链中。
  • 添加了一个更新来涵盖 FindZib 的建议,仍然没有乐趣:(

标签: boost cmake c++17


【解决方案1】:

下面这段代码似乎表明你找到了动态库,这不是你想要的..显然:)

ZLIB_LIBRARIES - [/usr/lib/x86_64-linux-gnu/libz.so]

根据this,zlib 对于使用 find_package 和 static 不是很友好。解决这个问题的另一种方法是通过自己的 cmake-file 自己编译 zlib。

  • 创建一个文件夹。例如,您的项目内部的外部
  • 下载/克隆 zlib 到其中

这些是我在示例中得到的文件/文件夹:

./CMakeLists.txt
./external/zlib
./build
./main.cpp

从这个例子中得到启发:

cmake_minimum_required(VERSION 3.14)
project(zlib-test)
add_executable(${PROJECT_NAME} main.cpp)
add_subdirectory(external/zlib EXCLUDE_FROM_ALL)
target_link_libraries(${PROJECT_NAME} PRIVATE zlibstatic)

根据 otool 的说法,zlib 不是动态链接的,我在网上为 zlib 找到的随机代码似乎仍然有效。

computer:build$ otool -L zlib-test 
zlib-test:
        /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.4)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.250.1)

computer:build$ ./zlib-test 
Initial size: 100
Compressed size: 21
Uncompressed size: 100
Great Success

无论您是否会使用 find_package 解决您的问题,我都认为自己编译 zlib 对您有利,因为您可以控制所使用的版本。但这处于宗教的边缘,所以请随心所欲:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-11
    • 1970-01-01
    • 2013-12-13
    • 2016-09-14
    • 1970-01-01
    相关资源
    最近更新 更多