Skip to content

Conversation

@kou
Copy link
Member

@kou kou commented Aug 28, 2018

Debian package recommends not static linking zlib for security reason. If we use zlib as a static library, Debian package lint reports the following error:

E: libarrow10: embedded-library usr/lib/x86_64-linux-gnu/libarrow.so.10.0.0: zlib

embedded-library error detail: https://lintian.debian.org/tags/embedded-library.html

zlib detection by pkg-config is also added because system zlib provides zlib.pc.

Detect order (default):

  • pkg-config (as shared library)
  • System default path (as shared library)
  • Vendoered zlib (as static library)

Detect order with ZLIB_HOME environment variable:

  • zlib at ZLIB_HOME environment variable value (as shared library)

This is not backward compatible. We used vendored zlib by default.

Summary:

  • Use system zlib by default
    • Changed.
  • System zlib is searched by pkg-config or from the default system path
  • Use the specified zlib when ZLIB_HOME is specified
    • Not changed.
  • If ZLIB_HOME is specified, system zlib isn't searched by pkg-config
    • Not changed.
  • Use vendored zlib as fallback (no ZLIB_HOME and no system zlib)
    • Changed. Vendored zlib was the default.
  • Use system zlib as shared library
    • Changed. Zlib was always used as static library.
  • Use ZLIB_HOME zlib as shared library
    • Changed. Zlib was always used as static library.
  • Use vendored zlib as static library
    • Not changed.
  • Bundle zlib into wheels for Windows.
  • Build directory is always removed on AppVeyor.
    • Changed.
    • Because CMake's cache reports wrong result.
  • Use zlib in the build target Python directory instead of ARROW_BUILD_TOOLCHAIN on Travis CI.
    • Changed.
    • Because linking with zlib in ARROW_BUILD_TOOLCHAIN causes wrong libpython.dylib load on macOS. See comment in ci/travis_script_python.sh for details.
  • after_failure change in .travis.yml is a by-product of debugging crash on macOS.
    • Should I separate this change to another pull request?
  • ZLIB_LIBS has been removed.
    • Because it's not a good name and we don't use anywhere.
    • It doesn't contain library paths. It contains directories that includes library.

@kou
Copy link
Member Author

kou commented Aug 28, 2018

I'll work on changing .deb/.rpm to use this features after this change is merged.

@kou kou changed the title [C++] Support system shared zlib ARROW-3128: [C++] Support system shared zlib Aug 28, 2018
@codecov-io
Copy link

codecov-io commented Aug 28, 2018

Codecov Report

Merging #2483 into master will decrease coverage by 0.01%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2483      +/-   ##
==========================================
- Coverage   87.69%   87.67%   -0.02%     
==========================================
  Files         372      372              
  Lines       57915    57915              
==========================================
- Hits        50788    50778      -10     
- Misses       7057     7063       +6     
- Partials       70       74       +4
Impacted Files Coverage Δ
go/arrow/math/int64_avx2_amd64.go 0% <0%> (-100%) ⬇️
go/arrow/memory/memory_avx2_amd64.go 0% <0%> (-100%) ⬇️
go/arrow/math/float64_avx2_amd64.go 0% <0%> (-100%) ⬇️
go/arrow/math/uint64_avx2_amd64.go 0% <0%> (-100%) ⬇️
go/arrow/memory/memory_amd64.go 28.57% <0%> (-14.29%) ⬇️
go/arrow/math/math_amd64.go 31.57% <0%> (-5.27%) ⬇️
go/arrow/math/float64_amd64.go 33.33% <0%> (ø) ⬆️
go/arrow/math/int64_amd64.go 33.33% <0%> (ø) ⬆️
go/arrow/math/uint64_amd64.go 33.33% <0%> (ø) ⬆️
go/arrow/math/float64_sse4_amd64.go 100% <0%> (+100%) ⬆️
... and 3 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7a2d228...3bac9fc. Read the comment docs.

Copy link
Member

@pitrou pitrou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments below.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This docstring needs fixing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I think using the system zlib should be the default except if not found. There's no reason to vendor such a stable library (except on Windows), IMHO.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh... Sorry for my low quality pull request...
I'll fix it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think using the system zlib should be the default except if not found.

I want to do so. But I keep the current behavior for backward compatibility.
If nobody objects it, I'll do so.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what "where relevant" means? Also, do we need an option for this? Can't we always use a shared zlib? (the zlib ABI is probably very stable...)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per @pitrou comment above, I would be OK with making the default "ON", though it will require some changes to our packaging scripts

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. I'll remove this option and fix our packaging scripts.
It'll make our build system simpler.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add comments explaining why all this exists? Write-only configuration code is not nice.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK.
I'll add a comment that zlib uses zlib.lib on Windows.
FYI: https://github.com/madler/zlib/blob/master/win32/README-WIN32.txt#L50

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses pkg-config?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make things clearer, perhaps we could use a different prefix for the pkg-config results, for example PKG_ZLIB. That would make the below more readable, IMHO.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense. I'll do.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So ZLIB_LIBS lists directories? Uh :-/

Copy link
Member Author

@kou kou Aug 29, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We define the following API in the header of this file...

#  ZLIB_LIBS, directory containing zlib libraries

I think that nobody uses ZLIB_LIBS. Can we remove ZLIB_LIBS?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PARQUET_MINIMAL_DEPENDENCY isn't used anymore above, it seems, so perhaps we needn't test it here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be used when we merge perquet-cpp into Arrow repository.
But "found the ZLIB shared library" message will be enough. We'll not need "Found the ZLIB header" message.
I'll remove this condition.

@xhochy Do you have any concerns?

Copy link
Member

@xhochy xhochy Aug 29, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 (no concerns)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a warning message if the zlib isn't found? Especially as we vendor it...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be done in ThirdpartyToolchain.cmake not in FindZLIB.cmake.
We don't care whether vendored or not here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO, we should make it an error to set both ZLIB_HOME and ARROW_ZLIB_VENDORED. It's already annoying enough to debug configuration issues.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed ARROW_ZLIB_VENDORED to use system zlib by default and vendored zlib as fallback.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, we should make it an error if ARROW_ZLIB_VENDORED is false and a third-party zlib couldn't be found.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, this sounds reasonable since building needs the development headers, which aren't always installed (as opposed to the library itself, which is pretty much everywhere).

@kou
Copy link
Member Author

kou commented Aug 29, 2018

We need more works for CI.
I'll work on it later.

@kou kou force-pushed the cpp-system-zlib branch 3 times, most recently from 00e4e34 to bc32ff3 Compare August 30, 2018 13:45
@kou
Copy link
Member Author

kou commented Aug 31, 2018

Now, CI is green again. Can someone review this?

Summary:

  • Use system zlib by default
    • Changed.
  • System zlib is searched by pkg-config or from the default system path
  • Use the specified zlib when ZLIB_HOME is specified
    • Not changed.
  • If ZLIB_HOME is specified, system zlib isn't searched by pkg-config
  • Use vendored zlib as fallback (no ZLIB_HOME and no system zlib)
    • Changed. Vendored zlib was the default.
  • Use system zlib as shared library
    • Changed. Zlib is always used as static library.
  • Use ZLIB_HOME zlib as static library
  • Use vendored zlib as static library
    • Not changed.
  • after_failure change in .travis.yml is a by-product of debugging crash on macOS.
    • Should I separate this change to another pull request?
  • ZLIB_LIBS has been removed.
    • Because it's not a good name and we don't use anywhere.
    • It doesn't contain library paths. It contains directories that includes library.

Copy link
Member

@wesm wesm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we deploy Python packages on systems which may not have libz available in $PATH / %PATH%, we either need to

  • statically link in those packages or
  • bundle libz.so/dll

In case case of conda packages, we should definitely switch to dynamic linking. So that will require changes in https://github.com/conda-forge/arrow-cpp-feedstock/blob/master/recipe/meta.yaml#L40

The question really is the Python wheels. Is zlib shipped with CPython? I guess we should experiment to find out

cc @xhochy @pitrou @cpcloud

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still need a flag to link statically since we deploy Python and C++ packages on platforms which may not have libz in the dynamic loader path

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this static linking required on Windows? OSX and Linux don't need it in wheels.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just looked at a default install of Python 3.6 on Windows 64 and it doesn't appear to include zlib. I tried doing ctypes.CDLL('z.dll') and CDLL('libz.dll') and neither work. So either we need to bundle the shared library in wheels or statically link

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK.
I'll try to bundle zlib as shared library for wheels.
If it's succeeded, I'll remove static link support for ZLIB_ROOT case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need changing per comment above

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be exposed as a transitive dependency of arrow_static/arrow_shared? I think there's some way to get CMake to automatically include transitive link dependencies

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it too but I couldn't...
I try again with ADD_ARROW_TEST(compression-test EXTRA_LINK_LIBS zlib), it works well. Oh.

@xhochy
Copy link
Member

xhochy commented Aug 31, 2018

zlib is not part of the manylinux1 spec, so at least there, we should ship it with Arrow.

@pitrou
Copy link
Member

pitrou commented Sep 3, 2018

zlib is not part of the manylinux1 spec, so at least there, we should ship it with Arrow.

I had missed that. It's a bit surprising, I wonder if there are GNU/Linux systems without even zlib installed.

@pitrou
Copy link
Member

pitrou commented Sep 3, 2018

@kou kou force-pushed the cpp-system-zlib branch 16 times, most recently from e4ec03c to ae7e277 Compare September 8, 2018 05:32
@kou kou force-pushed the cpp-system-zlib branch 2 times, most recently from 298a870 to 62858dc Compare September 9, 2018 00:08
@kou
Copy link
Member Author

kou commented Sep 9, 2018

CI is green again. Can someone review this again?

Summary:

  • Use system zlib by default
    • Changed.
  • System zlib is searched by pkg-config or from the default system path
  • Use the specified zlib when ZLIB_HOME is specified
    • Not changed.
  • If ZLIB_HOME is specified, system zlib isn't searched by pkg-config
    • Not changed.
  • Use vendored zlib as fallback (no ZLIB_HOME and no system zlib)
    • Changed. Vendored zlib was the default.
  • Use system zlib as shared library
    • Changed. Zlib was always used as static library.
  • Use ZLIB_HOME zlib as shared library
    • Changed. Zlib was always used as static library.
  • Use vendored zlib as static library
    • Not changed.
  • Bundle zlib into wheels for Windows.
  • Build directory is always removed on AppVeyor.
    • Changed.
    • Because CMake's cache reports wrong result.
  • Use zlib in the build target Python directory instead of ARROW_BUILD_TOOLCHAIN on Travis CI.
    • Changed.
    • Because linking with zlib in ARROW_BUILD_TOOLCHAIN causes wrong libpython.dylib load on macOS. See comment in ci/travis_script_python.sh for details.
  • after_failure change in .travis.yml is a by-product of debugging crash on macOS.
    • Should I separate this change to another pull request?
  • ZLIB_LIBS has been removed.
    • Because it's not a good name and we don't use anywhere.
    • It doesn't contain library paths. It contains directories that includes library.

@wesm
Copy link
Member

wesm commented Sep 9, 2018

Thanks @kou for working on this! I will review today or tomorrow. I added your summary to the PR description so it will end up in the commit message

conda create -y -q -p $CONDA_ENV_DIR python=$PYTHON_VERSION cmake curl
conda activate $CONDA_ENV_DIR

# We should zlib in the target Python directory to avoid loading wrong
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There seems to be a word missing: "We should zlib".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I've fixed this.

Copy link
Member

@wesm wesm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for working on this. A couple of last questions before merging. I was confused in particular by the amount of code involved with bundling zlib in the python/CMakeLists.txt, but I haven't looked closely enough to see why it's needed.

ADD_ARROW_TEST(bit-util-test)
ADD_ARROW_TEST(checked-cast-test)
ADD_ARROW_TEST(compression-test)
ADD_ARROW_TEST(compression-test EXTRA_LINK_LIBS zlib)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this should transitively linked as a result of linking to libarrow.a. We should make a follow up to make sure that CMake is set to include transitive dependencies when statically linking

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we add zlib to ARROW_STATIC_LINK_LIBS even when we use zlib as shared library, we can remove this: db17bdb

I'm not sure that it's a good manner in this project...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

endfunction()

function(bundle_zlib zlib_home)
if (MSVC)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can FindZLIB.cmake not be used here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't use FindZLIB.cmake here.
It finds zlib.lib to link zlib as shared library. But we need zlib.dll here.

Anyway, I've removed unused codes by 3db0830
The removed codes are for non Windows. I kept them because we may use them later. But we can remove unused codes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, no problem. Thank you

Copy link
Member

@wesm wesm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1. Not sure what's up with the Travis CI failure but it doesn't appear related to this

@wesm wesm closed this in 65154c9 Sep 13, 2018
@kou kou deleted the cpp-system-zlib branch September 13, 2018 13:50
@kou
Copy link
Member Author

kou commented Sep 13, 2018

Thanks.
#2554 will solve this failure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants