[ocaml] 01/01: Support BUILD_PATH_PREFIX_MAP for reproducible builds
Ximin Luo
infinity0 at debian.org
Tue Dec 5 13:25:01 UTC 2017
This is an automated email from the git hooks/post-receive script.
infinity0 pushed a commit to branch pu/reproducible_builds
in repository ocaml.
commit b3e55cce8b01732f92c00e5cbb748a97cc1f920d
Author: Ximin Luo <infinity0 at debian.org>
Date: Tue Dec 5 13:03:21 2017 +0100
Support BUILD_PATH_PREFIX_MAP for reproducible builds
---
debian/changelog | 6 +
...tils-import-build_path_prefix_map-library.patch | 151 +++++++++++++++++++++
...h_prefix_map-update-.depend-and-Makefiles.patch | 137 +++++++++++++++++++
...UILD_PATH_PREFIX_MAP-variable-if-it-exist.patch | 116 ++++++++++++++++
debian/patches/series | 3 +
5 files changed, 413 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index 84aea84..6095e03 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+ocaml (4.05.0-10.0~reproducible1) UNRELEASED; urgency=medium
+
+ * Support BUILD_PATH_PREFIX_MAP for reproducible builds.
+
+ -- Ximin Luo <infinity0 at debian.org> Tue, 05 Dec 2017 13:01:40 +0100
+
ocaml (4.05.0-10) unstable; urgency=medium
* Drop support for ocamlopt on armel as suggested by upstream.
diff --git a/debian/patches/0001-utils-import-build_path_prefix_map-library.patch b/debian/patches/0001-utils-import-build_path_prefix_map-library.patch
new file mode 100644
index 0000000..6e9675e
--- /dev/null
+++ b/debian/patches/0001-utils-import-build_path_prefix_map-library.patch
@@ -0,0 +1,151 @@
+From 1dd4f02c280f31d501007a0a603af75252c516ee Mon Sep 17 00:00:00 2001
+From: Gabriel Scherer <gabriel.scherer at gmail.com>
+Date: Mon, 4 Dec 2017 23:30:43 +0000
+Subject: [PATCH 1/3] utils: import build_path_prefix_map library
+
+This library is imported from
+
+ <https://gitlab.com/gasche/build_path_prefix_map/>
+
+commit 811691e479b38c0e6c1c0e5c853c555a63177ee3
+---
+ utils/build_path_prefix_map.ml | 104 ++++++++++++++++++++++++++++++++++++++++
+ utils/build_path_prefix_map.mli | 24 ++++++++++
+ 2 files changed, 128 insertions(+)
+ create mode 100644 utils/build_path_prefix_map.ml
+ create mode 100644 utils/build_path_prefix_map.mli
+
+--- /dev/null
++++ b/utils/build_path_prefix_map.ml
+@@ -0,0 +1,104 @@
++type path = string
++type path_prefix = string
++type error_message = string
++
++let errorf fmt = Printf.kprintf (fun err -> Error err) fmt
++
++let encode_prefix str =
++ let buf = Buffer.create (String.length str) in
++ let push_char = function
++ | '%' -> Buffer.add_string buf "%#"
++ | '=' -> Buffer.add_string buf "%+"
++ | ':' -> Buffer.add_string buf "%."
++ | c -> Buffer.add_char buf c
++ in
++ String.iter push_char str;
++ Buffer.contents buf
++
++let decode_prefix str =
++ let buf = Buffer.create (String.length str) in
++ let rec loop i =
++ if i >= String.length str
++ then Ok (Buffer.contents buf)
++ else match str.[i] with
++ | '=' ->
++ errorf "invalid character '=' in key or value"
++ | '%' ->
++ let push c = Buffer.add_char buf c; loop (i + 2) in
++ if i + 1 = String.length str then
++ errorf "invalid encoded string %S (trailing '%%')" str
++ else begin match str.[i + 1] with
++ | '#' -> push '%'
++ | '+' -> push '='
++ | '.' -> push ':'
++ | c -> errorf "invalid %%-escaped character '%c'" c
++ end
++ | c ->
++ Buffer.add_char buf c;
++ loop (i + 1)
++ in loop 0
++
++type pair = { target: path_prefix; source : path_prefix }
++
++let encode_pair { target; source } =
++ String.concat "=" [encode_prefix target; encode_prefix source]
++
++let decode_pair str =
++ match String.index str '=' with
++ | exception Not_found ->
++ errorf "invalid key/value pair %S, no '=' separator" str
++ | equal_pos ->
++ let encoded_target = String.sub str 0 equal_pos in
++ let encoded_source =
++ String.sub str (equal_pos + 1) (String.length str - equal_pos - 1) in
++ match decode_prefix encoded_target, decode_prefix encoded_source with
++ | Ok target, Ok source -> Ok { target; source }
++ | ((Error _ as err), _) | (_, (Error _ as err)) -> err
++
++type map = pair option list
++
++let encode_map map =
++ let encode_elem = function
++ | None -> ""
++ | Some pair -> encode_pair pair
++ in
++ List.map encode_elem map
++ |> String.concat ":"
++
++let decode_map str =
++ let exception Shortcut of error_message in
++ let decode_or_empty = function
++ | "" -> None
++ | pair ->
++ begin match decode_pair pair with
++ | Ok str -> Some str
++ | Error err -> raise (Shortcut err)
++ end
++ in
++ let pairs = String.split_on_char ':' str in
++ match List.map decode_or_empty pairs with
++ | exception (Shortcut err) -> Error err
++ | map -> Ok map
++
++let rewrite_opt prefix_map path =
++ let is_prefix = function
++ | None -> false
++ | Some { target = _; source } ->
++ String.length source <= String.length path
++ && String.equal source (String.sub path 0 (String.length source))
++ in
++ match
++ List.find is_prefix
++ (* read key/value pairs from right to left, as the spec demands *)
++ (List.rev prefix_map)
++ with
++ | exception Not_found -> None
++ | None -> None
++ | Some { source; target } ->
++ Some (target ^ (String.sub path (String.length source)
++ (String.length path - String.length source)))
++
++let rewrite prefix_map path =
++ match rewrite_opt prefix_map path with
++ | None -> path
++ | Some path -> path
+--- /dev/null
++++ b/utils/build_path_prefix_map.mli
+@@ -0,0 +1,24 @@
++type path = string
++type path_prefix = string
++type error_message = string
++
++val encode_prefix : path_prefix -> string
++val decode_prefix : string -> (path_prefix, error_message) result
++
++type pair = { target: path_prefix; source : path_prefix }
++
++val encode_pair : pair -> string
++val decode_pair : string -> (pair, error_message) result
++
++type map = pair option list
++
++val encode_map : map -> string
++val decode_map : string -> (map, error_message) result
++
++val rewrite_opt : map -> path -> path option
++(** [rewrite_opt map path] tries to find a source in [map]
++ that is a prefix of the input [path]. If it succeeds,
++ it replaces this prefix with the corresponding target.
++ If it fails, it just returns [None]. *)
++
++val rewrite : map -> path -> path
diff --git a/debian/patches/0002-build_path_prefix_map-update-.depend-and-Makefiles.patch b/debian/patches/0002-build_path_prefix_map-update-.depend-and-Makefiles.patch
new file mode 100644
index 0000000..4c179ad
--- /dev/null
+++ b/debian/patches/0002-build_path_prefix_map-update-.depend-and-Makefiles.patch
@@ -0,0 +1,137 @@
+From 1679da3479dc5c9ab0186d6442a3b47fb76963eb Mon Sep 17 00:00:00 2001
+From: Gabriel Scherer <gabriel.scherer at gmail.com>
+Date: Mon, 4 Dec 2017 23:33:52 +0000
+Subject: [PATCH 2/3] build_path_prefix_map: update .depend and Makefiles
+
+---
+ .depend | 7 +++++--
+ Makefile | 1 +
+ debugger/Makefile | 1 +
+ ocamldoc/.depend | 14 +++++++-------
+ ocamldoc/Makefile | 2 +-
+ otherlibs/dynlink/Makefile | 1 +
+ tools/Makefile | 4 +++-
+ 7 files changed, 19 insertions(+), 11 deletions(-)
+
+--- a/.depend
++++ b/.depend
+@@ -1,6 +1,9 @@
+ utils/arg_helper.cmo : utils/arg_helper.cmi
+ utils/arg_helper.cmx : utils/arg_helper.cmi
+ utils/arg_helper.cmi :
++utils/build_path_prefix_map.cmo : utils/build_path_prefix_map.cmi
++utils/build_path_prefix_map.cmx : utils/build_path_prefix_map.cmi
++utils/build_path_prefix_map.cmi :
+ utils/ccomp.cmo : utils/misc.cmi utils/config.cmi utils/clflags.cmi \
+ utils/ccomp.cmi
+ utils/ccomp.cmx : utils/misc.cmx utils/config.cmx utils/clflags.cmx \
+@@ -108,9 +111,9 @@
+ parsing/location.cmx parsing/docstrings.cmx parsing/lexer.cmi
+ parsing/lexer.cmi : parsing/parser.cmi parsing/location.cmi
+ parsing/location.cmo : utils/warnings.cmi utils/terminfo.cmi utils/misc.cmi \
+- utils/clflags.cmi parsing/location.cmi
++ utils/clflags.cmi utils/build_path_prefix_map.cmi parsing/location.cmi
+ parsing/location.cmx : utils/warnings.cmx utils/terminfo.cmx utils/misc.cmx \
+- utils/clflags.cmx parsing/location.cmi
++ utils/clflags.cmx utils/build_path_prefix_map.cmx parsing/location.cmi
+ parsing/location.cmi : utils/warnings.cmi
+ parsing/longident.cmo : utils/misc.cmi parsing/longident.cmi
+ parsing/longident.cmx : utils/misc.cmx parsing/longident.cmi
+--- a/Makefile
++++ b/Makefile
+@@ -88,6 +88,7 @@
+ utils/terminfo.cmo utils/ccomp.cmo utils/warnings.cmo \
+ utils/consistbl.cmo \
+ utils/strongly_connected_components.cmo \
++ utils/build_path_prefix_map.cmo \
+ utils/targetint.cmo
+
+ PARSING=parsing/location.cmo parsing/longident.cmo \
+--- a/debugger/Makefile
++++ b/debugger/Makefile
+@@ -39,6 +39,7 @@
+ ../utils/identifiable.cmo ../utils/numbers.cmo \
+ ../utils/arg_helper.cmo ../utils/clflags.cmo \
+ ../utils/consistbl.cmo ../utils/warnings.cmo \
++ ../utils/build_path_prefix_map.cmo \
+ ../utils/terminfo.cmo \
+ ../parsing/location.cmo ../parsing/longident.cmo ../parsing/docstrings.cmo \
+ ../parsing/syntaxerr.cmo \
+--- a/ocamldoc/.depend
++++ b/ocamldoc/.depend
+@@ -218,19 +218,19 @@
+ ../parsing/parsetree.cmi odoc_value.cmo odoc_types.cmi odoc_type.cmo \
+ odoc_parameter.cmo odoc_module.cmo odoc_misc.cmi odoc_messages.cmo \
+ odoc_merge.cmi odoc_global.cmi odoc_extension.cmo odoc_exception.cmo \
+- odoc_env.cmi odoc_class.cmo ../utils/misc.cmi ../parsing/location.cmi \
+- ../typing/ident.cmi ../typing/ctype.cmi ../typing/btype.cmi \
+- ../parsing/asttypes.cmi odoc_sig.cmi
++ odoc_env.cmi odoc_class.cmo ../utils/misc.cmi ../parsing/longident.cmi \
++ ../parsing/location.cmi ../typing/ident.cmi ../typing/ctype.cmi \
++ ../typing/btype.cmi ../parsing/asttypes.cmi odoc_sig.cmi
+ odoc_sig.cmx : ../typing/types.cmx ../typing/typedtree.cmx \
+ ../parsing/parsetree.cmi odoc_value.cmx odoc_types.cmx odoc_type.cmx \
+ odoc_parameter.cmx odoc_module.cmx odoc_misc.cmx odoc_messages.cmx \
+ odoc_merge.cmx odoc_global.cmx odoc_extension.cmx odoc_exception.cmx \
+- odoc_env.cmx odoc_class.cmx ../utils/misc.cmx ../parsing/location.cmx \
+- ../typing/ident.cmx ../typing/ctype.cmx ../typing/btype.cmx \
+- ../parsing/asttypes.cmi odoc_sig.cmi
++ odoc_env.cmx odoc_class.cmx ../utils/misc.cmx ../parsing/longident.cmx \
++ ../parsing/location.cmx ../typing/ident.cmx ../typing/ctype.cmx \
++ ../typing/btype.cmx ../parsing/asttypes.cmi odoc_sig.cmi
+ odoc_sig.cmi : ../typing/types.cmi ../typing/typedtree.cmi \
+ ../parsing/parsetree.cmi odoc_types.cmi odoc_type.cmo odoc_name.cmi \
+- odoc_module.cmo odoc_env.cmi odoc_class.cmo
++ odoc_module.cmo odoc_env.cmi odoc_class.cmo ../parsing/location.cmi
+ odoc_str.cmo : ../typing/types.cmi ../typing/printtyp.cmi odoc_value.cmo \
+ odoc_type.cmo odoc_print.cmi odoc_name.cmi odoc_misc.cmi \
+ odoc_messages.cmo odoc_extension.cmo odoc_exception.cmo odoc_class.cmo \
+--- a/ocamldoc/Makefile
++++ b/ocamldoc/Makefile
+@@ -97,8 +97,8 @@
+ #############
+
+ INCLUDES_DEP=\
+- -I $(ROOTDIR)/parsing \
+ -I $(ROOTDIR)/utils \
++ -I $(ROOTDIR)/parsing \
+ -I $(ROOTDIR)/typing \
+ -I $(ROOTDIR)/driver \
+ -I $(ROOTDIR)/bytecomp \
+--- a/otherlibs/dynlink/Makefile
++++ b/otherlibs/dynlink/Makefile
+@@ -43,6 +43,7 @@
+ ../../utils/arg_helper.cmo ../../utils/clflags.cmo \
+ ../../utils/tbl.cmo ../../utils/consistbl.cmo \
+ ../../utils/terminfo.cmo ../../utils/warnings.cmo \
++ ../../utils/build_path_prefix_map.cmo \
+ ../../parsing/asttypes.cmi \
+ ../../parsing/location.cmo ../../parsing/longident.cmo \
+ ../../parsing/docstrings.cmo ../../parsing/syntaxerr.cmo \
+--- a/tools/Makefile
++++ b/tools/Makefile
+@@ -128,6 +128,7 @@
+ CSLPROF=ocamlprof.cmo
+ CSLPROF_IMPORTS=misc.cmo config.cmo identifiable.cmo numbers.cmo \
+ arg_helper.cmo clflags.cmo terminfo.cmo \
++ build_path_prefix_map.cmo \
+ warnings.cmo location.cmo longident.cmo docstrings.cmo \
+ syntaxerr.cmo ast_helper.cmo parser.cmo lexer.cmo parse.cmo
+
+@@ -179,7 +180,7 @@
+ # Converter olabl/ocaml 2.99 to ocaml 3
+
+ OCAML299TO3= lexer299.cmo ocaml299to3.cmo
+-LIBRARY3= misc.cmo warnings.cmo location.cmo
++LIBRARY3= misc.cmo warnings.cmo build_path_prefix_map.cmo location.cmo
+
+ ocaml299to3: $(OCAML299TO3)
+ $(CAMLC) $(LINKFLAGS) -o ocaml299to3 $(LIBRARY3) $(OCAML299TO3)
+@@ -213,6 +214,7 @@
+
+ ADDLABELS_IMPORTS=misc.cmo config.cmo arg_helper.cmo clflags.cmo \
+ identifiable.cmo numbers.cmo terminfo.cmo \
++ build_path_prefix_map.cmo \
+ warnings.cmo location.cmo longident.cmo docstrings.cmo \
+ syntaxerr.cmo ast_helper.cmo parser.cmo lexer.cmo parse.cmo
+
diff --git a/debian/patches/0003-honor-the-BUILD_PATH_PREFIX_MAP-variable-if-it-exist.patch b/debian/patches/0003-honor-the-BUILD_PATH_PREFIX_MAP-variable-if-it-exist.patch
new file mode 100644
index 0000000..1aec080
--- /dev/null
+++ b/debian/patches/0003-honor-the-BUILD_PATH_PREFIX_MAP-variable-if-it-exist.patch
@@ -0,0 +1,116 @@
+From 67f79f7cdff12605437e84c7c4abb845335dab85 Mon Sep 17 00:00:00 2001
+From: Gabriel Scherer <gabriel.scherer at gmail.com>
+Date: Mon, 4 Dec 2017 23:39:06 +0000
+Subject: [PATCH 3/3] honor the BUILD_PATH_PREFIX_MAP variable if it exists:
+
+ <https://reproducible-builds.org/specs/build-path-prefix-map/>
+---
+ Changes | 4 ++++
+ bytecomp/bytelink.ml | 6 +++---
+ bytecomp/emitcode.ml | 6 ++++--
+ parsing/location.ml | 22 +++++++++++++++++++++-
+ parsing/location.mli | 5 +++++
+ typing/cmt_format.ml | 2 +-
+ 6 files changed, 38 insertions(+), 7 deletions(-)
+
+--- a/Changes
++++ b/Changes
+@@ -5,6 +5,10 @@
+
+ ### Language features:
+
++- GPR#1515: honor the BUILD_PATH_PREFIX_MAP environment variable
++ to enable reproducible builds
++ (Gabriel Scherer, with help from Ximin Luo in Marrakech)
++
+ ### Code generation and optimizations:
+
+ - MPR#7201, GPR#954: Correct wrong optimisation of "0 / <expr>"
+--- a/bytecomp/bytelink.ml
++++ b/bytecomp/bytelink.ml
+@@ -295,9 +295,9 @@
+ (* Transform a file name into an absolute file name *)
+
+ let make_absolute file =
+- if Filename.is_relative file
+- then Filename.concat (Sys.getcwd()) file
+- else file
++ if not (Filename.is_relative file) then file
++ else Location.rewrite_absolute_path
++ (Filename.concat (Sys.getcwd()) file)
+
+ (* Create a bytecode executable file *)
+
+--- a/bytecomp/emitcode.ml
++++ b/bytecomp/emitcode.ml
+@@ -146,8 +146,10 @@
+ let path = ev.ev_loc.Location.loc_start.Lexing.pos_fname in
+ let abspath = Location.absolute_path path in
+ debug_dirs := StringSet.add (Filename.dirname abspath) !debug_dirs;
+- if Filename.is_relative path then
+- debug_dirs := StringSet.add (Sys.getcwd ()) !debug_dirs;
++ if Filename.is_relative path then begin
++ let cwd = Location.rewrite_absolute_path (Sys.getcwd ()) in
++ debug_dirs := StringSet.add cwd !debug_dirs;
++ end;
+ ev.ev_pos <- !out_position;
+ events := ev :: !events
+
+--- a/parsing/location.ml
++++ b/parsing/location.ml
+@@ -222,9 +222,29 @@
+
+ open Format
+
++let rewrite_absolute_path =
++ let init = ref false in
++ let map_cache = ref None in
++ fun path ->
++ if not !init then begin
++ init := true;
++ match Sys.getenv "BUILD_PATH_PREFIX_MAP" with
++ | exception Not_found -> ()
++ | encoded_map ->
++ match Build_path_prefix_map.decode_map encoded_map with
++ | Error err -> failwith err (* TODO improve *)
++ | Ok map -> map_cache := Some map
++ end;
++ match !map_cache with
++ | None -> path
++ | Some map -> Build_path_prefix_map.rewrite map path
++
+ let absolute_path s = (* This function could go into Filename *)
+ let open Filename in
+- let s = if is_relative s then concat (Sys.getcwd ()) s else s in
++ let s =
++ if not (is_relative s) then s
++ else (rewrite_absolute_path (concat (Sys.getcwd ()) s))
++ in
+ (* Now simplify . and .. components *)
+ let rec aux s =
+ let base = basename s in
+--- a/parsing/location.mli
++++ b/parsing/location.mli
+@@ -83,6 +83,11 @@
+ val print_compact: formatter -> t -> unit
+ val print_filename: formatter -> string -> unit
+
++val rewrite_absolute_path: string -> string
++ (** rewrite absolute path to honor the BUILD_PATH_PREFIX_MAP
++ variable (https://reproducible-builds.org/specs/build-path-prefix-map/)
++ if it is set. *)
++
+ val absolute_path: string -> string
+
+ val show_filename: string -> string
+--- a/typing/cmt_format.ml
++++ b/typing/cmt_format.ml
+@@ -180,7 +180,7 @@
+ cmt_comments = Lexer.comments ();
+ cmt_args = Sys.argv;
+ cmt_sourcefile = sourcefile;
+- cmt_builddir = Sys.getcwd ();
++ cmt_builddir = Location.rewrite_absolute_path (Sys.getcwd ());
+ cmt_loadpath = !Config.load_path;
+ cmt_source_digest = source_digest;
+ cmt_initial_env = if need_to_clear_env then
diff --git a/debian/patches/series b/debian/patches/series
index 1196040..dda5f49 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -9,3 +9,6 @@
0011-arm64-hide-symbols-for-stricter-binutils.patch
0013-Use-CCLINKFLAGS-for-linking-all-executables-and-shar.patch
0014-Compute-a-stable-name-for-preprocessed-files.patch
+0001-utils-import-build_path_prefix_map-library.patch
+0002-build_path_prefix_map-update-.depend-and-Makefiles.patch
+0003-honor-the-BUILD_PATH_PREFIX_MAP-variable-if-it-exist.patch
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/ocaml.git
More information about the Reproducible-commits
mailing list