2

I am attempting to link a large cmake project statically with latest boost 1.70 (not using the cmake package) however I am getting an undefined ref for zlib. This works fine with dynamic linking but I specifically need static.

I've attempted moving the order of my boost components, specifically adding zlib as a target lib and a number of config options ive read online but no joy !

CMAKE FILE

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 error

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

UPDATE 1

As with the comment suggestion I tried using the findzlib.cmake package, I even downloaded and compiled the latest version of zlib (1.2.11) as maybe that might work better with the version of boost I have (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]

And I still get the same linker error, the library it finds is a shared object and the cmake package doesn't seem to have an option for the static lib option.

mf42
  • 43
  • 5

1 Answers1

0

This code below seem to indicate that you found the dynamic library, which is not what you want.. obviously :)

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

According to this zlib is not so friendly regarding using find_package and static. Another way around this problem is to compile zlib yourself through your own cmake-file.

  • Create a folder. e.g external inside your project
  • Download/Clone zlib into it

These are the files/folders i got in my example:

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

Get inspiried by this example:

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)

According to otool, zlib is not dynamically linked and the random code i found for zlib online seems to work anyway.

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

Whether or not you would solve your issue with find_package, i would argue that compiling zlib yourself is in your favour anyway since you gain control of the version you are using. But this is on the edge of religion so please do whatever suite your needs :)

nauman
  • 141
  • 1
  • 11