Hello community,
here is the log from the commit of package ocaml-rpm-macros for
openSUSE:Factory checked in at 2020-02-26 15:01:43
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ocaml-rpm-macros (Old)
and /work/SRC/openSUSE:Factory/.ocaml-rpm-macros.new.26092 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ocaml-rpm-macros"
Wed Feb 26 15:01:43 2020 rev:5 rq:778683 version:20200220
Changes:
--------
--- /work/SRC/openSUSE:Factory/ocaml-rpm-macros/ocaml-rpm-macros.changes
2019-11-30 10:35:44.916183957 +0100
+++
/work/SRC/openSUSE:Factory/.ocaml-rpm-macros.new.26092/ocaml-rpm-macros.changes
2020-02-26 15:01:44.784796126 +0100
@@ -1,0 +2,17 @@
+Thu Feb 20 20:20:20 UTC 2020 - [email protected]
+
+- Add ocaml-ocaml.rpm.prov_req.attr.sh
+ New script for rpm Provides/Requires, replacement for rpm
+ built-in ocaml(NAME)=hash, which covers bytecode and interfaces
+ Now it covers also native code via ocamlx(NAME)=HASH (bsc#1154874)
+- Update the filelist generator
+ Use awk to match directories in ocamls built-in ld.conf
+ C stublibs in default locations do not need a ld.so.conf entry
+ Remaining ld.so.conf files for stublibs go to the devel package
+- Disable debug in ocamlfind() Provides/Requires generator
+ Update META parser to handle multiline statements and ppx
+- Provide a ocaml_standard_library macro
+- Explicitly preserve debuginfo in .cmxs, already enforced by dune
+- Install also COPYRIGHT.txt as license, needed for some JaneStreet pkgs
+
+-------------------------------------------------------------------
New:
----
ocaml-ocaml.rpm.prov_req.attr.sh
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ ocaml-rpm-macros.spec ++++++
--- /var/tmp/diff_new_pack.MhIsiE/_old 2020-02-26 15:01:45.300797156 +0100
+++ /var/tmp/diff_new_pack.MhIsiE/_new 2020-02-26 15:01:45.300797156 +0100
@@ -16,14 +16,16 @@
#
Name: ocaml-rpm-macros
-Version: 20191101
+Version: 20200220
Release: 0
Summary: RPM macros for building OCaml source packages
License: GPL-2.0-only
Group: Development/Languages/OCaml
Url: https://build.opensuse.org/project/show/devel:languages:ocaml
+Source0: ocaml-ocaml.rpm.prov_req.attr.sh
Source1: ocaml-findlib.rpm.prov_req.attr.sh
+%define ocaml_standard_library %{_libdir}/ocaml
%define do_opt 0
# macros to be set in prjconf:
#Macros:
@@ -60,13 +62,25 @@
%build
%install
+# map ocamlobjinfo output to rpm Provides/Requires
+tag="ocaml"
+mkdir -vp %{buildroot}%{_rpmconfigdir}/fileattrs
+tee %{buildroot}%{_rpmconfigdir}/fileattrs/z${tag}.attr <<_EOF_
+%__${tag}_provides %%{_rpmconfigdir}/${tag}.sh --provides
+%__${tag}_requires %%{_rpmconfigdir}/${tag}.sh --requires
+%__${tag}_magic ^(ELF|Objective caml|OCaml) .*$
+%__${tag}_path .(cma|cmi|cmo|cmx|cmxa|cmxs)$
+_EOF_
+#
+tee %{buildroot}%{_rpmconfigdir}/${tag}.sh < %{SOURCE0}
+
# map findlib names to rpm Provides/Requires
tag="ocamlfind"
mkdir -vp %{buildroot}%{_rpmconfigdir}/fileattrs
tee %{buildroot}%{_rpmconfigdir}/fileattrs/${tag}.attr <<_EOF_
%__${tag}_provides %%{_rpmconfigdir}/${tag}.sh -prov
%__${tag}_requires %%{_rpmconfigdir}/${tag}.sh -req
-%__${tag}_path ^%%{_libdir}/ocaml/.*/META$|^%%{_libdir}/ocaml/META$
+%__${tag}_path
^%{ocaml_standard_library}/.*/META$|^%{ocaml_standard_library}/META$
_EOF_
#
tee %{buildroot}%{_rpmconfigdir}/${tag}.sh < %{SOURCE1}
@@ -74,12 +88,23 @@
# install OCaml macros
mkdir -vp %{buildroot}%{_rpmmacrodir}
tee %{buildroot}%{_rpmmacrodir}/macros.%{name} <<'_EOF_'
+# Guidelines:
+# - Providing applications written in OCaml is the main goal of our packaging.
+# - Applications written in OCaml are static binaries.
+# - A concept of shared libraries does not exist, beside the Dynlink module
+# - All binaries go into the main package, in case they are produced.
+# - All modules go into the -devel subpackage
+# - Helper applications below %{ocaml_standard_library} go into the -devel
subpackage
+# - License files go into the main package.
+# - To aid debugging of cmxs files, their debuginfo is preserved by removing
the executable bit.
+#
# get rid of %{_rpmconfigdir}/find-debuginfo.sh
# strip kills the bytecode part of ELF binaries
#
# provide empty _find_debuginfo_dwz_opts
# the .dwz files contains identical contents, which leads to identical
# checksums, which leads to file conflicts due to identical symlinks
+%%ocaml_standard_library %{ocaml_standard_library}
%if %{do_opt}
%%ocaml_preserve_bytecode \
%%define _lto_cflags %%{nil} \
@@ -108,12 +133,13 @@
COPYING \\\
COPYING.txt \\\
COPYRIGHT \\\
+ COPYRIGHT.txt \\\
Copyright \\\
+ LGPL \\\
LICENCE \\\
LICENSE \\\
LICENSE.md \\\
LICENSE.txt \\\
- LGPL \\\
;\
do\
%if 0%{?suse_version} > 1315
@@ -123,103 +149,178 @@
%endif
test -f "${license}" && echo "%%%%${license_macro} ${license}" >>
'%%{name}.files.license' ;\
done ;\
- find %%{buildroot}$(ocamlc -where) | sed -ne '\
- s@^%%{buildroot}@@\
- #\
+ find %%{buildroot}%%{ocaml_standard_library} -name '*.cmxs' -exec chmod
-v a-x '{}' +\
+ find %%{buildroot}%%{ocaml_standard_library} ! -type d | awk\\\
+ -v "buildroot=%%{buildroot}"\\\
+ -v "ocaml_standard_library=%%{ocaml_standard_library}"\\\
+ -v "out_files_devel=%%{name}.files.devel"\\\
+ -v "out_files_ldconf=%%{name}.files.ldsoconf"\\\
+ -v "out_files_unhandled=%%{name}.files.unhandled"\\\
+ -v "ocaml_ldconf=$(ls -1d %%{ocaml_standard_library}/ld.conf ||
: ld.conf not found)"\\\
+ '\
+ BEGIN {\
+ nr=0\
+ if (ocaml_ldconf != "") {\
+ do {\
+ r = getline < ocaml_ldconf\
+ if (r > 0) {\
+ ldconf[nr++]=$0\
+ }\
+ } while (r > 0)\
+ }\
+ }\
+ function _split (line) {\
+ file_path=substr(line, length(buildroot) + 1)\
+ m=match(file_path, "/[^/]+$")\
+ dirname=substr(file_path, 0, m - 1)\
+ basename=substr(file_path, m + 1)\
+ if (dirname == ocaml_standard_library) {\
+ # do not package above standard_library\
+ parent_dir=""\
+ } else {\
+ m=match(dirname, "/[^/]+$")\
+ parent_dir=substr(dirname, 0, m - 1)\
+ }\
+ }\
+ function files_ldconf(line) {\
+ _split(line)\
+ print file_path >> out_files_devel\
+ print "%%dir " dirname >> out_files_devel\
+ for (ldconf_dir in ldconf) {\
+ if (dirname == ldconf[ldconf_dir]) {\
+ # done with this cycle, ocaml ld.conf covers it\
+ next\
+ }\
+ }\
+ print dirname >> out_files_ldconf\
+ next\
+ }\
+ function files_devel(line) {\
+ _split(line)\
+ print file_path >> out_files_devel\
+ print "%%dir " dirname >> out_files_devel\
+ if (parent_dir != "") {\
+ print "%%dir " parent_dir >> out_files_devel\
+ }\
+ next\
+ }\
+ function files_unhandled(line) {\
+ _split(line)\
+ print file_path >> out_files_unhandled\
+ next\
+ }\
# for findlib, describing a package\
- /\\/META$/{ b files_devel }\
+ /\\/META$/{\
+ files_devel($0)\
+ }\
# stub ELF library\
- /\\/[^/]\\+\\.so$/{ b files_ldsoconf }\
+ /\\/[^/]+\.so$/{\
+ files_ldconf($0)\
+ }\
# stub ELF library\
- /\\/[^/]\\+\\.so.owner$/{ b files_ldsoconf }\
+ /\\/[^/]+\.so.owner$/{\
+ files_ldconf($0)\
+ }\
# ELF archive with object files\
- /\\/[^/]\\+\\.a$/{ b files_devel }\
+ /\\/[^/]+\.a$/{\
+ files_devel($0)\
+ }\
# OCaml legacy source code annotations, produced via -annot\
- /\\/[^/]\\+\\.annot$/{ b files_devel }\
+ /\\/[^/]+\.annot$/{\
+ files_devel($0)\
+ }\
# OCaml library file with bytecode\
- /\\/[^/]\\+\\.cma$/{ b files_devel }\
+ /\\/[^/]+\.cma$/{\
+ files_devel($0)\
+ }\
# OCaml compiled header file\
- /\\/[^/]\\+\\.cmi$/{ b files_devel }\
+ /\\/[^/]+\.cmi$/{\
+ files_devel($0)\
+ }\
# OCaml object file with bytecode\
- /\\/[^/]\\+\\.cmo$/{ b files_devel }\
+ /\\/[^/]+\.cmo$/{\
+ files_devel($0)\
+ }\
# OCaml source code annotations, produced via -bin-annot from source
files\
- /\\/[^/]\\+\\.cmt$/{ b files_devel }\
+ /\\/[^/]+\.cmt$/{\
+ files_devel($0)\
+ }\
# OCaml source code annotations, produced via -bin-annot from header
files\
- /\\/[^/]\\+\\.cmti$/{ b files_devel }\
+ /\\/[^/]+\.cmti$/{\
+ files_devel($0)\
+ }\
# OCaml object file with native code\
- /\\/[^/]\\+\\.cmx$/{ b files_devel }\
+ /\\/[^/]+\.cmx$/{\
+ files_devel($0)\
+ }\
# OCaml library file with native code\
- /\\/[^/]\\+\\.cmxa$/{ b files_devel }\
+ /\\/[^/]+\.cmxa$/{\
+ files_devel($0)\
+ }\
# ELF shared library with native code\
- /\\/[^/]\\+\\.cmxs$/{ b files_devel }\
+ /\\/[^/]+\.cmxs$/{\
+ files_devel($0)\
+ }\
# Some helper binary\
- /\\/[^/]\\+\\.exe$/{ b files_devel }\
+ /\\/[^/]+\.exe$/{\
+ files_devel($0)\
+ }\
# C header\
- /\\/[^/]\\+\\.h$/{ b files_devel }\
+ /\\/[^/]+\.h$/{\
+ files_devel($0)\
+ }\
#\
- /\\/[^/]\\+\\.js$/{ b files_devel }\
+ /\\/[^/]+\.js$/{\
+ files_devel($0)\
+ }\
# OCaml source code, source file\
- /\\/[^/]\\+\\.ml$/{ b files_devel }\
+ /\\/[^/]+\.ml$/{\
+ files_devel($0)\
+ }\
# OCaml source code, header file\
- /\\/[^/]\\+\\.mli$/{ b files_devel }\
+ /\\/[^/]+\.mli$/{\
+ files_devel($0)\
+ }\
# ELF object file\
- /\\/[^/]\\+\\.o$/{ b files_devel }\
+ /\\/[^/]+\.o$/{\
+ files_devel($0)\
+ }\
#\
- /\\/[^/]\\+\\.sml$/{ b files_devel }\
- #\
- /\\/dune-package$/{ b files_devel }\
- #\
- /\\/opam$/{ b files_devel }\
+ /\\/[^/]+\.sml$/{\
+ files_devel($0)\
+ }\
+ # generated by dune\
+ /\\/dune-package$/{\
+ files_devel($0)\
+ }\
+ # generated by dune\
+ /\\/opam$/{\
+ files_devel($0)\
+ }\
#\
# record unknown paths\
- w %%{name}.files.unhandled\
- d\
- #\
- : files_devel\
- # full path for file\
- w %%{name}.files.devel\
- # tag + dirname\
- s@\\/[^/]\\+$@@\
- : tag_dirname\
- s@^@%%dir @\
- w %%{name}.files.devel\
- # parent directory\
- s@\\/[^/]\\+$@@\
- w %%{name}.files.devel\
- d\
- #\
- : files_ldsoconf\
- # full path for file\
- w %%{name}.files.devel\
- # dirname for ld.so.conf\
- s@\\/[^/]\\+$@@\
- w %%{name}.files.ldsoconf\
- b tag_dirname\
- ' ;\
- cat '%%{name}.files.license' >> '%%{name}.files' ; \
- for i in \\\
- %%{name}.files \\\
- %%{name}.files.devel \\\
- %%{name}.files.ldsoconf \\\
- %%{name}.files.unhandled \\\
+ files_unhandled($0)\
+ END {\
;\
- do\
- sort -u $i > $$ ;\
- mv $$ $i ;\
- done ;\
+ }' ;\
+ cat '%%{name}.files.license' >> '%%{name}.files' ;\
if test -s %%{name}.files.ldsoconf ;\
- then \
+ then\
ldsoconfd='/etc/ld.so.conf.d' ;\
mkdir -vp "%%{buildroot}${ldsoconfd}" ;\
tee "%%{buildroot}${ldsoconfd}/%%{name}.conf" <
%%{name}.files.ldsoconf ;\
- echo "%config ${ldsoconfd}/%%{name}.conf" >> %%{name}.files ;\
+ echo "%config ${ldsoconfd}/%%{name}.conf" >>
%%{name}.files.devel ;\
fi ;\
- head -n 1234 \\\
+ for i in \\\
%%{name}.files \\\
%%{name}.files.devel \\\
%%{name}.files.ldsoconf \\\
%%{name}.files.unhandled \\\
;\
+ do\
+ sort -u $i > $$ ;\
+ mv $$ $i ;\
+ done ;\
%%{nil}
# setup.ml comes from oasis, but this is here for libs oasis depends on
@@ -277,7 +378,7 @@
%%ocaml_oasis_install \
ocaml setup.ml -install
%%ocaml_oasis_findlib_install \
- export OCAMLFIND_DESTDIR=%%{buildroot}`ocamlc -where` ; \
+ export OCAMLFIND_DESTDIR=%%{buildroot}%%{ocaml_standard_library} ; \
export OCAMLFIND_LDCONF=/dev/null ; \
mkdir -p $OCAMLFIND_DESTDIR ; \
ocaml setup.ml -install
@@ -322,22 +423,22 @@
%ifarch ppc64 ppc64le
ulimit -s $((1024 * 64)) ; \
%endif
- dune_for_release= ; \
+ dune_for_release= ;\
if test -f dune_release_pkgs-%%{name}-%%{version}-%%{release} ; \
then \
read dune_release_pkgs <
dune_release_pkgs-%%{name}-%%{version}-%%{release} ; \
dune_for_release="--for-release-of-packages=${dune_release_pkgs}" ; \
- fi ; \
+ fi ;\
dune install \\\
--verbose \\\
${dune_for_release} \\\
%%{?_smp_mflags} \\\
--prefix=%%{_prefix} \\\
- --libdir=$(ocamlc -where) \\\
+ --libdir=%%{ocaml_standard_library} \\\
--destdir=%%{buildroot} \\\
${dune_release_pkgs//,/ } \\\
- $OCAML_DUNE_INSTALL_ARGS ; \
- rm -rfv %%{buildroot}%%{_prefix}/doc ; \
+ $OCAML_DUNE_INSTALL_ARGS ;\
+ rm -rfv %%{buildroot}%%{_prefix}/doc ;\
if test -d %%{buildroot}%%{_prefix}/man ; then \
mkdir -vp %%{buildroot}%%{_datadir} ; \
mv -vt %%{buildroot}%%{_datadir} %%{buildroot}%%{_prefix}/man ;
\
++++++ ocaml-findlib.rpm.prov_req.attr.sh ++++++
--- /var/tmp/diff_new_pack.MhIsiE/_old 2020-02-26 15:01:45.324797204 +0100
+++ /var/tmp/diff_new_pack.MhIsiE/_new 2020-02-26 15:01:45.324797204 +0100
@@ -33,14 +33,15 @@
cmd="${cmd}" \
awk '
BEGIN {
- dbg=1;
+ dbg=0;
count=1;
depth=0;
pkg_name=ENVIRON["pkg_name"];
cmd=ENVIRON["cmd"];
if(dbg) printf "bEGIN \\"%s\\" cmd: %s\n", pkg_name, cmd >
"/dev/stderr" ;
- reqs[pkg_name]=""
+ requires[pkg_name]=""
+ ppx_runtime_deps[pkg_name]=""
pkg_names[depth]=pkg_name
}
@@ -73,8 +74,8 @@
}
if(dbg) printf "dir: %s %s\n", x, candidate > "/dev/stderr" ;
if (candidate != pkg_name) {
- reqs[candidate] = reqs[pkg_name];
- delete reqs[pkg_name];
+ requires[candidate] = requires[pkg_name];
+ delete requires[pkg_name];
pkg_name = candidate;
if(dbg) printf "new pkg_name %s %s\n", x, pkg_name >
"/dev/stderr" ;
pkg_names[depth]=pkg_name
@@ -86,14 +87,76 @@
next
}
- /^[[:blank:]]*requires.*[[:blank:]]*=/ {
+ /^[[:blank:]]*requires(|\([^)]+\))[[:blank:]]*(+=|=)/ {
if(dbg) printf "GOT: %s\n", $0 > "/dev/stderr" ;
- x = split($0, a, "\\"");
+ done=0
+ requires_line = ""
+ do {
+ need_next_line = 1
+ line = $0
+ requires_line = sprintf("%s%s", requires_line, line)
+ l = length(requires_line)
+ qm = index(requires_line, "\\"")
+ if (l > qm) {
+ line = substr(requires_line, qm + 1)
+ qm = index(line, "\\"")
+ need_next_line = qm == 0
+ }
+
+ if (need_next_line) {
+ done = getline == 0
+ } else {
+ done = 1
+ }
+ } while (done == 0)
+
+ x = split(requires_line, a, "\\"");
if ( a[2] ) {
if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ;
x = gsub("[[:blank:]]+", ",", a[2]);
if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ;
- reqs[pkg_name] = a[2];
+ if (requires[pkg_name] == "") {
+ requires[pkg_name] = a[2]
+ } else {
+ requires[pkg_name] = sprintf("%s,%s", requires[pkg_name],a[2])
+ }
+ }
+ next
+ }
+
+ /^[[:blank:]]*ppx_runtime_deps[[:blank:]]*(+=|=)/ {
+ if(dbg) printf "GOT: %s\n", $0 > "/dev/stderr" ;
+ done=0
+ ppx_runtime_deps_line = ""
+ do {
+ need_next_line = 1
+ line = $0
+ ppx_runtime_deps_line = sprintf("%s%s", ppx_runtime_deps_line, line)
+ l = length(ppx_runtime_deps_line)
+ qm = index(ppx_runtime_deps_line, "\\"")
+ if (l > qm) {
+ line = substr(ppx_runtime_deps_line, qm + 1)
+ qm = index(line, "\\"")
+ need_next_line = qm == 0
+ }
+
+ if (need_next_line) {
+ done = getline == 0
+ } else {
+ done = 1
+ }
+ } while (done == 0)
+
+ x = split(ppx_runtime_deps_line, a, "\\"");
+ if ( a[2] ) {
+ if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ;
+ x = gsub("[[:blank:]]+", ",", a[2]);
+ if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ;
+ if (ppx_runtime_deps[pkg_name] == "") {
+ ppx_runtime_deps[pkg_name] = a[2]
+ } else {
+ requires[pkg_name] = sprintf("%s,%s", requires[pkg_name],a[2])
+ }
}
next
}
@@ -106,7 +169,7 @@
if ( a[2] ) {
if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ;
pkg_name = pkg_name"."a[2];
- reqs[pkg_name]=""
+ requires[pkg_name]=""
pkg_names[depth]=pkg_name
if(dbg) printf "new pkg_name %s %s\n", x, pkg_name > "/dev/stderr" ;
}
@@ -124,10 +187,15 @@
END {
if(dbg) printf "eND \\"%s\\"\n", pkg_name > "/dev/stderr" ;
- for (req in reqs) {
+ for (req in requires) {
+ if(dbg)printf "eNd \\"%s\\"\n", req > "/dev/stderr";
+ # format: provides:requires
+ printf "%s:%s\n", req, requires[req];
+ }
+ for (req in ppx_runtime_deps) {
if(dbg)printf "eNd \\"%s\\"\n", req > "/dev/stderr";
# format: provides:requires
- printf "%s:%s\n", req, reqs[req];
+ printf "%s:%s\n", req, ppx_runtime_deps[req];
}
if(dbg) printf "ENd \\"%s\\"\n", pkg_name > "/dev/stderr" ;
}
@@ -158,3 +226,4 @@
*) ;;
esac
done
+# vim: tw=666 ts=2 shiftwidth=2 et
++++++ ocaml-ocaml.rpm.prov_req.attr.sh ++++++
#!/bin/bash
# This is a helper for rpm which collects 'Provides' and 'Requires' information
from OCaml files.
# It reads a list of filenames from STDIN.
# It expects as argument either '--provides|-P' or '--requires|-R'.
# Additional optional arguments are:
# -f "ocamlobjinfo command"
# -c # ignored, recognized just for compat reasons
# -i NAME # omit the Requires/Provides for this bytecode unit name
# -x NAME # omit the Requires/Provides for this native unit name
#
# OCaml object files contain either bytecode or native code.
# Each bytecode variant provides a certain interface, which is represented by a
hash.
# Each native variant provides a certain interface and a certain
implementation, which are represented by hashes.
# Each variant may also require a certain interface and/or implementation
provided by other files.
# The details for each file can be inspected with 'ocamlobjinfo'.
#
# Each file contains at least one module.
# Information about each module follows after a line starting with "Name:" or
"Unit name:":
#
# cma/cmi/cmo (bytecode):
# Unit name: NAME
# Interfaces imported:
# HASH NAME
# HASH NAME_FROM_OTHER_MODULE
#
# cmx/cmxa/cmxs (native):
# Name: NAME
# CRC of implementation: HASH
# Interfaces imported:
# HASH NAME
# HASH NAME_FROM_OTHER_MODULE
# Implementations imported:
# HASH NAME_FROM_OTHER_MODULE
#
# The hash may contain just '-', in which case it is ignored.
#
# Output:
# ocaml(NAME) = HASH # for interfaces (bytecode and native)
# ocamlx(NAME) = HASH # for implementations (native)
set -e
#
OCAMLOBJINFO=ocamlobjinfo
rpm_prefix_interface='ocaml'
rpm_prefix_implementation='ocamlx'
#
parse() {
local filename="$1"
${OCAMLOBJINFO} "${filename}" | awk '
BEGIN {
debug=0
mode=ENVIRON["mode"]
RPM_BUILD_ROOT=ENVIRON["RPM_BUILD_ROOT"]
rpm_prefix_interface=ENVIRON["rpm_prefix_interface"]
rpm_prefix_implementation=ENVIRON["rpm_prefix_implementation"]
state="find"
unit=""
split(ENVIRON["ignore_implementation"], ignore_implementation_a)
for (i in ignore_implementation_a) {
val=ignore_implementation_a[i]
if (debug)
printf "INFO: ignore_implementation %s\n", val > "/dev/stderr"
ignore_implementation[val]=1
}
split(ENVIRON["ignore_interface"], ignore_interface_a)
for (i in ignore_interface_a) {
val=ignore_interface_a[i]
if (debug)
printf "INFO: ignore_interface %s\n", val > "/dev/stderr"
ignore_interface[val]=1
}
}
/^File / {
if (RPM_BUILD_ROOT != "" ) {
file=substr($2,length(RPM_BUILD_ROOT)+1)
} else {
file=$2
}
state="file"
next
}
/^Unit name:/ {
unit=$3
state="cma"
next
}
/^Name:/ {
unit=$2
state="cmx"
next
}
/^CRC of implementation:/ {
if (state == "cmx") {
if (ignore_implementation[unit] != "") {
if (ignore_implementation[unit] != "seen") {
printf "INFO: ignoring Provides %s(%s)=%s from %s\n",
rpm_prefix_implementation, unit, $4, file > "/dev/stderr"
ignore_implementation[unit]="seen"
}
} else {
implementation_provides[unit]=$4
}
} else {
printf "WARN: state %s, expected cmx, got %s\n", state, $0 > "/dev/stderr"
}
state="crc"
next
}
/^Interfaces imported:/ {
state="interface"
next
}
/^Implementations imported:/ {
state="implementation"
next
}
/^\t/ {
if (state == "interface" && NF > 1 && match($1, "^-") == 0) {
if (unit == $2) {
if (ignore_interface[unit] != "") {
if (ignore_interface[unit] != "seen") {
printf "INFO: ignoring Provides %s(%s)=%s from %s\n",
rpm_prefix_interface, unit, $1, file > "/dev/stderr"
ignore_interface[unit]="seen"
}
} else {
interface_provides[unit]=$1
}
} else {
if (ignore_interface[$2] != "") {
if (ignore_interface[$2] != "seen") {
printf "INFO: ignoring Requires %s(%s)=%s from %s\n",
rpm_prefix_interface, $2, $1, file > "/dev/stderr"
ignore_interface[$2]="seen"
}
} else {
interface_requires[$2]=$1
}
}
next
} else if (state == "implementation" && NF > 1 && match($1, "^-") == 0) {
if (unit == $2) {
if (ignore_implementation[unit] != "") {
if (ignore_implementation[unit] != "seen") {
printf "INFO: ignoring Provides %s(%s)=%s from %s\n",
rpm_prefix_implementation, unit, $1, file > "/dev/stderr"
ignore_implementation[unit]="seen"
}
} else {
implementation_provides[unit]=$1
}
} else {
if (ignore_implementation[$2] != "") {
if (ignore_implementation[$2] != "seen") {
printf "INFO: ignoring Requires %s(%s)=%s from %s\n",
rpm_prefix_implementation, $2, $1, file > "/dev/stderr"
ignore_implementation[$2]="seen"
}
} else {
implementation_requires[$2]=$1
}
}
next
} else {
next
}
}
/^.*/ {
state="find"
}
END {
if (mode == "provides") {
for (i in interface_provides) {
printf "%s(%s) = %s\n", rpm_prefix_interface, i, interface_provides[i]
}
for (i in implementation_provides) {
printf "%s(%s) = %s\n", rpm_prefix_implementation, i,
implementation_provides[i]
}
}
if (mode == "requires") {
for (i in interface_requires) {
printf "%s(%s) = %s\n", rpm_prefix_interface, i, interface_requires[i]
}
for (i in implementation_requires) {
printf "%s(%s) = %s\n", rpm_prefix_implementation, i,
implementation_requires[i]
}
}
}
'
}
#
#
usage() {
echo >&2 "Usage: ${0##*/} -provides|-requires [-f 'ocamlobjinfo cmd']"
}
#
mode=
ignore_implementation_a=()
ignore_interface_a=()
while test "$#" -gt 0
do
: "${1}" "${2}"
case "${1}" in
-P|--provides) mode='provides' ;;
-R|--requires) mode='requires' ;;
-i) ignore_interface_a+=("$2") ; shift ;;
-x) ignore_implementation_a+=("$2") ; shift ;;
-f) OCAMLOBJINFO="$2"; shift ;;
-h|--help) usage ; exit 0 ;;
-c) ;; # ignored
--) break ;;
*) usage ; exit 1 ;;
esac
shift
done
if test -z "${mode}"
then
usage
exit 1
fi
#
export rpm_prefix_interface
export rpm_prefix_implementation
export mode
export ignore_implementation="${ignore_implementation_a[@]}"
export ignore_interface="${ignore_interface_a[@]}"
#
while read filename
do
case "${filename}" in
*.cma) parse "${filename}" ;;
*.cmi) parse "${filename}" ;;
*.cmo) parse "${filename}" ;;
*.cmx) parse "${filename}" ;;
*.cmxa) parse "${filename}" ;;
*.cmxs) parse "${filename}" ;;
*) continue ;;
esac
done
# vim: tw=666 ts=2 shiftwidth=2 et