#3 Build the implementation as a shared library
Merged 7 months ago by music. Opened 2 years ago by music.
rpms/ music/catch22 shared-lib  into  rawhide

file added
+67
@@ -0,0 +1,67 @@ 

+ DOWNSTREAM_SO_NUMBER = YOU_MUST_SET_THIS

+ 

+ CC = gcc

+ CFLAGS ?= -O2 -Wall -Wextra

+ LDFLAGS ?=

+ LDLIBS = -lm

+ 

+ INSTALL = install -p

+ PREFIX ?= /usr/local

+ LIBDIR ?= $(PREFIX)/lib

+ INCLUDEDIR ?= $(PREFIX)/include

+ BINDIR ?= $(PREFIX)/bin

+ 

+ all: run_features lib

+ 

+ # https://github.oom/chlubba/catch22/wiki/Installation-and-Testing

+ OBJECTS = \

+ 	butterworth.o \

+ 	CO_AutoCorr.o \

+ 	DN_HistogramMode_10.o \

+ 	DN_HistogramMode_5.o \

+ 	DN_Mean.o \

+ 	DN_OutlierInclude.o \

+ 	DN_Spread_Std.o \

+ 	FC_LocalSimple.o \

+ 	fft.o \

+ 	helper_functions.o \

+ 	histcounts.o \

+ 	IN_AutoMutualInfoStats.o \

+ 	MD_hrv.o \

+ 	PD_PeriodicityWang.o \

+ 	SB_BinaryStats.o \

+ 	SB_CoarseGrain.o \

+ 	SB_MotifThree.o \

+ 	SB_TransitionMatrix.o \

+ 	SC_FluctAnal.o \

+ 	splinefit.o \

+ 	SP_Summaries.o \

+ 	stats.o

+ 

+ %.o: %.c

+ 	$(CC) $(CFLAGS) -fpic -c -o $@ $^

+ 

+ libcatch22.so.0.$(DOWNSTREAM_SO_NUMBER): $(OBJECTS)

+ 	$(CC) $(LDFLAGS) -Wl,-soname,libcatch22.so.0.$(DOWNSTREAM_SO_NUMBER) -shared -o $@ $^ $(LDLIBS)

+ 

+ libcatch22.so: libcatch22.so.0.$(DOWNSTREAM_SO_NUMBER)

+ 	ln -svf libcatch22.so.0.$(DOWNSTREAM_SO_NUMBER) libcatch22.so

+ 

+ lib: libcatch22.so libcatch22.so.0.$(DOWNSTREAM_SO_NUMBER)

+ 

+ run_features: main.o libcatch22.so

+ 	$(CC) $(LDFLAGS) -o $@ main.o -L. -lcatch22 $(LDLIBS)

+ 

+ clean:

+ 	$(RM) *.so* *.o run_features

+ 

+ install: all

+ 	$(INSTALL) -d $(DESTDIR)$(LIBDIR)

+ 	$(INSTALL) -t $(DESTDIR)$(LIBDIR) libcatch22.so.0.$(DOWNSTREAM_SO_NUMBER)

+ 	ln -s libcatch22.so.0.$(DOWNSTREAM_SO_NUMBER) $(DESTDIR)$(LIBDIR)/libcatch22.so

+ 	$(INSTALL) -d $(DESTDIR)$(INCLUDEDIR)/catch22

+ 	$(INSTALL) -t $(DESTDIR)$(INCLUDEDIR)/catch22 -m 0644 *.h

+ 	$(INSTALL) -d $(DESTDIR)$(BINDIR)

+ 	$(INSTALL) -t $(DESTDIR)$(BINDIR) run_features

+ 

+ .PHONY: clean lib install

file modified
+59 -34
@@ -12,6 +12,9 @@ 

  # https://github.com/chlubba/catch22/wiki/Installation-and-Testing#r says that is to be preferred

  # https://github.com/hendersontrent/Rcatch22

  

+ # Downstream .so version; see comment above Source2, and make sure to increment

+ # the following integer each time there is an ABI change upstream.

+ %global downstream_so_number 1

  Name:           catch22

  Version:        0.4.0

  Release:        %autorelease
@@ -28,6 +31,10 @@ 

  Source1:        compare_output

  # Hand-written for Fedora in groff_man(7) format based on --help text

  Source2:        run_features.1

+ # Upstream does not provide any build system at all. This Makefile allows us to

+ # build a shared library and link the run_features executable to it. We must

+ # therefore use downstream .so versioning.

+ Source3:        Makefile

  

  # Backport upstream commit 135fb01bbd71c98fea01a7a2612abdca531b44f6 “Python

  # version numbering fixed”
@@ -38,6 +45,7 @@ 

  # https://github.com/DynamicsAndNeuralSystems/catch22/issues/27

  Patch:          %{url}/commit/135fb01bbd71c98fea01a7a2612abdca531b44f6.patch

  

+ BuildRequires:  make

  BuildRequires:  gcc

  BuildRequires:  python3-devel

  
@@ -63,8 +71,35 @@ 

  For catch22-related information and resources, including a list of publications

  using catch22, see the catch22 wiki (https://github.com/chlubba/catch22/wiki).}

  

+ Requires:       %{name}-libs = %{version}-%{release}

+ 

  %description %_description

  

+ This package contains the command-line tool run_features.

+ 

+ 

+ %package libs

+ Summary:        %{summary}

+ # See the comment above the base package License field

+ License:        GPL-3.0-only

+ 

+ %description libs %{_description}

+ 

+ This package contains the implementation compiled as a shared library.

+ 

+ 

+ %package devel

+ Summary:        %{summary}

+ # See the comment above the base package License field

+ License:        GPL-3.0-only

+ 

+ Requires:       %{name}-libs = %{version}-%{release}

+ 

+ %description devel %{_description}

+ 

+ This package contains headers and other files required for developing

+ applications that link against the implementation as a shared library.

+ 

  

  %if %{with Py}

  %package -n python3-%{name}
@@ -94,6 +129,7 @@ 

  

  %prep

  %autosetup -p1

+ cp -p '%{SOURCE3}' C/

  find . -name ".gitignore" -print -delete

  

  %if %{with Py}
@@ -119,35 +155,8 @@ 

  

  

  %build

- pushd C

  %set_build_flags

- # https://github.com/chlubba/catch22/wiki/Installation-and-Testing

- "${CC-gcc}" ${CFLAGS} -o run_features \

-     main.c \

-     CO_AutoCorr.c \

-     DN_HistogramMode_10.c \

-     DN_HistogramMode_5.c \

-     DN_OutlierInclude.c \

-     FC_LocalSimple.c \

-     IN_AutoMutualInfoStats.c \

-     MD_hrv.c \

-     PD_PeriodicityWang.c \

-     SB_BinaryStats.c \

-     SB_CoarseGrain.c \

-     SB_MotifThree.c \

-     SB_TransitionMatrix.c \

-     SC_FluctAnal.c \

-     SP_Summaries.c \

-     DN_Mean.c \

-     DN_Spread_Std.c \

-     butterworth.c \

-     fft.c \

-     helper_functions.c \

-     histcounts.c \

-     splinefit.c \

-     stats.c \

-     ${LDFLAGS} -lm

- popd

+ %make_build -C C DOWNSTREAM_SO_NUMBER='%{downstream_so_number}'

  

  %if %{with Py}

  pushd wrap_Python
@@ -161,9 +170,12 @@ 

  

  

  %install

- pushd C

- install -p -m 0755 run_features -Dt %{buildroot}/%{_bindir}

- popd

+ %make_install -C C \

+     DOWNSTREAM_SO_NUMBER='%{downstream_so_number}' \

+     PREFIX='%{_prefix}' \

+     INCLUDEDIR='%{_includedir}' \

+     LIBDIR='%{_libdir}' \

+     BINDIR='%{_bindir}'

  install -t '%{buildroot}%{_mandir}/man1' -D -p -m 0644 '%{SOURCE2}'

  

  %if %{with Py}
@@ -181,7 +193,9 @@ 

  %check

  find testData -type f -name '*_output.txt' \

      -execdir cp -v -p '{}' '{}.expected' ';'

- PATH="${PATH}:%{buildroot}%{_bindir}" ./testData/runtests.sh

+ env LD_LIBRARY_PATH='%{buildroot}%{_libdir}' \

+     PATH="${PATH}:%{buildroot}%{_bindir}" \

+     ./testData/runtests.sh

  

  for x in testData/*.expected

  do
@@ -213,12 +227,23 @@ 

  

  

  %files

- %license LICENSE

- %doc README.md featureList.txt

  %{_bindir}/run_features

  %{_mandir}/man1/run_features.1*

  

  

+ %files libs

+ %license LICENSE

+ 

+ %{_libdir}/lib%{name}.so.0.%{downstream_so_number}

+ 

+ 

+ %files devel

+ %doc README.md featureList.txt

+ 

+ %{_includedir}/%{name}/

+ %{_libdir}/lib%{name}.so

+ 

+ 

  %if %{with Py}

  %files -n python3-%{name} -f %{pyproject_files}

  %license LICENSE

  • Add catch22-libs and catch22-devel subpackages.

Upstream has started to maintain the Python bindings as a separate repository, and the Python package name has changed:

https://github.com/DynamicsAndNeuralSystems/pycatch22
https://pypi.org/project/pycatch22/

Building a shared library should allow us to create a new python-pycatch22 package with the catch22 implementation unbundled.

I wish they hadn't split and bundled, we'll have to tweak the build system of pycatch22 to use the shared object too.

I worry about us providing a general shared object a little. It isn't clear to me if upstream intends this, and if they don't they also dont worry about soname versions and ABI stability. Us providing a versioned shared object may indicate to downstream users that it is meant to be developed against etc.

Is it worth speaking to upstream about this, do you think?

A "middle path" could be to generate the soname but keep the version at 0, and keep it in a /usr/lib/catch22/.. folder to indicate that it's a private shared object? That'll still allow us to use it for the pycatch22 package, but it'll prevent others from using it as a public shared object to develop against?

(I may not be making sense here, please do let me know if that's the case :D)

I worry about us providing a general shared object a little. It isn't clear to me if upstream intends this, and if they don't they also dont worry about soname versions and ABI stability. Us providing a versioned shared object may indicate to downstream users that it is meant to be developed against etc.

That’s fair. As you might remember, upstream provides no build system at all, just a comment in the documentation about feeding all the sources to GCC.

Is it worth speaking to upstream about this, do you think?

Maybe. Trying to persuade them to usefully organize the code as a library would be a public service, although I’m not quite sure if I’m feeling up to tackling it right now.

A "middle path" could be to generate the soname but keep the version at 0, and keep it in a /usr/lib/catch22/.. folder to indicate that it's a private shared object? That'll still allow us to use it for the pycatch22 package, but it'll prevent others from using it as a public shared object to develop against?

Note that the .so version here is 0.1 in accordance with the downstream .so versioning guidelines, not just 1.

However, the suggestion of building as a “private” library is not a bad one.

Another possibility is to throw up our hands and say that upstream doesn’t even build catch22 as a library, so we can’t be expected to unbundle it. That’s a valid approach.

We have some time to think it over. Let me know how your thoughts develop.

I opened a ticket upstream:

https://github.com/DynamicsAndNeuralSystems/catch22/issues/29

we can wait a few days to see what they say and then see what we want to do

This is what upstream said:

Thanks for the input and interest in the package. Yes, we thought it was cleaner to separate out
the R, python, and Julia wrappers into their own repos. We are not proficient in managing shared 
libraries, and for use in python are supporting installation as pycatch22 via pip.

If I understand correctly, there is elegance in the shared library solution in maintaining the C in a 
single place, but given we are not proficient in managing it and don't anticipate changes to it, were 
planning to go with the less elegant solution [in the case of any change being required: manually 
propagating (or using git submodule) any updates in the C source to the other (wrapper) packages 
for R, python, and Julia…], which allows the wrappers, like pycatch22, Rcatch22, and Catch22.jl, to 
work as standalone packages.

https://github.com/DynamicsAndNeuralSystems/catch22/issues/29

So upstream has no intention of going down the shared object route. We'll need to do it ourselves.

What do you think @music ?

What do you think? You’ll have to live with whatever we do, so I am happy to defer to your preference. I think any of the following are reasonable:

  • Build a shared object ourselves as in this PR, and take care of bumping the .so version as needed (probably every time). Carry an unbundling patch in the Python bindings (probably a trivial one).
  • As above, but keep the shared library out of the default linking path. I think I like this less and less the more I consider it, though.
  • Just go ahead with bundling, since upstream doesn’t support an external library for the Python bindings and we’ve satisfied the requirements in https://docs.fedoraproject.org/en-US/packaging-guidelines/#bundling.

Sorry for the delay @music, fell down my task list..

Should we go with option 1 here for now, and we can always return to bundling in the future if required?

We haven't packaged/planned to package the R and Julia versions yet, so we can think about this again later if/when we get to those.

Housekeeping

Looking at the current version of the package, I assume this is still ongoing. Any updates?

Looking at the current version of the package, I assume this is still ongoing. Any updates?

I don’t want to speak for Ankur, but from my perspective it’s ongoing in the sense that the status quo was unsatisfying and we kind of quietly walked away from it in favor of working on other things.

I think I could be OK with reviving the downstream shared library patch approach. Upstream is not very active, and carrying the patch should be low-maintenance even though it is fairly intrusive. (But it mostly just moves complexity out of the existing spec file’s %build section since there is no upstream build system.) I do think I would want to try packaging the Python package and linking it against the proposed shared library before merging this PR.

rebased onto b5f612f

8 months ago

Rebased without further work.

I spent a little time trying to build a python-pycatch22 package linked against the shared library from this PR.

The first thing I found is that the *_*.h pattern in https://src.fedoraproject.org/rpms/catch22/pull-request/3#_1__64 is bogus. All of the headers are needed.

Once I fix that, I find I can build a python-pycatch22 package against the resulting shared library with only trivial downstream patching in that package.

I guess that’s probably worth it.

rebased onto e569731

8 months ago

The old Python bindings, python3dist(catch22), are still buildable from this repository, but once we have a python-pycatch22 package for python3dist(pycatch22) we should probably stop building Python bindings in this package and Obsolete them, since I think they’re just “repo cruft” rather than a maintained interface at this point. Note that https://pypi.org/project/catch22/ has only one release, and it’s been yanked.

rebased onto e2b6412

8 months ago

Rebased on top of https://src.fedoraproject.org/rpms/catch22/pull-request/4.

I’m going to go ahead and merge both of these and prepare the review request for python-pycatch22. Once that package is in Rawhide, I’ll start backporting these PR’s and building the new package for older releases.

If we decide it was a mistake down the road, it’s not too hard to back out the shared-library approach and go back to bundling.

rebased onto 593aa7c

7 months ago

Pull-Request has been merged by music

7 months ago
Metadata