Skip to content

Commit

Permalink
Backport PR #13523: [envars] honor file "coq_environment.txt"
Browse files Browse the repository at this point in the history
  • Loading branch information
gares committed Dec 5, 2020
2 parents e974541 + 793fc13 commit 842bed6
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 8 deletions.
10 changes: 10 additions & 0 deletions INSTALL.md
Expand Up @@ -99,3 +99,13 @@ dependencies...) as Coq. Distribution of pre-compiled plugins and
Coq version compiled with the same OCaml toolchain. An OCaml setup
mismatch is the most probable cause for an `Error while loading ...:
implementation mismatch on ...`.

coq_environment.txt
-------------------
Coq binaries which honor environment variables, such as `COQLIB`, can
be seeded values for these variables by placing a text file named
`coq_environment.txt` next to them. The file can contain assignments
like `COQLIB="some path"`, that is a variable name followed by `=` and
a string that follows OCaml's escaping conventions. This feature can be
used by installers of binary package to make Coq aware of its installation
path.
34 changes: 32 additions & 2 deletions lib/envars.ml
Expand Up @@ -12,7 +12,37 @@ open Util

(** {1 Helper functions} *)

let getenv_else s dft = try Sys.getenv s with Not_found -> dft ()
let parse_env_line l =
try Scanf.sscanf l "%[^=]=%S" (fun name value -> Some(name,value))
with _ -> None

let with_ic file f =
let ic = open_in file in
try
let rc = f ic in
close_in ic;
rc
with e -> close_in ic; raise e

let getenv_from_file name =
let base = Filename.dirname Sys.executable_name in
try
with_ic (base ^ "/coq_environment.txt") (fun ic ->
let rec find () =
let l = input_line ic in
match parse_env_line l with
| Some(n,v) when n = name -> v
| _ -> find ()
in
find ())
with
| Sys_error s -> raise Not_found
| End_of_file -> raise Not_found

let system_getenv name =
try Sys.getenv name with Not_found -> getenv_from_file name

let getenv_else s dft = try system_getenv s with Not_found -> dft ()

let safe_getenv warning n =
getenv_else n (fun () ->
Expand Down Expand Up @@ -145,7 +175,7 @@ let coqpath =

(** {2 Caml paths} *)

let ocamlfind () = Coq_config.ocamlfind
let ocamlfind () = getenv_else "OCAMLFIND" (fun () -> Coq_config.ocamlfind)

(** {1 XDG utilities} *)

Expand Down
6 changes: 5 additions & 1 deletion test-suite/dune
Expand Up @@ -8,6 +8,10 @@
(targets libpath.inc)
(action (with-stdout-to %{targets} (run ./ocaml_pwd.exe -quoted ../../install/%{context_name}/lib/coq/ ))))

(rule
(targets bin.inc)
(action (with-stdout-to %{targets} (run ./ocaml_pwd.exe -quoted -trailing-slash ../../install/%{context_name}/bin/ ))))

(rule
(targets summary.log)
(deps
Expand Down Expand Up @@ -44,4 +48,4 @@
; %{bin:fake_ide}
(action
(progn
(bash "make -j %{env:NJOBS=2} BIN= COQLIB=%{read:libpath.inc} PRINT_LOGS=1 UNIT_TESTS=%{env:COQ_UNIT_TEST=unit-tests}"))))
(bash "make -j %{env:NJOBS=2} BIN=%{read:bin.inc} COQLIB=%{read:libpath.inc} PRINT_LOGS=1 UNIT_TESTS=%{env:COQ_UNIT_TEST=unit-tests}"))))
51 changes: 51 additions & 0 deletions test-suite/misc/coq_environment.sh
@@ -0,0 +1,51 @@
#!/usr/bin/env bash

export COQBIN=$BIN
export PATH=$COQBIN:$PATH

TMP=`mktemp -d`
cd $TMP

cat > coq_environment.txt <<EOT
# we override COQLIB because we can
COQLIB="$TMP/overridden" # bla bla
OCAMLFIND="$TMP/overridden"
FOOBAR="one more"
EOT

cp $BIN/coqc .
cp $BIN/coq_makefile .
mkdir -p overridden/tools/
cp $COQLIB/tools/CoqMakefile.in overridden/tools/

unset COQLIB
N=`./coqc -config | grep COQLIB | grep /overridden | wc -l`
if [ $N -ne 1 ]; then
echo COQLIB not overridden by coq_environment
coqc -config
exit 1
fi
N=`./coqc -config | grep OCAMLFIND | grep /overridden | wc -l`
if [ $N -ne 1 ]; then
echo OCAMLFIND not overridden by coq_environment
coqc -config
exit 1
fi
./coq_makefile -o CoqMakefile -R . foo > /dev/null
N=`grep COQMF_OCAMLFIND CoqMakefile.conf | grep /overridden | wc -l`
if [ $N -ne 1 ]; then
echo COQMF_OCAMLFIND not overridden by coq_environment
cat CoqMakefile.conf
exit 1
fi

export COQLIB="/overridden2"
N=`./coqc -config | grep COQLIB | grep /overridden2 | wc -l`
if [ $N -ne 1 ]; then
echo COQLIB not overridden by COQLIB when coq_environment present
coqc -config
exit 1
fi

rm -rf $TMP
exit 0
27 changes: 23 additions & 4 deletions test-suite/ocaml_pwd.ml
@@ -1,7 +1,26 @@
open Arg

let quoted = ref false
let trailing_slash = ref false

let arguments = [
"-quoted",Set quoted, "Quote path";
"-trailing-slash",Set trailing_slash, "End the path with a /";
]
let subject = ref None
let set_subject x =
if !subject <> None then
failwith "only one path";
subject := Some x

let _ =
let quoted = Sys.argv.(1) = "-quoted" in
let ch_dir = Sys.argv.(if quoted then 2 else 1) in
Sys.chdir ch_dir;
Arg.parse arguments set_subject "Usage:";
let subject =
match !subject with
| None -> failwith "no path given";
| Some x -> x in
Sys.chdir subject;
let dir = Sys.getcwd () in
let dir = if quoted then Filename.quote dir else dir in
let dir = if !trailing_slash then dir ^ "/" else dir in
let dir = if !quoted then Filename.quote dir else dir in
Format.printf "%s%!" dir
2 changes: 1 addition & 1 deletion tools/coq_makefile.ml
Expand Up @@ -216,7 +216,7 @@ let generate_conf_coq_config oc =
section oc "Coq configuration.";
let src_dirs = Coq_config.all_src_dirs in
Envars.print_config ~prefix_var_name:"COQMF_" oc src_dirs;
fprintf oc "COQMF_WINDRIVE=%s\n" (windrive Coq_config.coqlib)
fprintf oc "COQMF_WINDRIVE=%s\n" (windrive (Envars.coqlib()))
;;

let generate_conf_files oc
Expand Down

0 comments on commit 842bed6

Please sign in to comment.