From 90202ee419f8b55aed797ccf66585fd20fa33c57 Mon Sep 17 00:00:00 2001 From: Pierre Boutillier Date: Tue, 17 Sep 2024 16:41:44 +0200 Subject: [PATCH 1/5] configurator: Allow to specify a path in PKG_CONFIG This makes the implementation of `which` in configurator closer to the one of stdune. Signed-off-by: Pierre Boutillier --- otherlibs/configurator/src/v1.ml | 9 +++++++-- .../test/blackbox-tests/pkg-config-quoting.t/run.t | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/otherlibs/configurator/src/v1.ml b/otherlibs/configurator/src/v1.ml index e54ac7785dc..86a2a67e0c2 100644 --- a/otherlibs/configurator/src/v1.ml +++ b/otherlibs/configurator/src/v1.ml @@ -91,8 +91,13 @@ module Find_in_path = struct ;; let which prog = - List.find_map (get_path ()) ~f:(fun dir -> - let fn = dir ^/ prog ^ exe in + if Filename.is_implicit prog + then + List.find_map (get_path ()) ~f:(fun dir -> + let fn = dir ^/ prog ^ exe in + Option.some_if (Sys.file_exists fn) fn) + else ( + let fn = if Filename.check_suffix prog exe then prog else prog ^ exe in Option.some_if (Sys.file_exists fn) fn) ;; end diff --git a/otherlibs/configurator/test/blackbox-tests/pkg-config-quoting.t/run.t b/otherlibs/configurator/test/blackbox-tests/pkg-config-quoting.t/run.t index 2afc5783dad..08ab88fa1f4 100644 --- a/otherlibs/configurator/test/blackbox-tests/pkg-config-quoting.t/run.t +++ b/otherlibs/configurator/test/blackbox-tests/pkg-config-quoting.t/run.t @@ -1,5 +1,5 @@ -These tests show how various pkg-config invocations get quotes: - $ dune build 2>&1 | awk '/run:.*bin\/pkg-config/{a=1}/stderr/{a=0}a' +These tests show how various pkg-config invocations get quotes (and test specifying a custom PKG_CONFIG): + $ PKG_CONFIG=$PWD/_build/install/default/bin/pkg-config dune build 2>&1 | awk '/run:.*bin\/pkg-config/{a=1}/stderr/{a=0}a' run: $TESTCASE_ROOT/_build/install/default/bin/pkg-config --print-errors gtk+-quartz-3.0 -> process exited with code 0 -> stdout: From c29795b21acd38b835e8ce03bbb1a98af47bd224 Mon Sep 17 00:00:00 2001 From: Pierre Boutillier Date: Wed, 18 Sep 2024 11:11:41 +0200 Subject: [PATCH 2/5] Configurator: try to call pkgconf before failing back to pkg-config Pkgconf is a modern implementation of the "pkg-config freedesktop standard". Linux distros actually use pkgconf as their pkg-config implementation and provide a in place replacement. (Homebrew packages both and is the last place I found where you can get the historical implementation). It is always OK to call pkgconf for pkg-config all the CLI and outputs within the standard are following the standard :-). Cygwin pkg-config package though provides pkgconf but does not provide the alias pkg-config forcing us to uptream the switch to the tool name instead of the standard. Signed-off-by: Pierre Boutillier --- otherlibs/configurator/src/v1.ml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/otherlibs/configurator/src/v1.ml b/otherlibs/configurator/src/v1.ml index 86a2a67e0c2..30abf75660b 100644 --- a/otherlibs/configurator/src/v1.ml +++ b/otherlibs/configurator/src/v1.ml @@ -658,18 +658,21 @@ module Pkg_config = struct } let get c = - let pkg_config_exe_name = - match Sys.getenv "PKG_CONFIG" with - | s -> s - | exception Not_found -> "pkg-config" - in let pkg_config_args = match Sys.getenv "PKG_CONFIG_ARGN" with | s -> String.split ~on:' ' s | exception Not_found -> [] in - Option.map (which c pkg_config_exe_name) ~f:(fun pkg_config -> - { pkg_config; pkg_config_args; configurator = c }) + match Sys.getenv "PKG_CONFIG" with + | s -> + Option.map (which c s) ~f:(fun pkg_config -> + { pkg_config; pkg_config_args; configurator = c }) + | exception Not_found -> + (match which c "pkgconf" with + | None -> + Option.map (which c "pkg-config") ~f:(fun pkg_config -> + { pkg_config; pkg_config_args; configurator = c }) + | Some pkg_config -> Some { pkg_config; pkg_config_args; configurator = c }) ;; type package_conf = From 22d2e2603844bf6e42091327cab4a9e26d053f34 Mon Sep 17 00:00:00 2001 From: Pierre Boutillier Date: Wed, 18 Sep 2024 15:41:51 +0200 Subject: [PATCH 3/5] Configurator tests: toy pkg-config cleaned and renamed into pkgconf Signed-off-by: Pierre Boutillier --- .../blackbox-tests/pkg-config-args.t/dune | 8 +++---- .../{pkg_config.ml => pkgconf.ml} | 2 +- .../blackbox-tests/pkg-config-args.t/run.t | 22 ++++++++++--------- .../pkg-config-quoting.t/pkg_config.ml | 2 +- 4 files changed, 18 insertions(+), 16 deletions(-) rename otherlibs/configurator/test/blackbox-tests/pkg-config-args.t/{pkg_config.ml => pkgconf.ml} (89%) diff --git a/otherlibs/configurator/test/blackbox-tests/pkg-config-args.t/dune b/otherlibs/configurator/test/blackbox-tests/pkg-config-args.t/dune index 1c2cf5745f2..ea5b35b8fd7 100644 --- a/otherlibs/configurator/test/blackbox-tests/pkg-config-args.t/dune +++ b/otherlibs/configurator/test/blackbox-tests/pkg-config-args.t/dune @@ -1,11 +1,11 @@ (executable - (name pkg_config) - (modules pkg_config)) + (name pkgconf) + (modules pkgconf)) (env (_ (binaries - (./pkg_config.exe as pkg-config)))) + (./pkgconf.exe as pkgconf)))) (executable (name config_test) @@ -14,6 +14,6 @@ (rule (alias default) - (deps %{bin:pkg-config}) + (deps %{bin:pkgconf}) (action (run ./config_test.exe -verbose))) diff --git a/otherlibs/configurator/test/blackbox-tests/pkg-config-args.t/pkg_config.ml b/otherlibs/configurator/test/blackbox-tests/pkg-config-args.t/pkgconf.ml similarity index 89% rename from otherlibs/configurator/test/blackbox-tests/pkg-config-args.t/pkg_config.ml rename to otherlibs/configurator/test/blackbox-tests/pkg-config-args.t/pkgconf.ml index 3ed607cf1d7..1d2834644dc 100644 --- a/otherlibs/configurator/test/blackbox-tests/pkg-config-args.t/pkg_config.ml +++ b/otherlibs/configurator/test/blackbox-tests/pkg-config-args.t/pkgconf.ml @@ -4,5 +4,5 @@ let not_flag x = not ("--print-errors" = x) let () = let args = List.tl (Array.to_list Sys.argv) in let args = List.filter not_flag args in - Format.printf "%a@." + Format.printf "@[%a@]@." (Format.pp_print_list Format.pp_print_string) args diff --git a/otherlibs/configurator/test/blackbox-tests/pkg-config-args.t/run.t b/otherlibs/configurator/test/blackbox-tests/pkg-config-args.t/run.t index 2a821a9c85a..e4b74355985 100644 --- a/otherlibs/configurator/test/blackbox-tests/pkg-config-args.t/run.t +++ b/otherlibs/configurator/test/blackbox-tests/pkg-config-args.t/run.t @@ -1,34 +1,36 @@ These tests show that setting `PKG_CONFIG_ARGN` passes extra args to `pkg-config` - $ dune build 2>&1 | awk '/run:.*bin\/pkg-config/{a=1}/stderr/{a=0}a' - run: $TESTCASE_ROOT/_build/default/.bin/pkg-config --print-errors dummy-pkg + $ dune build 2>&1 | awk '/run:.*bin\/pkgconf/{a=1}/stderr/{a=0}a' + run: $TESTCASE_ROOT/_build/default/.bin/pkgconf --print-errors dummy-pkg -> process exited with code 0 -> stdout: | dummy-pkg - run: $TESTCASE_ROOT/_build/default/.bin/pkg-config --cflags dummy-pkg + run: $TESTCASE_ROOT/_build/default/.bin/pkgconf --cflags dummy-pkg -> process exited with code 0 -> stdout: | --cflags | dummy-pkg - run: $TESTCASE_ROOT/_build/default/.bin/pkg-config --libs dummy-pkg + run: $TESTCASE_ROOT/_build/default/.bin/pkgconf --libs dummy-pkg -> process exited with code 0 -> stdout: | --libs | dummy-pkg $ dune clean - $ PKG_CONFIG_ARGN="--static" dune build 2>&1 | awk '/run:.*bin\/pkg-config/{a=1}/stderr/{a=0}a' - run: $TESTCASE_ROOT/_build/default/.bin/pkg-config --print-errors dummy-pkg + $ PKG_CONFIG_ARGN="--static" dune build 2>&1 | awk '/run:.*bin\/pkgconf/{a=1}/stderr/{a=0}a' + run: $TESTCASE_ROOT/_build/default/.bin/pkgconf --print-errors dummy-pkg -> process exited with code 0 -> stdout: | dummy-pkg - run: $TESTCASE_ROOT/_build/default/.bin/pkg-config --static --cflags dummy-pkg + run: $TESTCASE_ROOT/_build/default/.bin/pkgconf --static --cflags dummy-pkg -> process exited with code 0 -> stdout: - | --static--cflags + | --static + | --cflags | dummy-pkg - run: $TESTCASE_ROOT/_build/default/.bin/pkg-config --static --libs dummy-pkg + run: $TESTCASE_ROOT/_build/default/.bin/pkgconf --static --libs dummy-pkg -> process exited with code 0 -> stdout: - | --static--libs + | --static + | --libs | dummy-pkg diff --git a/otherlibs/configurator/test/blackbox-tests/pkg-config-quoting.t/pkg_config.ml b/otherlibs/configurator/test/blackbox-tests/pkg-config-quoting.t/pkg_config.ml index 3ed607cf1d7..1d2834644dc 100644 --- a/otherlibs/configurator/test/blackbox-tests/pkg-config-quoting.t/pkg_config.ml +++ b/otherlibs/configurator/test/blackbox-tests/pkg-config-quoting.t/pkg_config.ml @@ -4,5 +4,5 @@ let not_flag x = not ("--print-errors" = x) let () = let args = List.tl (Array.to_list Sys.argv) in let args = List.filter not_flag args in - Format.printf "%a@." + Format.printf "@[%a@]@." (Format.pp_print_list Format.pp_print_string) args From 4c1135e4043be7443cf9e8734b9f11d21c7f8a1c Mon Sep 17 00:00:00 2001 From: Pierre Boutillier Date: Wed, 18 Sep 2024 12:10:15 +0200 Subject: [PATCH 4/5] Configurator: add by default --personality=@target@ to pkgconf calls Specifying a personality is only useful when cross-compiling (which you do when you use mingw on Windows) but (nearly) never harmful as pkgconf installs a default.personality which it uses for all triplets (that parses therefore the nearly) it hasn't a explicit personality for. Signed-off-by: Pierre Boutillier --- otherlibs/configurator/src/v1.ml | 15 ++++++++++++--- .../test/blackbox-tests/pkg-config-args.t/run.t | 10 +++++++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/otherlibs/configurator/src/v1.ml b/otherlibs/configurator/src/v1.ml index 30abf75660b..ddd8446fb14 100644 --- a/otherlibs/configurator/src/v1.ml +++ b/otherlibs/configurator/src/v1.ml @@ -658,21 +658,30 @@ module Pkg_config = struct } let get c = - let pkg_config_args = + let get_pkg_config_args default = match Sys.getenv "PKG_CONFIG_ARGN" with | s -> String.split ~on:' ' s - | exception Not_found -> [] + | exception Not_found -> default in match Sys.getenv "PKG_CONFIG" with | s -> Option.map (which c s) ~f:(fun pkg_config -> + let pkg_config_args = get_pkg_config_args [] in { pkg_config; pkg_config_args; configurator = c }) | exception Not_found -> (match which c "pkgconf" with | None -> Option.map (which c "pkg-config") ~f:(fun pkg_config -> + let pkg_config_args = get_pkg_config_args [] in { pkg_config; pkg_config_args; configurator = c }) - | Some pkg_config -> Some { pkg_config; pkg_config_args; configurator = c }) + | Some pkg_config -> + let pkg_config_args = + get_pkg_config_args + (match ocaml_config_var c "target" with + | None -> [] + | Some target -> [ "--personality"; target ]) + in + Some { pkg_config; pkg_config_args; configurator = c }) ;; type package_conf = diff --git a/otherlibs/configurator/test/blackbox-tests/pkg-config-args.t/run.t b/otherlibs/configurator/test/blackbox-tests/pkg-config-args.t/run.t index e4b74355985..e468970b0d4 100644 --- a/otherlibs/configurator/test/blackbox-tests/pkg-config-args.t/run.t +++ b/otherlibs/configurator/test/blackbox-tests/pkg-config-args.t/run.t @@ -1,18 +1,22 @@ These tests show that setting `PKG_CONFIG_ARGN` passes extra args to `pkg-config` - $ dune build 2>&1 | awk '/run:.*bin\/pkgconf/{a=1}/stderr/{a=0}a' + $ dune build 2>&1 | awk '/run:.*bin\/pkgconf/{a=1}/stderr/{a=0}a' | sed s/$(ocamlc -config | sed -n "/^target:/ {s/target: //; p; }")/\$TARGET/g run: $TESTCASE_ROOT/_build/default/.bin/pkgconf --print-errors dummy-pkg -> process exited with code 0 -> stdout: | dummy-pkg - run: $TESTCASE_ROOT/_build/default/.bin/pkgconf --cflags dummy-pkg + run: $TESTCASE_ROOT/_build/default/.bin/pkgconf --personality $TARGET --cflags dummy-pkg -> process exited with code 0 -> stdout: + | --personality + | $TARGET | --cflags | dummy-pkg - run: $TESTCASE_ROOT/_build/default/.bin/pkgconf --libs dummy-pkg + run: $TESTCASE_ROOT/_build/default/.bin/pkgconf --personality $TARGET --libs dummy-pkg -> process exited with code 0 -> stdout: + | --personality + | $TARGET | --libs | dummy-pkg From 32a403d15bbc54f9a52e13979cee144396724712 Mon Sep 17 00:00:00 2001 From: Pierre Boutillier Date: Fri, 18 Oct 2024 12:37:24 +0200 Subject: [PATCH 5/5] Configurator: document new pkg-config plugin behaviors Signed-off-by: Pierre Boutillier --- doc/changes/10937.md | 2 ++ otherlibs/configurator/src/v1.mli | 21 ++++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 doc/changes/10937.md diff --git a/doc/changes/10937.md b/doc/changes/10937.md new file mode 100644 index 00000000000..d98de0868ed --- /dev/null +++ b/doc/changes/10937.md @@ -0,0 +1,2 @@ +- Configurator uses `pkgconf` as pkg-config implementation when available + and forwards it the `target` of `ocamlc -config`. (#10937, @pirbo) diff --git a/otherlibs/configurator/src/v1.mli b/otherlibs/configurator/src/v1.mli index 4c3329e3bc5..f9fc83aa83e 100644 --- a/otherlibs/configurator/src/v1.mli +++ b/otherlibs/configurator/src/v1.mli @@ -73,8 +73,11 @@ module Pkg_config : sig type configurator = t type t - (** Search pkg-config in PATH. Prefers the [PKG_CONFIG_PATH] environment - variable if set. Returns [None] if pkg-config is not found. *) + (** Search a pkg-config implementation in PATH. Use the one + defined in [PKG_CONFIG] environment variable if set else try + [pkgconf] then [pkg-config]. Append the [PKG_CONFIG_PATH] + environment variable to the searched pathes. Returns [None] if + nothing is not found. *) val get : configurator -> t option type package_conf = @@ -84,9 +87,11 @@ module Pkg_config : sig (** [query t ~package] query pkg-config for the [package]. The package must not contain a version constraint. Multiple, unversioned packages are - separated with spaces, for example "gtk+-3.0 gtksourceview-3.0". If set, - the [PKG_CONFIG_ARGN] environment variable specifies a list of arguments - to pass to pkg-config. Returns [None] if [package] is not available *) + separated with spaces, for example "gtk+-3.0 gtksourceview-3.0". By + default, the OCaml compiler [target] is passed to pkgconf as + [--personality] argument. An alternative list of arguments can be + specified by setting the [PKG_CONFIG_ARGN] environment variable. + Returns [None] if [package] is not available *) val query : t -> package:string -> package_conf option val query_expr : t -> package:string -> expr:string -> package_conf option @@ -95,8 +100,10 @@ module Pkg_config : sig (** [query_expr_err t ~package ~expr] query pkg-config for the [package]. [expr] may contain a version constraint, for example "gtk+-3.0 >= 3.18". [package] must be just the name of the package. If [expr] is specified, - [package] must be specified as well. If set, the [PKG_CONFIG_ARGN] - environment variable specifies a list of arguments to pass to pkg-config. + [package] must be specified as well. By default, the OCaml compiler + "target" is passed to pkgconf as [--personality] argument. An + alternative list of arguments can be specified by setting the + [PKG_CONFIG_ARGN] environment variable. Returns [Error error_msg] if [package] is not available *) val query_expr_err : t