Accepting request 778683 from devel:languages:ocaml

- 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

OBS-URL: https://build.opensuse.org/request/show/778683
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/ocaml-rpm-macros?expand=0&rev=5
This commit is contained in:
Dominique Leuenberger 2020-02-26 14:01:43 +00:00 committed by Git OBS Bridge
commit f88bd505cc
4 changed files with 514 additions and 84 deletions

View File

@ -33,14 +33,15 @@ do_work() {
cmd="${cmd}" \ cmd="${cmd}" \
awk ' awk '
BEGIN { BEGIN {
dbg=1; dbg=0;
count=1; count=1;
depth=0; depth=0;
pkg_name=ENVIRON["pkg_name"]; pkg_name=ENVIRON["pkg_name"];
cmd=ENVIRON["cmd"]; cmd=ENVIRON["cmd"];
if(dbg) printf "bEGIN \\"%s\\" cmd: %s\n", pkg_name, cmd > "/dev/stderr" ; 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 pkg_names[depth]=pkg_name
} }
@ -73,8 +74,8 @@ do_work() {
} }
if(dbg) printf "dir: %s %s\n", x, candidate > "/dev/stderr" ; if(dbg) printf "dir: %s %s\n", x, candidate > "/dev/stderr" ;
if (candidate != pkg_name) { if (candidate != pkg_name) {
reqs[candidate] = reqs[pkg_name]; requires[candidate] = requires[pkg_name];
delete reqs[pkg_name]; delete requires[pkg_name];
pkg_name = candidate; pkg_name = candidate;
if(dbg) printf "new pkg_name %s %s\n", x, pkg_name > "/dev/stderr" ; if(dbg) printf "new pkg_name %s %s\n", x, pkg_name > "/dev/stderr" ;
pkg_names[depth]=pkg_name pkg_names[depth]=pkg_name
@ -86,14 +87,76 @@ do_work() {
next next
} }
/^[[:blank:]]*requires.*[[:blank:]]*=/ { /^[[:blank:]]*requires(|\([^)]+\))[[:blank:]]*(+=|=)/ {
if(dbg) printf "GOT: %s\n", $0 > "/dev/stderr" ; 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 ( a[2] ) {
if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ; if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ;
x = gsub("[[:blank:]]+", ",", a[2]); x = gsub("[[:blank:]]+", ",", a[2]);
if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ; 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 next
} }
@ -106,7 +169,7 @@ do_work() {
if ( a[2] ) { if ( a[2] ) {
if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ; if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ;
pkg_name = pkg_name"."a[2]; pkg_name = pkg_name"."a[2];
reqs[pkg_name]="" requires[pkg_name]=""
pkg_names[depth]=pkg_name pkg_names[depth]=pkg_name
if(dbg) printf "new pkg_name %s %s\n", x, pkg_name > "/dev/stderr" ; if(dbg) printf "new pkg_name %s %s\n", x, pkg_name > "/dev/stderr" ;
} }
@ -124,10 +187,15 @@ do_work() {
END { END {
if(dbg) printf "eND \\"%s\\"\n", pkg_name > "/dev/stderr" ; 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"; if(dbg)printf "eNd \\"%s\\"\n", req > "/dev/stderr";
# format: provides:requires # format: provides:requires
printf "%s:%s\n", req, reqs[req]; 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, ppx_runtime_deps[req];
} }
if(dbg) printf "ENd \\"%s\\"\n", pkg_name > "/dev/stderr" ; if(dbg) printf "ENd \\"%s\\"\n", pkg_name > "/dev/stderr" ;
} }
@ -158,3 +226,4 @@ do
*) ;; *) ;;
esac esac
done done
# vim: tw=666 ts=2 shiftwidth=2 et

View File

@ -0,0 +1,243 @@
#!/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

View File

@ -1,3 +1,20 @@
-------------------------------------------------------------------
Thu Feb 20 20:20:20 UTC 2020 - ohering@suse.de
- 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
------------------------------------------------------------------- -------------------------------------------------------------------
Mon Nov 25 12:34:56 UTC 2019 - ohering@suse.de Mon Nov 25 12:34:56 UTC 2019 - ohering@suse.de

View File

@ -16,14 +16,16 @@
# #
Name: ocaml-rpm-macros Name: ocaml-rpm-macros
Version: 20191101 Version: 20200220
Release: 0 Release: 0
Summary: RPM macros for building OCaml source packages Summary: RPM macros for building OCaml source packages
License: GPL-2.0-only License: GPL-2.0-only
Group: Development/Languages/OCaml Group: Development/Languages/OCaml
Url: https://build.opensuse.org/project/show/devel: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 Source1: ocaml-findlib.rpm.prov_req.attr.sh
%define ocaml_standard_library %{_libdir}/ocaml
%define do_opt 0 %define do_opt 0
# macros to be set in prjconf: # macros to be set in prjconf:
#Macros: #Macros:
@ -60,13 +62,25 @@ in ocaml spec files.
%build %build
%install %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 # map findlib names to rpm Provides/Requires
tag="ocamlfind" tag="ocamlfind"
mkdir -vp %{buildroot}%{_rpmconfigdir}/fileattrs mkdir -vp %{buildroot}%{_rpmconfigdir}/fileattrs
tee %{buildroot}%{_rpmconfigdir}/fileattrs/${tag}.attr <<_EOF_ tee %{buildroot}%{_rpmconfigdir}/fileattrs/${tag}.attr <<_EOF_
%__${tag}_provides %%{_rpmconfigdir}/${tag}.sh -prov %__${tag}_provides %%{_rpmconfigdir}/${tag}.sh -prov
%__${tag}_requires %%{_rpmconfigdir}/${tag}.sh -req %__${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_ _EOF_
# #
tee %{buildroot}%{_rpmconfigdir}/${tag}.sh < %{SOURCE1} tee %{buildroot}%{_rpmconfigdir}/${tag}.sh < %{SOURCE1}
@ -74,12 +88,23 @@ tee %{buildroot}%{_rpmconfigdir}/${tag}.sh < %{SOURCE1}
# install OCaml macros # install OCaml macros
mkdir -vp %{buildroot}%{_rpmmacrodir} mkdir -vp %{buildroot}%{_rpmmacrodir}
tee %{buildroot}%{_rpmmacrodir}/macros.%{name} <<'_EOF_' 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 # get rid of %{_rpmconfigdir}/find-debuginfo.sh
# strip kills the bytecode part of ELF binaries # strip kills the bytecode part of ELF binaries
# #
# provide empty _find_debuginfo_dwz_opts # provide empty _find_debuginfo_dwz_opts
# the .dwz files contains identical contents, which leads to identical # the .dwz files contains identical contents, which leads to identical
# checksums, which leads to file conflicts due to identical symlinks # checksums, which leads to file conflicts due to identical symlinks
%%ocaml_standard_library %{ocaml_standard_library}
%if %{do_opt} %if %{do_opt}
%%ocaml_preserve_bytecode \ %%ocaml_preserve_bytecode \
%%define _lto_cflags %%{nil} \ %%define _lto_cflags %%{nil} \
@ -108,12 +133,13 @@ tee %{buildroot}%{_rpmmacrodir}/macros.%{name} <<'_EOF_'
COPYING \\\ COPYING \\\
COPYING.txt \\\ COPYING.txt \\\
COPYRIGHT \\\ COPYRIGHT \\\
COPYRIGHT.txt \\\
Copyright \\\ Copyright \\\
LGPL \\\
LICENCE \\\ LICENCE \\\
LICENSE \\\ LICENSE \\\
LICENSE.md \\\ LICENSE.md \\\
LICENSE.txt \\\ LICENSE.txt \\\
LGPL \\\
;\ ;\
do\ do\
%if 0%{?suse_version} > 1315 %if 0%{?suse_version} > 1315
@ -123,80 +149,168 @@ tee %{buildroot}%{_rpmmacrodir}/macros.%{name} <<'_EOF_'
%endif %endif
test -f "${license}" && echo "%%%%${license_macro} ${license}" >> '%%{name}.files.license' ;\ test -f "${license}" && echo "%%%%${license_macro} ${license}" >> '%%{name}.files.license' ;\
done ;\ done ;\
find %%{buildroot}$(ocamlc -where) | sed -ne '\ find %%{buildroot}%%{ocaml_standard_library} -name '*.cmxs' -exec chmod -v a-x '{}' +\
s@^%%{buildroot}@@\ 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\ # for findlib, describing a package\
/\\/META$/{ b files_devel }\ /\\/META$/{\
files_devel($0)\
}\
# stub ELF library\ # stub ELF library\
/\\/[^/]\\+\\.so$/{ b files_ldsoconf }\ /\\/[^/]+\.so$/{\
files_ldconf($0)\
}\
# stub ELF library\ # stub ELF library\
/\\/[^/]\\+\\.so.owner$/{ b files_ldsoconf }\ /\\/[^/]+\.so.owner$/{\
files_ldconf($0)\
}\
# ELF archive with object files\ # ELF archive with object files\
/\\/[^/]\\+\\.a$/{ b files_devel }\ /\\/[^/]+\.a$/{\
files_devel($0)\
}\
# OCaml legacy source code annotations, produced via -annot\ # OCaml legacy source code annotations, produced via -annot\
/\\/[^/]\\+\\.annot$/{ b files_devel }\ /\\/[^/]+\.annot$/{\
files_devel($0)\
}\
# OCaml library file with bytecode\ # OCaml library file with bytecode\
/\\/[^/]\\+\\.cma$/{ b files_devel }\ /\\/[^/]+\.cma$/{\
files_devel($0)\
}\
# OCaml compiled header file\ # OCaml compiled header file\
/\\/[^/]\\+\\.cmi$/{ b files_devel }\ /\\/[^/]+\.cmi$/{\
files_devel($0)\
}\
# OCaml object file with bytecode\ # OCaml object file with bytecode\
/\\/[^/]\\+\\.cmo$/{ b files_devel }\ /\\/[^/]+\.cmo$/{\
files_devel($0)\
}\
# OCaml source code annotations, produced via -bin-annot from source files\ # 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\ # 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\ # OCaml object file with native code\
/\\/[^/]\\+\\.cmx$/{ b files_devel }\ /\\/[^/]+\.cmx$/{\
files_devel($0)\
}\
# OCaml library file with native code\ # OCaml library file with native code\
/\\/[^/]\\+\\.cmxa$/{ b files_devel }\ /\\/[^/]+\.cmxa$/{\
files_devel($0)\
}\
# ELF shared library with native code\ # ELF shared library with native code\
/\\/[^/]\\+\\.cmxs$/{ b files_devel }\ /\\/[^/]+\.cmxs$/{\
files_devel($0)\
}\
# Some helper binary\ # Some helper binary\
/\\/[^/]\\+\\.exe$/{ b files_devel }\ /\\/[^/]+\.exe$/{\
files_devel($0)\
}\
# C header\ # C header\
/\\/[^/]\\+\\.h$/{ b files_devel }\ /\\/[^/]+\.h$/{\
files_devel($0)\
}\
#\ #\
/\\/[^/]\\+\\.js$/{ b files_devel }\ /\\/[^/]+\.js$/{\
files_devel($0)\
}\
# OCaml source code, source file\ # OCaml source code, source file\
/\\/[^/]\\+\\.ml$/{ b files_devel }\ /\\/[^/]+\.ml$/{\
files_devel($0)\
}\
# OCaml source code, header file\ # OCaml source code, header file\
/\\/[^/]\\+\\.mli$/{ b files_devel }\ /\\/[^/]+\.mli$/{\
files_devel($0)\
}\
# ELF object file\ # ELF object file\
/\\/[^/]\\+\\.o$/{ b files_devel }\ /\\/[^/]+\.o$/{\
files_devel($0)\
}\
#\ #\
/\\/[^/]\\+\\.sml$/{ b files_devel }\ /\\/[^/]+\.sml$/{\
#\ files_devel($0)\
/\\/dune-package$/{ b files_devel }\ }\
#\ # generated by dune\
/\\/opam$/{ b files_devel }\ /\\/dune-package$/{\
files_devel($0)\
}\
# generated by dune\
/\\/opam$/{\
files_devel($0)\
}\
#\ #\
# record unknown paths\ # record unknown paths\
w %%{name}.files.unhandled\ files_unhandled($0)\
d\ END {\
#\ ;\
: files_devel\ }' ;\
# full path for file\ cat '%%{name}.files.license' >> '%%{name}.files' ;\
w %%{name}.files.devel\ if test -s %%{name}.files.ldsoconf ;\
# tag + dirname\ then\
s@\\/[^/]\\+$@@\ ldsoconfd='/etc/ld.so.conf.d' ;\
: tag_dirname\ mkdir -vp "%%{buildroot}${ldsoconfd}" ;\
s@^@%%dir @\ tee "%%{buildroot}${ldsoconfd}/%%{name}.conf" < %%{name}.files.ldsoconf ;\
w %%{name}.files.devel\ echo "%config ${ldsoconfd}/%%{name}.conf" >> %%{name}.files.devel ;\
# parent directory\ fi ;\
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 \\\ for i in \\\
%%{name}.files \\\ %%{name}.files \\\
%%{name}.files.devel \\\ %%{name}.files.devel \\\
@ -207,19 +321,6 @@ tee %{buildroot}%{_rpmmacrodir}/macros.%{name} <<'_EOF_'
sort -u $i > $$ ;\ sort -u $i > $$ ;\
mv $$ $i ;\ mv $$ $i ;\
done ;\ done ;\
if test -s %%{name}.files.ldsoconf ;\
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 ;\
fi ;\
head -n 1234 \\\
%%{name}.files \\\
%%{name}.files.devel \\\
%%{name}.files.ldsoconf \\\
%%{name}.files.unhandled \\\
;\
%%{nil} %%{nil}
# setup.ml comes from oasis, but this is here for libs oasis depends on # setup.ml comes from oasis, but this is here for libs oasis depends on
@ -277,7 +378,7 @@ ocaml setup.ml -configure \\\
%%ocaml_oasis_install \ %%ocaml_oasis_install \
ocaml setup.ml -install ocaml setup.ml -install
%%ocaml_oasis_findlib_install \ %%ocaml_oasis_findlib_install \
export OCAMLFIND_DESTDIR=%%{buildroot}`ocamlc -where` ; \ export OCAMLFIND_DESTDIR=%%{buildroot}%%{ocaml_standard_library} ; \
export OCAMLFIND_LDCONF=/dev/null ; \ export OCAMLFIND_LDCONF=/dev/null ; \
mkdir -p $OCAMLFIND_DESTDIR ; \ mkdir -p $OCAMLFIND_DESTDIR ; \
ocaml setup.ml -install ocaml setup.ml -install
@ -322,22 +423,22 @@ ocaml setup.ml -configure \\\
%ifarch ppc64 ppc64le %ifarch ppc64 ppc64le
ulimit -s $((1024 * 64)) ; \ ulimit -s $((1024 * 64)) ; \
%endif %endif
dune_for_release= ; \ dune_for_release= ;\
if test -f dune_release_pkgs-%%{name}-%%{version}-%%{release} ; \ if test -f dune_release_pkgs-%%{name}-%%{version}-%%{release} ; \
then \ then \
read dune_release_pkgs < dune_release_pkgs-%%{name}-%%{version}-%%{release} ; \ read dune_release_pkgs < dune_release_pkgs-%%{name}-%%{version}-%%{release} ; \
dune_for_release="--for-release-of-packages=${dune_release_pkgs}" ; \ dune_for_release="--for-release-of-packages=${dune_release_pkgs}" ; \
fi ; \ fi ;\
dune install \\\ dune install \\\
--verbose \\\ --verbose \\\
${dune_for_release} \\\ ${dune_for_release} \\\
%%{?_smp_mflags} \\\ %%{?_smp_mflags} \\\
--prefix=%%{_prefix} \\\ --prefix=%%{_prefix} \\\
--libdir=$(ocamlc -where) \\\ --libdir=%%{ocaml_standard_library} \\\
--destdir=%%{buildroot} \\\ --destdir=%%{buildroot} \\\
${dune_release_pkgs//,/ } \\\ ${dune_release_pkgs//,/ } \\\
$OCAML_DUNE_INSTALL_ARGS ; \ $OCAML_DUNE_INSTALL_ARGS ;\
rm -rfv %%{buildroot}%%{_prefix}/doc ; \ rm -rfv %%{buildroot}%%{_prefix}/doc ;\
if test -d %%{buildroot}%%{_prefix}/man ; then \ if test -d %%{buildroot}%%{_prefix}/man ; then \
mkdir -vp %%{buildroot}%%{_datadir} ; \ mkdir -vp %%{buildroot}%%{_datadir} ; \
mv -vt %%{buildroot}%%{_datadir} %%{buildroot}%%{_prefix}/man ; \ mv -vt %%{buildroot}%%{_datadir} %%{buildroot}%%{_prefix}/man ; \