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:
commit
f88bd505cc
@ -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
|
||||||
|
243
ocaml-ocaml.rpm.prov_req.attr.sh
Normal file
243
ocaml-ocaml.rpm.prov_req.attr.sh
Normal 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
|
@ -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
|
||||||
|
|
||||||
|
@ -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 ; \
|
||||||
|
Loading…
Reference in New Issue
Block a user