The unpac monorepo manager self-hosting as a monorepo using unpac
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Test all three bytecode search methods

+144 -41
+1
.gitignore
··· 272 272 /testsuite/_retries 273 273 274 274 /testsuite/tools/codegen 275 + /testsuite/tools/poisonedruntime 275 276 /testsuite/tools/expect 276 277 /testsuite/tools/lexcmm.ml 277 278 /testsuite/tools/parsecmm.ml
+4
Makefile
··· 2055 2055 2056 2056 testsuite/tools/test_in_prefi%: CAMLOPT = $(BEST_OCAMLOPT) $(STDLIBFLAGS) 2057 2057 2058 + testsuite/tools/poisonedruntime$(EXE): testsuite/tools/poisonedruntime.$(O) 2059 + $(V_MKEXE)$(call MKEXE_VIA_CC,$@,$^) 2060 + 2058 2061 ocamltest_BYTECODE_LINKFLAGS = -custom -g 2059 2062 2060 2063 ocamltest/ocamltest$(EXE): ocamlc ocamlyacc ocamllex ··· 2106 2109 rm -f $(addprefix testsuite/lib/*.,cm* o obj a lib) 2107 2110 rm -f $(addprefix testsuite/tools/*.,cm* o obj a lib) 2108 2111 rm -f testsuite/tools/codegen testsuite/tools/codegen.exe 2112 + rm -f testsuite/tools/poisonedruntime testsuite/tools/poisonedruntime.exe 2109 2113 rm -f testsuite/tools/expect testsuite/tools/expect.exe 2110 2114 rm -f testsuite/tools/test_in_prefix testsuite/tools/test_in_prefix.exe 2111 2115 rm -f testsuite/tools/test_in_prefix.opt \
+9 -1
testsuite/in_prefix/Makefile.test
··· 38 38 VERBOSE_FLAG = 39 39 endif 40 40 41 - test-in-prefix: $(DRIVER) ../tools/main_in_c.$(O) 41 + export PATH := $(SRCDIR_ABS)/testsuite/in_prefix/poisoned-runtime:$(PATH) 42 + 43 + test-in-prefix: $(DRIVER) ../tools/main_in_c.$(O) ../tools/poisonedruntime$(EXE) 44 + @rm -f ocamlrun* 45 + @$(LN) $(ROOTDIR)/runtime/ocamlrun$(EXE) test-ocamlrun$(EXE) 46 + @$(MKDIR) poisoned-runtime 47 + @cd poisoned-runtime && $(LN) ../../tools/poisonedruntime$(EXE) ocamlrun$(EXE) 42 48 @$< $(DRIVER_ARGS) 49 + @rm -rf poisoned-runtime 50 + @rm -f test-ocamlrun$(EXE) 43 51 44 52 SCRUB_ENV = \ 45 53 CAML_LD_LIBRARY_PATH OCAMLLIB CAMLLIB OCAMLPARAM OCAMLRUNPARAM CAMLRUNPARAM
+11 -9
testsuite/tools/environment.ml
··· 46 46 47 47 (* Derived properties *) 48 48 49 - let is_renamed {phase; _} = (phase = Renamed) 49 + let is_renamed {phase; _} = (phase <> Original) 50 50 51 51 let bindir {prefix; bindir_suffix; _} = 52 52 Filename.concat prefix bindir_suffix ··· 180 180 let value = 181 181 String.sub binding (equals + 1) (String.length binding - equals - 1) 182 182 in 183 - if is_path_env name then 183 + if phase <> Execution && is_path_env name then 184 184 if Sys.win32 then 185 185 if String.index_opt bindir ';' <> None then 186 186 Printf.sprintf "%s=\"%s\";%s" name bindir value ··· 226 226 highlighted. If argv0 is specified, then the original program executable is 227 227 also shown. *) 228 228 let display_execution level status pid ~runtime program argv0 args 229 - ({pp_path; verbose; serial; _} as env) = 229 + ({pp_path; verbose; serial; phase; _} as env) = 230 230 let pp_program style program f = function 231 231 | Some argv0 -> 232 232 Format.fprintf f "@{<%s>%s (from %a)@}" ··· 269 269 if serial <> !last_environment then begin 270 270 last_environment := serial; 271 271 Format.printf "\ 272 - @{<inline_code>> @}@{<loc>Environment@}\n\ 273 - @{<inline_code>> @} @{<loc>PATH=%a:$PATH@}\n" 274 - pp_path (bindir env); 272 + @{<inline_code>> @}@{<loc>Environment@}\n"; 273 + if phase <> Execution then 274 + Format.printf "\ 275 + @{<inline_code>> @} @{<loc>PATH=%a:$PATH@}\n" 276 + pp_path (bindir env); 275 277 if not Sys.win32 then 276 278 Format.printf "\ 277 279 @{<inline_code>> @} @{<loc>%s=%a:$%s@}\n" ··· 428 430 (* The tests are easier to write with the assumption that shims are 429 431 simply ignored in the Original phase (otherwise they all begin 430 432 [Env.is_renamed env && (* ... *)] *) 431 - let runtime = runtime && phase = Renamed in 433 + let runtime = runtime && phase <> Original in 432 434 let env = 433 - if phase = Renamed && (stubs || stdlib) then 435 + if phase <> Original && (stubs || stdlib) then 434 436 apply_shims ~stubs ~stdlib env 435 437 else 436 438 env ··· 449 451 fails without each shim in turn. The final entry in the strategy must be 450 452 the request itself. *) 451 453 let test_without cond shim strategy = 452 - if phase = Renamed && cond then 454 + if phase <> Original && cond then 453 455 shim env :: strategy 454 456 else 455 457 strategy
+1 -1
testsuite/tools/environment.mli
··· 37 37 with [LD_LIBRARY_PATH] / [DYLD_LIBRARY_PATH] set or updated). *) 38 38 39 39 val is_renamed : t -> bool 40 - (** [is_renamed t] if [~phase = Renamed] *) 40 + (** [is_renamed t] if [~phase <> Original] *) 41 41 42 42 val test_root : t -> string 43 43 (** Retrieves the [~test_root] passed to {!make}. *)
+1 -1
testsuite/tools/harness.ml
··· 23 23 | Custom 24 24 | Vanilla 25 25 26 - type phase = Original | Renamed 26 + type phase = Original | Execution | Renamed 27 27 28 28 type mode = Bytecode | Native 29 29
+5 -2
testsuite/tools/harness.mli
··· 39 39 40 40 (** Test harness phases. *) 41 41 type phase = 42 - | Original (* Compiler installed in its original configured prefix. *) 43 - | Renamed (* Compiler moved to a different prefix from its configuration. *) 42 + | Original (* Compiler installed in its original configured prefix. *) 43 + | Execution (* Executing programs built by the compiler installed in its 44 + original prefix after the compiler has been moved to a 45 + different prefix. *) 46 + | Renamed (* Compiler moved to a different prefix from its configuration. *) 44 47 45 48 (* Tooling modes. *) 46 49 type mode =
+27
testsuite/tools/poisonedruntime.c
··· 1 + /**************************************************************************/ 2 + /* */ 3 + /* OCaml */ 4 + /* */ 5 + /* David Allsopp, University of Cambridge & Tarides */ 6 + /* */ 7 + /* Copyright 2025 David Allsopp Ltd. */ 8 + /* */ 9 + /* All rights reserved. This file is distributed under the terms of */ 10 + /* the GNU Lesser General Public License version 2.1, with the */ 11 + /* special exception on linking described in the file LICENSE. */ 12 + /* */ 13 + /**************************************************************************/ 14 + 15 + /* Micro-program used to sit in PATH to test local path search for bytecode 16 + executables. */ 17 + 18 + #define CAML_INTERNALS 19 + #include <caml/callback.h> 20 + #include <stdio.h> 21 + 22 + int main_os(int argc, char_os **argv) 23 + { 24 + printf("The poisoned runtime has been invoked!\n" 25 + "This suggests something is wrong in stdlib/header.c\n"); 26 + return 1; 27 + }
+68 -24
testsuite/tools/testLinkModes.ml
··· 364 364 tendered && not target_launcher_searches_for_ocamlrun 365 365 && (config.has_relative_libdir = None || not (Environment.is_renamed env)) 366 366 in 367 - let rec run env = 367 + let rec run ~re_executing env = 368 368 let runs = 369 369 test_runs usr_bin_sh test_program_path test_program 370 370 config env ~via_ocamlrun in 371 371 let execute ({argv0; prefix_path_with_cwd}, outcome) = 372 372 let expected_executable_name, expected_exit_code, expected_argv0 = 373 373 match outcome with 374 - | Fail code -> "", code, "" 375 - | Success {executable_name; argv0} -> executable_name, 0, argv0 374 + | Fail code -> 375 + "", code, "" 376 + | Success {executable_name; argv0} -> 377 + (* Systems which don't have caml_executable_name get particularly 378 + fiddly here, because they can fail for multiple reasons in this 379 + test! Any tendered executable which was expected to succeed is 380 + set to fail here, since the shim for CAML_LD_LIBRARY_PATH will 381 + not be applied. *) 382 + if tendered && with_unix && Harness.no_caml_executable_name 383 + (* Passing the executable directly to ocamlrun will fail if 384 + ocamlrun isn't configured with a relative libdir *) 385 + && (not via_ocamlrun || config.has_relative_libdir = None) 386 + && (re_executing || Environment.is_renamed env 387 + && config.has_relative_libdir = None) then 388 + "", 134, "" 389 + else 390 + executable_name, 0, argv0 376 391 in 377 - let stubs = tendered && with_unix && config.has_relative_libdir = None in 392 + let stubs = 393 + tendered && with_unix 394 + (* The programs compiled before the prefix is renamed are intentionally 395 + run without the runtime in PATH in order to test the bytecode 396 + launcher's searching in the image directory before PATH. A side 397 + effect of this is that ld.conf then can't be found, because the 398 + runtime copied to the testsuite directory doesn't have ld.conf in the 399 + correct place. The shim is skipped for systems which don't have 400 + caml_executable_name because otherwise we'd have a test which fails 401 + in the Original phase and succeeds in the Execution phase, which is a 402 + special case too far! *) 403 + && (not Harness.no_caml_executable_name 404 + && (config.has_relative_libdir = None 405 + || not via_ocamlrun && re_executing)) 406 + in 378 407 run_program 379 408 env config ~runtime:via_ocamlrun ~stubs 380 409 test_program_path ~prefix_path_with_cwd expected_executable_name ··· 386 415 if Environment.is_renamed env then 387 416 (Harness.erase_file test_program_path; `None) 388 417 else 389 - `Some run 418 + `Some (run ~re_executing:true) 390 419 in 391 - `Some run 420 + `Some (run ~re_executing:false) 392 421 393 422 (* Describe the various ways in which executables can be produced by our two 394 423 compilers... *) 395 424 type linkage = 396 - | Default_ocamlc of launch_mode 425 + | Default_ocamlc of launch_mode * Config.search_method 397 426 | Default_ocamlopt 398 427 | Custom_runtime of runtime_mode 399 428 | Output_obj of compiler * runtime_mode ··· 462 491 0 463 492 in 464 493 match test with 465 - | Default_ocamlc Header_exe -> 466 - let args = 467 - if config.bytecode_shebangs_by_default then 468 - ["-launch-method"; "exe"] 469 - else 470 - [] in 471 - f ~tendered:true args 472 - | Default_ocamlc Header_shebang -> 494 + | Default_ocamlc(launch_method, search_method) -> 473 495 let args = 474 - if config.bytecode_shebangs_by_default then 475 - [] 476 - else 477 - ["-launch-method"; "sh"] in 478 - f ~tendered:true args 496 + match launch_method with 497 + | Header_exe when config.bytecode_shebangs_by_default -> 498 + ["-launch-method"; "exe"] 499 + | Header_shebang when not config.bytecode_shebangs_by_default -> 500 + ["-launch-method"; "sh"] 501 + | _ -> 502 + [] in 503 + let target_launcher_searches_for_ocamlrun = 504 + (search_method <> Config.Disable) 505 + in 506 + let param = 507 + match search_method with 508 + | Disable -> "disable" 509 + | Fallback -> "fallback" 510 + | Enable -> "enable" 511 + in 512 + let args = "-runtime-search" :: param :: args in 513 + f ~target_launcher_searches_for_ocamlrun ~tendered:true args 479 514 | Default_ocamlopt -> 480 515 f ~mode:Native [] 481 516 | Custom_runtime Static -> ··· 700 735 pp_path ocamlc_where pp_path ocamlopt_where; 701 736 let compile_test = compile_test sh config env in 702 737 let tests = [ 703 - compile_test (Default_ocamlc Header_exe) 704 - "byt_default_exe" "with tender"; 738 + compile_test (Default_ocamlc(Header_exe, Disable)) 739 + "byt_default_exe_disable" "with absolute tender"; 740 + compile_test (Default_ocamlc(Header_exe, Fallback)) 741 + "byt_default_exe_fallback" "with fallback tender"; 742 + compile_test (Default_ocamlc(Header_exe, Enable)) 743 + "byt_default_exe_enable" "with relocatable tender"; 705 744 compile_test (Custom_runtime Static) 706 745 "custom_static" "-custom static runtime"; 707 746 compile_test (Custom_runtime Shared) ··· 731 770 ] in 732 771 let tests = 733 772 if Config.shebangscripts then 734 - (compile_test (Default_ocamlc Header_shebang) "byt_default_sh" "with #!") 735 - :: tests 773 + (compile_test (Default_ocamlc(Header_shebang, Disable)) 774 + "byt_default_sh_disable" "with absolute #!") :: 775 + (compile_test (Default_ocamlc(Header_shebang, Fallback)) 776 + "byt_default_sh_fallback" "with fallback #!") :: 777 + (compile_test (Default_ocamlc(Header_shebang, Enable)) 778 + "byt_default_sh_enable" "with relocatable #!") :: 779 + tests 736 780 else 737 781 tests in 738 782 Printf.printf "Running programs\n%!";
+17 -3
testsuite/tools/test_in_prefix.ml
··· 68 68 TestBytecodeBinaries.run config env; 69 69 TestLinkModes.run ~sh config env 70 70 71 + let rename_exe_in_test_root env from_base to_base = 72 + Sys.rename (Environment.in_test_root env (Harness.exe from_base)) 73 + (Environment.in_test_root env (Harness.exe to_base)) 74 + 71 75 let () = 72 76 let ~config, ~pwd, ~prefix, ~bindir:_, ~bindir_suffix, ~libdir, 73 77 ~libdir_suffix, ~summarise_only, ~verbose = ··· 215 219 pp_path prefix; 216 220 Sys.rename new_prefix prefix); 217 221 let env = 218 - make_env ~phase:Renamed ~prefix:new_prefix ~bindir_suffix ~libdir_suffix in 222 + make_env ~phase:Execution ~prefix:new_prefix ~bindir_suffix ~libdir_suffix 223 + in 219 224 (* 3. Re-run the test programs compiled with the normal prefix *) 220 225 Printf.printf "Re-running test programs\n%!"; 221 - List.iter 222 - (function `Some f -> assert (f env = `None) | `None -> ()) programs; 226 + (* Verify that the searching runtimes are searching the directory containing 227 + the program itself first. *) 228 + let runtime = "ocamlrun" in 229 + rename_exe_in_test_root env ("test-" ^ runtime) runtime; 230 + Fun.protect 231 + ~finally:(fun () -> rename_exe_in_test_root env runtime ("test-" ^ runtime)) 232 + (fun () -> 233 + List.iter 234 + (function `Some f -> assert (f env = `None) | `None -> ()) programs); 235 + let env = 236 + make_env ~phase:Renamed ~prefix:new_prefix ~bindir_suffix ~libdir_suffix in 223 237 (* 4. Finally re-run the main test battery in the new prefix *) 224 238 Compmisc.init_path ~standard_library:libdir (); 225 239 let programs = run_tests env in