Sync from SUSE:ALP:Source:Standard:1.0 ocaml-rpm-macros revision ea8fc1b2a682e96b55d82beb371b96fb

This commit is contained in:
Adrian Schröter 2023-12-21 13:27:00 +01:00
commit f00d66f3ee
5 changed files with 1238 additions and 0 deletions

23
.gitattributes vendored Normal file
View File

@ -0,0 +1,23 @@
## Default LFS
*.7z filter=lfs diff=lfs merge=lfs -text
*.bsp filter=lfs diff=lfs merge=lfs -text
*.bz2 filter=lfs diff=lfs merge=lfs -text
*.gem filter=lfs diff=lfs merge=lfs -text
*.gz filter=lfs diff=lfs merge=lfs -text
*.jar filter=lfs diff=lfs merge=lfs -text
*.lz filter=lfs diff=lfs merge=lfs -text
*.lzma filter=lfs diff=lfs merge=lfs -text
*.obscpio filter=lfs diff=lfs merge=lfs -text
*.oxt filter=lfs diff=lfs merge=lfs -text
*.pdf filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.rpm filter=lfs diff=lfs merge=lfs -text
*.tbz filter=lfs diff=lfs merge=lfs -text
*.tbz2 filter=lfs diff=lfs merge=lfs -text
*.tgz filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.txz filter=lfs diff=lfs merge=lfs -text
*.whl filter=lfs diff=lfs merge=lfs -text
*.xz filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.zst filter=lfs diff=lfs merge=lfs -text

View File

@ -0,0 +1,235 @@
#!/bin/bash
set -e
prov_req_name="ocamlfind"
td=`mktemp --directory`
test -n "${td}"
_x() {
rm -rf "${td}"
}
trap _x EXIT
cmd=
test "$1" = "-prov" && cmd=prov
test "$1" = "-req" && cmd=req
do_work() {
local f=$1
local pkg_name
local pkg_prov_req
local pkg_prov
local pkg_req
local elem req
pkg_name="${f##*/}"
if test "${pkg_name}" = "META"
then
pkg_name="${f%/*}"
pkg_name="${pkg_name##*/}"
else
pkg_name="${pkg_name#META.}"
fi
pkg_prov_req="`
env \
pkg_name="${pkg_name}" \
cmd="${cmd}" \
awk '
BEGIN {
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" ;
requires[pkg_name]=""
ppx_runtime_deps[pkg_name]=""
pkg_names[depth]=pkg_name
}
{
if(dbg) printf "line: %s\n", $0 > "/dev/stderr"
}
/^[[:blank:]]*directory[[:blank:]]*=/ {
if(dbg) printf "GOT: %s\n", $0 > "/dev/stderr" ;
if (depth == 0) {
x = split($0, a, "\\"");
if ( a[2] ) {
candidate = a[2];
if(dbg) printf "dir: %s %s\n", x, candidate > "/dev/stderr" ;
if (candidate == "^") {
next
}
if (candidate == "+") {
next
}
if (candidate ~ /^\^/) {
next
}
if (candidate ~ /^\+/) {
candidate = substr(candidate, 2);
}
if (candidate ~ /^\//) {
x = split(candidate, a, "/");
if ( x )
candidate = a[x];
}
if (candidate ~ /^\.\.\//) {
x = split(candidate, a, "/");
if ( x )
candidate = a[x];
}
if(dbg) printf "dir: %s %s\n", x, candidate > "/dev/stderr" ;
if (candidate != 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
} else {
if(dbg) printf "pkg_name remains %s\n", pkg_name > "/dev/stderr" ;
}
}
}
next
}
/^[[:blank:]]*requires(|\([^-][^)]+\))[[:blank:]]*(+=|=)/ {
if(dbg) printf "GOT: %s\n", $0 > "/dev/stderr" ;
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" ;
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
}
/^[[:blank:]]*package[[:blank:]]/ {
if(dbg) printf "GOT: %s\n", $0 > "/dev/stderr" ;
depth = depth + 1;
if(dbg) printf "depth %s\n", depth > "/dev/stderr" ;
x = split($0, a, "\\"");
if ( a[2] ) {
if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ;
pkg_name = pkg_name"."a[2];
requires[pkg_name]=""
pkg_names[depth]=pkg_name
if(dbg) printf "new pkg_name %s %s\n", x, pkg_name > "/dev/stderr" ;
}
next
}
/^[[:blank:]]*)/ {
if(dbg) printf "GOT: %s\n", $0 > "/dev/stderr" ;
depth = depth -1;
if(dbg) printf "depth %s\n", depth > "/dev/stderr" ;
pkg_name=pkg_names[depth]
if(dbg) printf "old pkg_name %s %s\n", x, pkg_name > "/dev/stderr" ;
next
}
END {
if(dbg) printf "eND \\"%s\\"\n", pkg_name > "/dev/stderr" ;
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, ppx_runtime_deps[req];
}
if(dbg) printf "ENd \\"%s\\"\n", pkg_name > "/dev/stderr" ;
}
' \"${f}\"
`"
for elem in ${pkg_prov_req}
do
pkg_prov="${elem%%:*}"
pkg_req="${elem#*:}"
pkg_req="${pkg_req//,/ }"
if test -n "${pkg_prov}" && test "${cmd}" = "prov"
then
echo "${prov_req_name}($pkg_prov)"
fi
if test "${cmd}" = "req"
then
for i in ${pkg_req}
do
echo "${prov_req_name}(${i})"
done
fi
done
}
while read filename
do
case "${filename}" in
*/META*) do_work "${filename}" ;;
*) ;;
esac
done
# vim: tw=666 ts=2 shiftwidth=2 et

View File

@ -0,0 +1,247 @@
#!/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
#
# cmxs files are recoqnized, but need to be ignored.
# They contain references of the interfaces and implementations
# compiled into them.
#
# 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) ;;
*) continue ;;
esac
done
# vim: tw=666 ts=2 shiftwidth=2 et

188
ocaml-rpm-macros.changes Normal file
View File

@ -0,0 +1,188 @@
-------------------------------------------------------------------
Tue Oct 31 21:44:55 UTC 2023 - Aaron Puchert <aaronpuchert@alice-dsl.net>
- Increase stack size limit for riscv64 like for ppc64(le).
-------------------------------------------------------------------
Sun Jan 29 08:34:55 UTC 2023 - Bernhard Wiedemann <bwiedemann@suse.com>
- Allow variables in smp_mflags to be interpolated
for https://github.com/rpm-software-management/rpm/issues/2343
-------------------------------------------------------------------
Sun Jan 1 01:01:01 UTC 2023 - ohering@suse.de
- Remove stale references to ocaml_make_testsuite
-------------------------------------------------------------------
Thu Jul 7 07:07:07 UTC 2022 - ohering@suse.de
- Handle plain ^ and + as values for directory= in findlib META files
They stand for the OCaml standard library directory.
-------------------------------------------------------------------
Sat Apr 9 12:34:56 UTC 2022 - ohering@suse.de
- remove unused ocaml_dune_bootstrap_directory
- move all invocations of dune from ocaml_dune_setup to ocaml_dune_build
- process content of ocaml_standard_library only if it exists in buildroot
-------------------------------------------------------------------
Tue Feb 22 22:22:22 UTC 2022 - ohering@suse.de
- remove usage of external-lib-deps for dune3
- define ocaml_dune_bootstrap_directory for dune3
- remove braces from rpm macros
-------------------------------------------------------------------
Wed Oct 27 07:31:27 UTC 2021 - ohering@suse.de
- Move cmxs files into the main package
Applications like Coq may load them at runtime.
- Ignore dependencies for cmxs files
- Restore dummy ocaml_native_compiler to allow quilt setup with
old packages
-------------------------------------------------------------------
Sat Sep 11 12:34:56 UTC 2021 - ohering@suse.de
- Rename a single opam file to $dune_release_pkgs.opam
-------------------------------------------------------------------
Wed Apr 21 12:34:56 UTC 2021 - ohering@suse.de
- Remove ocaml_native_compiler flag, assume native target
This flag puts too much burden on pkgs that use ocaml, but build
with their buildsystem instead of using dune
-------------------------------------------------------------------
Fri Apr 9 09:09:09 UTC 2021 - ohering@suse.de
- Use bcond suse_ocaml_use_rpm_license_macro for license in filelist
- Add suse prefix to ocaml_native_compiler to avoid conflict
- Create Provides/Requires only for rpm variants which understand fileattrs
- Fix syntax for chmod of .cmxs
- Add conditional to disable debug_package macro when building with broken rpm variants
-------------------------------------------------------------------
Tue Feb 9 09:09:09 UTC 2021 - ohering@suse.de
- Fix regex in file list generator to really match dot and extension
-------------------------------------------------------------------
Thu Jan 21 21:21:21 UTC 2021 - ohering@suse.de
- Adjust parser of ocamfind() requires
Take negative predicates in requires() into account, and ignore them.
This is supposed to avoid dependency cycles due to excessive
list of dependencies.
-------------------------------------------------------------------
Thu Jan 14 14:14:14 UTC 2021 - ohering@suse.de
- Adjust injection of version into findlib META files
A file VERSION is not handled anymore by dune since 1.11.
Remove version: from *.opam files, inject version into dune-project
-------------------------------------------------------------------
Thu Aug 20 20:20:20 UTC 2020 - ohering@suse.de
- Package also *.v, for Coq
- Package changelog files
- Enable native riscv64
-------------------------------------------------------------------
Thu May 14 14:14:14 UTC 2020 - ohering@suse.de
- The filename for rpm *.attr files and the tag used within these
files must match. Otherwise rpm will not execute the helper scripts.
Use tag 'suseocaml', rename zocaml.attr to suseocaml.attr to
avoid filename conflicts with rpm-build.rpm (bsc#1154874)
- Rename also ocamlfind to suseocamlfind
- Escape plain % chars
-------------------------------------------------------------------
Sun Apr 12 12:12:12 UTC 2020 - ohering@suse.de
- run OCaml rpm dependency generator only if both path and magic matches (rpm#1173)
-------------------------------------------------------------------
Sat Mar 21 12:34:56 UTC 2020 - ohering@suse.de
- Disable parallel build for OCaml 4.08, 4.09 and 4.10
to get reproducible cma archives (issue#9307)
-------------------------------------------------------------------
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
- Install also LGPL as license, needed by ocaml-lablgtk2
-------------------------------------------------------------------
Fri Nov 1 12:34:56 UTC 2019 - ohering@suse.de
- Moved ocaml-findlib.rpm.prov_req.attr.sh from ocaml to provide
ocamlfind() in ocaml itself
- Handle license separately because sed w truncates output
- Document individual file extensions
- Move cmxs and so files to devel packages because they are not
used at runtime. Also, cmxs dependencies in main pkg are
not covered by ocaml-find-requires.sh (bsc#1154874)
- Set VERSION unconditionally for each patch, sometimes dune picks it up
- Pass --for-release-of-packages to dune via dune_release_pkgs=
- Print potential BuildRequires during build
- Package sml for camlp5
- SLE_12 has still no license macro, package as doc instead
- Use _smp_mflags instead of nproc for parallel build
-------------------------------------------------------------------
Wed Oct 9 05:48:16 UTC 2019 - ohering@suse.de
- Package also COPYRIGHT, for labltk
- Package also Copyright, for dose3
- Package also *.cmo
- Package also *.so.owner
- Package also *.o
- Package also /etc/ld.so.conf.d
- Package also *.js
-------------------------------------------------------------------
Fri Oct 4 07:56:44 UTC 2019 - ohering@suse.de
- Use _rpmmacrodir
- Automatically package known license files in main pkg
- List unhandled files in ocaml_create_file_list macro
- Do not mark files as %config
-------------------------------------------------------------------
Mon Sep 30 14:15:16 UTC 2019 - ohering@suse.de
- Increase ulimit -s on ppc64 in dune macros
Required for at least ocaml-camomile
- Show external-lib-deps also for dune runtest
- Provide a ocaml_create_file_list macro
- Optional extra args for dune commands
- Pass --verbose to dune commands
- Move prefix/man to datadir/man to workaround bug in dune (#2670)
-------------------------------------------------------------------
Mon Sep 30 12:34:56 UTC 2019 - ohering@suse.de
- moved ocaml-rpm-macros from ocaml.spec to separate pkg

545
ocaml-rpm-macros.spec Normal file
View File

@ -0,0 +1,545 @@
#
# spec file for package ocaml-rpm-macros
#
# Copyright (c) 2023 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
Name: ocaml-rpm-macros
Version: 20231101
Release: 0
Summary: RPM macros for building OCaml source packages
License: GPL-2.0-only
Group: Development/Languages/OCaml
BuildRoot: %_tmppath/%name-%version-build
ExclusiveArch: %arm aarch64 %ix86 ppc ppc64 ppc64le riscv64 s390x x86_64
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
# Some rpm variants know about license, but can only use them in plain file context
%bcond_without suse_ocaml_use_rpm_license_macro
# Some rpm variants are unable to create proper debuginfo and/or debugsource packages
%bcond_without suse_ocaml_opt_debug_package
# Some rpm variants fail to build even this innocent package...
%define debug_package %nil
%define ocaml_standard_library %_libdir/ocaml
%description
OCaml is a high-level, strongly-typed, functional and object-oriented
programming language from the ML family of languages.
This package contains a set of helper macros to unify common code used
in ocaml spec files.
%prep
%build
%install
> files.fileattrs
if test -d '%_rpmconfigdir/fileattrs'
then
# Generating dependencies can currently only be done by rpm versions
# which support "fileattrs", because it is easy to add new hooks.
mkdir -vp %buildroot%_rpmconfigdir/fileattrs
# Map ocamlobjinfo output to rpm Provides/Requires
# This tag name MUST match what ocaml.spec uses internally
tag="suseocaml"
file_attr="%_rpmconfigdir/fileattrs/${tag}.attr"
file_sh="%_rpmconfigdir/${tag}.sh"
attr_sh="%%_rpmconfigdir/${tag}.sh"
tee %buildroot${file_sh} < %{SOURCE0}
tee %buildroot${file_attr} <<_EOF_
%%__${tag}_provides ${attr_sh} --provides
%%__${tag}_requires ${attr_sh} --requires
%%__${tag}_magic ^(Objective caml|OCaml) .*$
%%__${tag}_path .(cma|cmi|cmo|cmx|cmxa)$
%%__${tag}_flags magic_and_path
_EOF_
echo "${file_attr}" >> files.fileattrs
echo "%%attr(755,root,root) ${file_sh}" >> files.fileattrs
# Map findlib names to rpm Provides/Requires
tag="suseocamlfind"
file_attr="%_rpmconfigdir/fileattrs/${tag}.attr"
file_sh="%_rpmconfigdir/${tag}.sh"
attr_sh="%%_rpmconfigdir/${tag}.sh"
tee %buildroot${file_sh} < %{SOURCE1}
tee %buildroot${file_attr} <<_EOF_
%%__${tag}_provides ${attr_sh} -prov
%%__${tag}_requires ${attr_sh} -req
%%__${tag}_path ^%ocaml_standard_library/.*/META$|^%ocaml_standard_library/META$
_EOF_
echo "${file_attr}" >> files.fileattrs
echo "%%attr(755,root,root) ${file_sh}" >> files.fileattrs
fi
#
# 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 %{without suse_ocaml_opt_debug_package}
# Obviously, handling presence or absence of debug information works only when being built in a SUSE system.
%endif
%%ocaml_preserve_bytecode \
%if %{without suse_ocaml_opt_debug_package}
%%define debug_package %%nil \
%%define __debug_install_post %%nil \
%endif
%%define _lto_cflags %%nil \
%%nil
%%_find_debuginfo_dwz_opts %%nil
# Compatibility for quilt setup and old packages
%%ocaml_native_compiler 1
%%suse_ocaml_native_compiler 1
# Create file list for base pkg and base-devel pkg
# Files with known extensions or names are written to 'files' or 'files.devel'
# Other unknown files are shown on stdout
%%ocaml_create_file_list \
> %%name.files ;\
> %%name.files.changes ;\
> %%name.files.devel ;\
> %%name.files.ldsoconf ;\
> %%name.files.license ;\
> %%name.files.unhandled ;\
for changes in \\\
CHANGELOG.md \\\
CHANGES \\\
CHANGES.md \\\
CHANGES.txt \\\
ChangeLog \\\
Changelog \\\
;\
do\
test -f "${changes}" && echo "%%%%doc ${changes}" >> '%%name.files.changes' ;\
done ;\
for license in \\\
COPYING \\\
COPYING.txt \\\
COPYRIGHT \\\
COPYRIGHT.txt \\\
Copyright \\\
LGPL \\\
LICENCE \\\
LICENSE \\\
LICENSE.md \\\
LICENSE.txt \\\
;\
do\
%if %{with suse_ocaml_use_rpm_license_macro}
license_macro='license' ;\
%else
license_macro='doc' ;\
%endif
test -f "${license}" && echo "%%%%${license_macro} ${license}" >> '%%name.files.license' ;\
done ;\
if test -d %%buildroot%%ocaml_standard_library ;\
then\
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_main=%%name.files"\\\
-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_main(line) {\
_split(line)\
print file_path >> out_files_main\
print "%%dir " dirname >> out_files_main\
if (parent_dir != "") {\
print "%%dir " parent_dir >> out_files_main\
}\
next\
}\
function files_unhandled(line) {\
_split(line)\
print file_path >> out_files_unhandled\
next\
}\
# for findlib, describing a package\
/\\/META$/{\
files_devel($0)\
}\
# stub ELF library\
/\\/[^/]+\\.so$/{\
files_ldconf($0)\
}\
# stub ELF library\
/\\/[^/]+\\.so.owner$/{\
files_ldconf($0)\
}\
# ELF archive with object files\
/\\/[^/]+\\.a$/{\
files_devel($0)\
}\
# OCaml legacy source code annotations, produced via -annot\
/\\/[^/]+\\.annot$/{\
files_devel($0)\
}\
# OCaml library file with bytecode\
/\\/[^/]+\\.cma$/{\
files_devel($0)\
}\
# OCaml compiled header file\
/\\/[^/]+\\.cmi$/{\
files_devel($0)\
}\
# OCaml object file with bytecode\
/\\/[^/]+\\.cmo$/{\
files_devel($0)\
}\
# OCaml source code annotations, produced via -bin-annot from source files\
/\\/[^/]+\\.cmt$/{\
files_devel($0)\
}\
# OCaml source code annotations, produced via -bin-annot from header files\
/\\/[^/]+\\.cmti$/{\
files_devel($0)\
}\
# OCaml object file with native code\
/\\/[^/]+\\.cmx$/{\
files_devel($0)\
}\
# OCaml library file with native code\
/\\/[^/]+\\.cmxa$/{\
files_devel($0)\
}\
# ELF shared library with native code\
/\\/[^/]+\\.cmxs$/{\
files_main($0)\
}\
# Some helper binary\
/\\/[^/]+\\.exe$/{\
files_devel($0)\
}\
# C header\
/\\/[^/]+\\.h$/{\
files_devel($0)\
}\
#\
/\\/[^/]+\\.js$/{\
files_devel($0)\
}\
# OCaml source code, source file\
/\\/[^/]+\\.ml$/{\
files_devel($0)\
}\
# OCaml source code, header file\
/\\/[^/]+\\.mli$/{\
files_devel($0)\
}\
# ELF object file\
/\\/[^/]+\\.o$/{\
files_devel($0)\
}\
#\
/\\/[^/]+\\.sml$/{\
files_devel($0)\
}\
# generated by dune\
/\\/dune-package$/{\
files_devel($0)\
}\
# generated by dune\
/\\/opam$/{\
files_devel($0)\
}\
# Some Coq files\
/\\/[^/]+\\.v$/{\
files_devel($0)\
}\
#\
# record unknown paths\
files_unhandled($0)\
END {\
;\
}' ;\
fi ;\
cat '%%name.files.changes' >> '%%name.files' ;\
cat '%%name.files.license' >> '%%name.files' ;\
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.devel ;\
fi ;\
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
#
# html goes into a separate, browsable dir
# which is also safe regarding wiping due to %%doc macro usage
%%_oasis_docdir_base %%_datadir/doc/ocaml
%%_oasis_docdir_dvi %%_oasis_docdir_base/%%name
%%_oasis_docdir_html %%_oasis_docdir_base/%%name
%%_oasis_docdir_pdf %%_oasis_docdir_base/%%name
%%_oasis_docdir_ps %%_oasis_docdir_base/%%name
%%oasis_docdir %%_oasis_docdir_base/%%name
#
# For now provide a convinience macro which covers also the parent dir
%%oasis_docdir_dvi %%dir %%_oasis_docdir_base \
%%_oasis_docdir_dvi
%%oasis_docdir_html %%dir %%_oasis_docdir_base \
%%_oasis_docdir_html
%%oasis_docdir_pdf %%dir %%_oasis_docdir_base \
%%_oasis_docdir_pdf
%%oasis_docdir_ps %%dir %%_oasis_docdir_base \
%%_oasis_docdir_ps
#
# various macros to unify setup/build/install
%%oasis_setup \
oasis setup
%%ocaml_oasis_configure \
ocaml setup.ml -configure \\\
--psdir %%_oasis_docdir_ps \\\
--pdfdir %%_oasis_docdir_pdf \\\
--dvidir %%_oasis_docdir_dvi \\\
--htmldir %%_oasis_docdir_html \\\
--docdir %%oasis_docdir \\\
--localedir %%_datadir/locale \\\
--datadir %%_datadir \\\
\\\
--bindir %%_bindir \\\
--mandir %%_mandir \\\
--destdir %%buildroot \\\
--datarootdir %%_datadir \\\
--infodir %%_infodir \\\
--libdir %%_libdir \\\
--libexecdir %%_libexecdir \\\
--localstatedir %%_localstatedir \\\
--sbindir %%_sbindir \\\
--prefix %%_prefix \\\
--sysconfdir %%_sysconfdir \\\
--exec-prefix %%_prefix \\\
--sharedstatedir %%_sharedstatedir
#
%%ocaml_oasis_build \
ocaml setup.ml -build
%%ocaml_oasis_doc \
ocaml setup.ml -doc
%%ocaml_oasis_install \
ocaml setup.ml -install
%%ocaml_oasis_findlib_install \
export OCAMLFIND_DESTDIR=%%buildroot%%ocaml_standard_library ; \
export OCAMLFIND_LDCONF=/dev/null ; \
mkdir -p $OCAMLFIND_DESTDIR ; \
ocaml setup.ml -install
%%ocaml_oasis_test \
ocaml setup.ml -test
#
%%ocaml_dune_setup \
%ifarch ppc64 ppc64le riscv64
ulimit -s $((1024 * 64)) ; \
%endif
%if 0
# obviously this works just with a single entry in dune_release_pkgs=
%endif
if test -n "${dune_release_pkgs}" ; \
then \
test -f 'opam' && mv -v 'opam' "${dune_release_pkgs}.opam" ; \
fi ; \
echo '%%version' | tee VERSION ; \
for opam in *.opam \
do\
test -f "${opam}" || continue ; \
sed -i~ '\
/^version:/d\
' "${opam}" ; \
diff -u "$_"~ "$_" || : got version ; \
done ; \
if test -f 'dune-project' ; \
then \
sed -i~ '\
/^([[:blank:]]*version[[:blank:]]\\+/d\
/^([[:blank:]]*lang[[:blank:]]\\+dune[[:blank:]]/a (version %%version)\
' 'dune-project'; \
diff -u "$_"~ "$_" || : got version ; \
fi ; \
dune_for_release= ; \
: dune_release_pkgs \
if test -n "${dune_release_pkgs}" ; \
then \
echo "${dune_release_pkgs}" > dune_release_pkgs-%%name-%%version-%%release ; \
dune_for_release="--for-release-of-packages=${dune_release_pkgs}" ; \
fi ; \
%%nil
%%ocaml_dune_build \
dune --version ; \
dune installed-libraries $OCAML_DUNE_INSTALLED_LIBRARIES_ARGS ; \
if test -z "${_smp_mflags}" ;\
then \
_smp_mflags="%%{?_smp_mflags}" ;\
case "$(ocamlc --version)" in \\\
4.08*) _smp_mflags='-j1' ;;\\\
4.09*) _smp_mflags='-j1' ;;\\\
4.10*) _smp_mflags='-j1' ;;\\\
esac ;\
fi ;\
dune build \\\
--verbose \\\
${dune_for_release} \\\
${_smp_mflags} \\\
'@install' \\\
$OCAML_DUNE_BUILD_INSTALL_ARGS
%%ocaml_dune_install \
%ifarch ppc64 ppc64le riscv64
ulimit -s $((1024 * 64)) ; \
%endif
if test -z "${_smp_mflags}" ;\
then \
_smp_mflags="%%{?_smp_mflags}" ;\
case "$(ocamlc --version)" in \\\
4.08*) _smp_mflags='-j1' ;;\\\
4.09*) _smp_mflags='-j1' ;;\\\
4.10*) _smp_mflags='-j1' ;;\\\
esac ;\
fi ;\
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 ;\
dune install \\\
--verbose \\\
${dune_for_release} \\\
${_smp_mflags} \\\
--prefix=%%_prefix \\\
--libdir=%%ocaml_standard_library \\\
--destdir=%%buildroot \\\
${dune_release_pkgs//,/ } \\\
$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 ; \
fi ;
%%ocaml_dune_test \
%ifarch ppc64 ppc64le
ulimit -s $((1024 * 64)) ; \
%endif
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 ; \
if dune runtest \\\
--verbose \\\
${dune_for_release} \\\
$OCAML_DUNE_RUNTEST_ARGS ; \
then \
echo "dune runtest succeeded" ; \
else \
echo "dune runtest failed" ; \
if test -n "${dune_test_tolerate_fail}" ; \
then \
echo "ignored" ; \
else \
echo "aborting" ; \
exit 1 ; \
fi ; \
fi
#
#
_EOF_
%files -f files.fileattrs
%defattr(-,root,root,-)
%_rpmmacrodir/*
%changelog