Move compressed marshaling away from the stdlib and into the compilers (5.1 version)#12734
Conversation
Already done in trunk.
Currently, both the bytecode version and the native-code version of Dynlink drag in many modules from the compiler, including some that use compressed marshaling. This causes users of dynlink.cmxa to depend on -lzstd systematically. Actually, the native-code version of Dynlink needs much fewer compiler modules, none of which require compressed marshaling. This commit just shrinks the list of compiler modules included in dynlink.cmxa, thus cutting the dependency on -lzstd.
Manual cherry-pick from 7ed7268 . Co-authored-by: David Allsopp <david.allsopp@metastack.com>
These functions used to be in extern.c and intern.c. Now, they are in zstd.c and connect themselves to extern.c and intern.c via hooks activated by a new primitive `caml_zstd_initialize`.
- Removes the Marshal.Compression constructor, in preparation for explicit API in 5.2 - Add just to_channel (for now) to ocamlcommon - caml_zstd_initialize called from Compression for now.
…value` The "flags" argument was always [], so remove it. This avoids an Obj.magic in compression.ml.
d0c4a14 to
63f2cfa
Compare
Under the hood, it's just `Stdlib.input_value`. However, it documents the places in the compiler where we expect to read compressed marshaled data.
…erlibs We attach -lzstd to ocamlcommon.cmxa and insert zstd.n.o in ocamlcommon.a. (The latter is a hack, to be replaced by something better eventually.)
63f2cfa to
768beb3
Compare
| compilerlibs/ocamlcommon.cmxa: $(COMMON_CMI) $(COMMON:.cmo=.cmx) $(ZSTD_OBJ) | ||
| $(V_LINKOPT)$(CAMLOPT) -a -linkall -o $@ \ | ||
| $(ZSTD_FLAGS) $(COMMON:.cmo=.cmx) | ||
| $(V_MKLIB)$(ARCMD) r compilerlibs/ocamlcommon.$(A) $(ZSTD_OBJ) |
There was a problem hiding this comment.
This creative use of ar is due to @dra27. If we just add zstd.n.o to the ocamlopt -a command line, this file name is recorded in ocamlcommon.cmxa and passed to the system linker when the latter file is used, but the system linker will not find it and will not search for it in the -L search path. Instead, we include zstd.n.o and its contents in the ocamlcommon.a archive, where the system linker will find it reliably.
It's unclear whether this hack can work with the MSVC librarian lib. Good thing we're not supporting MSVC again yet.
To make things cleaner in the future, we can either
- Change
ocamlopt -aso that all.ofiles given on the command line are included in the generated.afile. The current behavior (of recording the file names in the.cmxafile) is useless anyway. - Put
zstd.n.oin a proper.aarchive, and install this archive. This would be the case if we make anotherlibsthat exposes compressed marshaling to users.
kit-ty-kate
left a comment
There was a problem hiding this comment.
Successfully tested on macOS, FreeBSD and Alpine Linux. Thank you so much!
|
The incompatible API change (removal of |
damiendoligez
left a comment
There was a problem hiding this comment.
Looks good modulo two nitpicks.
|
Because #12006 was released, you'll also need a Changes entry for this PR. |
- Add type constraint in dynlink/byte/dynlink.ml - Reword configure message about ZSTD support Co-authored-by: Damien Doligez <damien.doligez@gmail.com>
3814387 to
d3f94e9
Compare
- Add type constraint in dynlink/byte/dynlink.ml - Reword configure message about ZSTD support Co-authored-by: Damien Doligez <damien.doligez@gmail.com>
d3f94e9 to
0713d6a
Compare
0713d6a to
49b6988
Compare
|
CI is green (here and on Jenkins). Merging in 5.1 branch. Will port to trunk and improve soon. |
| const unsigned char *, | ||
| uintnat) = NULL; | ||
|
|
||
| CAMLprim value caml_compression_available(value vunit) |
There was a problem hiding this comment.
This is not used, is it intended ?
There was a problem hiding this comment.
Yes, indeed. To avoid an unnecessary bootstrap, the primitive will be removed before at release.
|
|
||
| CAMLprim value caml_zstd_initialize(value vunit) | ||
| { | ||
| return Val_unit; |
| { | ||
| caml_extern_compress_output = caml_zstd_compress; | ||
| caml_intern_decompress_input = caml_zstd_decompress; | ||
| return Val_unit; |
This is the second attempt at fixing the problem reported in #12562 concerning the compressed marshaling facility introduced in OCaml 5.1 by #12006.
The first attempt #12705 kept the API introduced in #12006 (an extra flag
Marshal.Compressionin theMarshalstandard library module) and tried to make sure that the ZSTD library is dynamically linked with ocamlopt-generated executables only if theMarshalmodule is actually used. This failed because of limitations of some system linkers.The present attempt removes the
Marshal.CompressionAPI and makes compressed marshaling unavailable via the standard library and private to the OCaml compilers. A new moduleCompressionis added to the compilers and to compiler-libs, and used to compress and uncompress the same compilation artefacts as in #12006. (Unless ZSTD is not available or configured out, in which case plain marshaling is used.)The implementation reuses parts of the first attempt #12705:
ocamlrunand executables produced withocamlc -customalways include zstd.c and always dynamically link with ZSTD. (Doing otherwise complicates coldstart and bootstrap too much.)What's new in this second attempt:
ocamloptdo NOT include zstd.c and do NOT link with ZSTD, unless they use compiler-libs (see next).This PR is against 5.1, so that it can be integrated in release 5.1.1. Two points of attention:
Marshal.Compressionflag). IIRC, we never did this (a minor release with an incompatible API) before. The working group composed of @dra27, @Octachron, @nojb and I think this is acceptable given the circumstances. This will have to be confirmed at the next developers meeting.