Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for building zstd binding against an external libzstd library #109

Merged
merged 9 commits into from
Nov 24, 2021

Conversation

dopuskh3
Copy link
Contributor

@dopuskh3 dopuskh3 commented Nov 18, 2021

This is heavily inspired by the following PR from @WGH-

Add the external_libzstd tag to be used when we want to build the binding against an externally provided
zstd library. If the tag is defined, the go build system will look for zstd pkg-config package to gather
build arguments.

Added CI jobs to run tests and benchmarks with latest go version.

@dopuskh3 dopuskh3 force-pushed the dopuskh3/zstd-external-library branch 9 times, most recently from 64661b6 to 53cdb61 Compare November 18, 2021 13:36
@dopuskh3 dopuskh3 requested a review from Viq111 November 18, 2021 13:38
Copy link
Contributor

@evanj evanj left a comment

Choose a reason for hiding this comment

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

I think this looks good, but we should get @Viq111 to take a look.

I also wonder if this package should be renaming all the zstd symbols by default, to allow it to be linked along side other versions of zstd? I think we would still want the option to use an external version, but this might reduce the number of places where people would need this option? (clearly that would be another thing to do in a future change, not here)

@dopuskh3 dopuskh3 force-pushed the dopuskh3/zstd-external-library branch 2 times, most recently from bd5a21c to b931fd9 Compare November 19, 2021 16:56
@WGH-
Copy link

WGH- commented Nov 19, 2021

When I was working on the PR, I got stuck because Debian Buster (10), on which golang Docker image was based on, had relatively old libzstd, and some of the .go files used new functions that weren't present. I couldn't find an easy way to make CI tests pass.

I suppose you circumvented this issue by waiting until golang images started to base on Debian Bullseye (11)?

If so, does it mean that external_libzstd won't work on older libzstd versions, even if user doesn't use any of those new functions?

@dopuskh3 dopuskh3 force-pushed the dopuskh3/zstd-external-library branch 3 times, most recently from 532c5e1 to 5962e6a Compare November 19, 2021 17:52
@dopuskh3
Copy link
Contributor Author

dopuskh3 commented Nov 19, 2021

When I was working on the PR, I got stuck because Debian Buster (10), on which golang Docker image was based on, had relatively old libzstd, and some of the .go files used new functions that weren't present. I couldn't find an easy way to make CI tests pass.

I suppose you circumvented this issue by waiting until golang images started to base on Debian Bullseye (11)?

If so, does it mean that external_libzstd won't work on older libzstd versions, even if user doesn't use any of those new functions?

external_libzstd will work as soon as the symbols used in the go bindings are available in the lib zstd.h located in the path returned by pkg-config. Unfortunately, cgo doesn't provide the ability to ask for dependency prerequisites (it could for example use pkg-config --atleast/exact/max-version feature)

@dopuskh3
Copy link
Contributor Author

I think this looks good, but we should get @Viq111 to take a look.

I also wonder if this package should be renaming all the zstd symbols by default, to allow it to be linked along side other versions of zstd?
I agree that bundling symbols that may be provided to the compiler by other projects linking with zstd can make the situation a little bit tricky to handle for larger projects. Specially, in this situation, forgetting to pass the external_libzstd tag to go build can end up silently use vendored source code for other dependencies using libzstd:

Here is what I observed in the following situation:

  [binary] <---- [DataDog/zstd] <---- [vendored zstd code]
     ^
     |
     +---------[confluent-kafka-go] <---- [librdkafka] <----[libzstd]

I observed that the calls to confluent-kafka-go using zstd actually ended up running the [vendored zstd code], which can be annoying in multiple ways.

In order to avoid this situation to silently happen, we could make passing a build tag mandatory by failing the compilation intentionally if none of the vendored_libztd nor external_libzstd is passed.

Copy link
Collaborator

@Viq111 Viq111 left a comment

Choose a reason for hiding this comment

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

Thanks! This looks good to me, I just added some small comments

zstd.h Outdated
@@ -2530,3 +2531,7 @@ ZSTDLIB_API size_t ZSTD_insertBlock (ZSTD_DCtx* dctx, const void* blockStart,
#if defined (__cplusplus)
}
#endif
#else /* USE_EXTERNAL_ZSTD */
#undef ZSTD_STATIC_LINKING_ONLY
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is a bit hacky to define ZSTD_STATIC_LINKING_ONLY in the Go file and then unset in the C file. Is there a way to just have the switch in external_zstd.go ? (i.e: an else that sets it)
(I don't remember if we need to define & import zstd.h in each go file)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Are you sure we actually need to define ZSTD_STATIC_LINKING_ONLY? It appears that library is building fine when that's not defined.

@dopuskh3 dopuskh3 force-pushed the dopuskh3/zstd-external-library branch 3 times, most recently from 63f8910 to 4b2486c Compare November 23, 2021 10:53
@dopuskh3 dopuskh3 force-pushed the dopuskh3/zstd-external-library branch 2 times, most recently from ce570f0 to 5063218 Compare November 23, 2021 10:57
@dopuskh3 dopuskh3 force-pushed the dopuskh3/zstd-external-library branch from 5063218 to 443dd38 Compare November 23, 2021 10:58
@dopuskh3 dopuskh3 force-pushed the dopuskh3/zstd-external-library branch from 443dd38 to 0c4231e Compare November 23, 2021 12:15
@dopuskh3
Copy link
Contributor Author

When I was working on the PR, I got stuck because Debian Buster (10), on which golang Docker image was based on, had relatively old libzstd, and some of the .go files used new functions that weren't present. I couldn't find an easy way to make CI tests pass.
I suppose you circumvented this issue by waiting until golang images started to base on Debian Bullseye (11)?
If so, does it mean that external_libzstd won't work on older libzstd versions, even if user doesn't use any of those new functions?

external_libzstd will work as soon as the symbols used in the go bindings are available in the lib zstd.h located in the path returned by pkg-config. Unfortunately, cgo doesn't provide the ability to ask for dependency prerequisites (it could for example use pkg-config --atleast/exact/max-version feature)

@WGH- I added version constraint with preprocessor macros in the external_libzstd.go file here

Copy link
Collaborator

@Viq111 Viq111 left a comment

Choose a reason for hiding this comment

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

lgtm!

Maybe one last thing (that doesn't necessitate another review). Could you add the go build -tags external_libzstd as a section in the README ? That way it's discoverable for users without needing to read the code

@dopuskh3 dopuskh3 force-pushed the dopuskh3/zstd-external-library branch from bbe7f2a to 1a7f3d7 Compare November 24, 2021 15:01
@dopuskh3 dopuskh3 merged commit 0b0bdec into 1.x Nov 24, 2021
@Viq111 Viq111 deleted the dopuskh3/zstd-external-library branch November 24, 2021 15:04
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.

4 participants