Subject: [PATCH 4/5] gnu: sameboy: Install shared library.

From: Maxim Cournoyer <[email-masked]>
Date: Sat, 12 Oct 2024 13:28:13 +0900

* gnu/packages/patches/sameboy-shared-lib.patch: New file.
* gnu/local.mk (dist_patch_DATA): Register it.
* gnu/packages/emulators.scm (sameboy) [source]: Apply it.
[arguments] <make-flags>: Replace DATA_DIR with PREFIX.  Add LIBRARY=shared
and FREEDESKTOP=1.
<phases>: Delete install phase override.
[native-inputs]: Add cppp and libtool.

Change-Id: Ieef8434ada5a4e7ba3d726efc9710a9c2c973040
---
 gnu/local.mk                                  |   1 +
 gnu/packages/emulators.scm                    |  23 +-
 gnu/packages/patches/sameboy-shared-lib.patch | 317 ++++++++++++++++++
 3 files changed, 328 insertions(+), 13 deletions(-)
 create mode 100644 gnu/packages/patches/sameboy-shared-lib.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index e08ecc744c..544cf36f04 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -2130,6 +2130,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/s7-flint-3.patch                      	\
   %D%/packages/patches/sajson-for-gemmi-numbers-as-strings.patch	\
   %D%/packages/patches/sajson-build-with-gcc10.patch		\
+  %D%/packages/patches/sameboy-shared-lib.patch			\
   %D%/packages/patches/sbc-fix-build-non-x86.patch		\
   %D%/packages/patches/sbcl-aserve-add-HTML-5-elements.patch	\
   %D%/packages/patches/sbcl-aserve-fix-rfe12668.patch	\
diff --git a/gnu/packages/emulators.scm b/gnu/packages/emulators.scm
index b7dff958b7..3df1b94506 100644
--- a/gnu/packages/emulators.scm
+++ b/gnu/packages/emulators.scm
@@ -60,6 +60,7 @@ (define-module (gnu packages emulators)
   #:use-module (gnu packages bash)
   #:use-module (gnu packages bison)
   #:use-module (gnu packages boost)
+  #:use-module (gnu packages c)
   #:use-module (gnu packages cdrom)
   #:use-module (gnu packages check)
   #:use-module (gnu packages cmake)
@@ -811,27 +812,23 @@ (define-public sameboy
              (commit (string-append "v" version))))
        (file-name (git-file-name name version))
        (sha256
-        (base32 "1lab1x156ghfcjcy31rv731wi2b5h56z35n02h4i5pj8wjcf2jr9"))))
+        (base32 "1lab1x156ghfcjcy31rv731wi2b5h56z35n02h4i5pj8wjcf2jr9"))
+       (patches (search-patches "sameboy-shared-lib.patch"))))
     (build-system gnu-build-system)
     (arguments
      (list
       #:tests? #f                       ; There are no tests
       #:make-flags #~(list #$(string-append "CC=" (cc-for-target))
-                           "NATIVE_CC=gcc" "CONF=release"
-                           (string-append "DATA_DIR=" #$output
-                                          "/share/sameboy/"))
+                           "FREEDESKTOP=1" ;for install target
+                           "LIBRARY=shared"
+                           "NATIVE_CC=gcc"
+                           "CONF=release"
+                           (string-append "PREFIX=" #$output))
       #:phases
       #~(modify-phases %standard-phases
-          (delete 'configure)
-          (replace 'install
-            (lambda _
-              (with-directory-excursion "build/bin/SDL"
-                (install-file "sameboy" (string-append #$output "/bin"))
-                (delete-file "sameboy")
-                (copy-recursively
-                 "." (string-append #$output "/share/sameboy/"))))))))
+          (delete 'configure))))
+    (native-inputs (list cppp libtool pkg-config rgbds))
     (inputs (list sdl2))
-    (native-inputs (list rgbds pkg-config))
     (home-page "https://sameboy.github.io/")
     (synopsis "Accurate Game Boy, Game Boy Color and Super Game Boy emulator")
     (description "SameBoy is a user friendly Game Boy, Game Boy Color
diff --git a/gnu/packages/patches/sameboy-shared-lib.patch b/gnu/packages/patches/sameboy-shared-lib.patch
new file mode 100644
index 0000000000..a18d4dec76
--- /dev/null
+++ b/gnu/packages/patches/sameboy-shared-lib.patch
@@ -0,0 +1,317 @@
+Upstream-status: https://github.com/LIJI32/SameBoy/pull/662
+
+diff --git a/Makefile b/Makefile
+index a1bce3e..cea556e 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,14 @@
+ # Make hacks
+ .INTERMEDIATE:
+ 
++# Library versioning, following libtool's 'version-info' scheme (see:
++# info '(libtool) Libtool versioning' or
++# https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html).
++LT_CURRENT := 0
++LT_REVISION := 0
++LT_AGE := 0
++LT_VERSION_INFO := $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
++
+ # Set target, configuration, version and destination folders
+ 
+ PLATFORM := $(shell uname -s)
+@@ -33,11 +41,47 @@ else
+ DEFAULT := sdl
+ endif
+ 
++ifneq ($(LIBRARY),)
++DEFAULT += lib
++endif
++
++# Select whether libtool should build/link for static vs shared
++# libraries, or both.
++ifneq ($(LIBRARY),)
++ifeq ($(LIBRARY), shared)
++LT_MODE_ARG := -shared
++else ifeq ($(LIBRARY), static)
++LT_MODE_ARG := -static
++else
++# Build both static and shared libraries.
++LT_MODE_ARG :=
++endif
++endif
++
+ NULL := /dev/null
+ ifeq ($(PLATFORM),windows32)
+ NULL := NUL
+ endif
+ 
++# Strip a given prefix from a string.
++# arg1: The prefix to strip.
++# arg2: The text containing the prefix.
++# Return $text with $prefix stripped, else nothing.
++define strip_prefix =
++$(let stripped,$(subst $(1),,$(2)),$\
++  $(shell test "$(1)$(stripped)" = "$(2)" && echo $(stripped)))
++endef
++
++# Simplify a path for use with pkg-config, by replacing $prefix with '${prefix}'
++# arg1: prefix, e.g. an installation prefix, such as /usr/local.
++# arg2: pkgdir, e.g. a path such as $datadir, $bindir, etc.
++# arg3: pkg-config variable name, e.g. 'prefix' or 'exec_prefix'.
++#       Defaults to 'prefix'.
++define simplify_pkgconf_dir =
++$(let stripped,$(call strip_prefix,$(1),$(2)),$\
++  $(if stripped,$${$(or $(3),prefix)}$(stripped),$(2)))
++endef
++
+ ifneq ($(shell which xdg-open 2> $(NULL))$(FREEDESKTOP),)
+ # Running on an FreeDesktop environment, configure for (optional) installation
+ DESTDIR ?= 
+@@ -46,6 +90,22 @@ DATA_DIR ?= $(PREFIX)/share/sameboy/
+ FREEDESKTOP ?= true
+ endif
+ 
++# Autoconf-style conventionally named variables.
++prefix ?= $(PREFIX)
++exec_prefix ?= $(prefix)
++includedir ?= $(prefix)/include
++bindir ?= $(exec_prefix)/bin
++libdir ?= $(exec_prefix)/lib
++datadir ?= $(prefix)/share
++
++# Prettified variants for use in the pkg-config file.
++override PKGCONF_EXEC_PREFIX = \
++	$(call simplify_pkgconf_dir,$(prefix),$(exec_prefix))
++override PKGCONF_INCLUDEDIR = \
++	$(call simplify_pkgconf_dir,$(prefix),$(includedir))
++override PKGCONF_LIBDIR = \
++	$(call simplify_pkgconf_dir,$(exec_prefix),$(libdir),exec_prefix)
++
+ default: $(DEFAULT)
+ 
+ ifeq ($(MAKECMDGOALS),)
+@@ -101,6 +161,9 @@ BIN := build/bin
+ OBJ := build/obj
+ INC := build/include/sameboy
+ LIBDIR := build/lib
++PKGCONF_DIR := $(LIBDIR)/pkgconfig
++LIBTOOL_LIBRARY := $(LIBDIR)/libsameboy.la
++PKGCONF_FILE := $(PKGCONF_DIR)/sameboy.pc
+ 
+ BOOTROMS_DIR ?= $(BIN)/BootROMs
+ 
+@@ -125,6 +188,26 @@ PKG_CONFIG := pkg-config
+ endif
+ endif
+ 
++# Libtool makes it easy to correctly build shared libraries with
++# version info on both MacOS and GNU/Linux; require it if building
++# libraries.
++ifneq ($(LIBRARY),)
++ifneq (, $(shell command -v libtool 2> $(NULL)))
++LIBTOOL := libtool
++LIBTOOL_CC := $(LIBTOOL) --tag=CC --mode=compile $(CC) -c
++LIBTOOL_LD := $(LIBTOOL) --tag=CC --mode=link $(CC) \
++	-version-info $(LT_VERSION_INFO) $(LT_MODE_ARG)
++else
++$(error "please install libtool")
++endif
++else
++# Not building libraries.
++LIBTOOL :=
++LIBTOOL_CC := $(CC)
++LIBTOOL_LD :=
++endif
++
++
+ ifeq ($(PLATFORM),windows32)
+ # To force use of the Unix version instead of the Windows version
+ MKDIR := $(shell which mkdir)
+@@ -276,11 +359,6 @@ LDFLAGS += -Wl,/NODEFAULTLIB:libcmt.lib
+ endif
+ endif
+ 
+-LIBFLAGS := -nostdlib -Wl,-r
+-ifneq ($(PLATFORM),Darwin)
+-LIBFLAGS += -no-pie
+-endif
+-
+ ifeq ($(CONF),debug)
+ CFLAGS += -g
+ else ifeq ($(CONF), release)
+@@ -336,11 +414,14 @@ tester: $(TESTER_TARGET) $(BIN)/tester/dmg_boot.bin $(BIN)/tester/cgb_boot.bin $
+ _ios: $(BIN)/SameBoy-iOS.app $(OBJ)/installer
+ ios-ipa: $(BIN)/SameBoy-iOS.ipa
+ ios-deb: $(BIN)/SameBoy-iOS.deb
++
++# Libraries.
+ ifeq ($(PLATFORM),windows32)
+ lib: lib-unsupported
+-else
+-lib: $(LIBDIR)/libsameboy.o $(LIBDIR)/libsameboy.a
++else ifneq ($(LIBRARY),)
++lib: $(LIBTOOL_LIBRARY) $(PKGCONF_FILE)
+ endif
++
+ all: sdl tester libretro lib
+ ifeq ($(PLATFORM),Darwin)
+ all: cocoa ios-ipa ios-deb
+@@ -361,6 +442,10 @@ CORE_SOURCES += $(shell ls Windows/*.c)
+ endif
+ 
+ CORE_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(CORE_SOURCES))
++# Libtool PIC objects are created along the .o variants, when building
++# a shared library.
++CORE_LOBJECTS := $(patsubst %,$(OBJ)/%.lo,$(CORE_SOURCES))
++$(CORE_LOBJECTS): $(CORE_OBJECTS)
+ PUBLIC_HEADERS := $(patsubst Core/%,$(INC)/%,$(CORE_HEADERS))
+ COCOA_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(COCOA_SOURCES))
+ IOS_OBJECTS := $(patsubst %,$(OBJ)/%.o,$(IOS_SOURCES))
+@@ -404,30 +489,30 @@ $(OBJ)/%.dep: %
+ 
+ $(OBJ)/Core/%.c.o: Core/%.c
+ 	-@$(MKDIR) -p $(dir $@)
+-	$(CC) $(CFLAGS) $(FAT_FLAGS) -DGB_INTERNAL -c $< -o $@
++	$(LIBTOOL_CC) $(CFLAGS) $(FAT_FLAGS) -DGB_INTERNAL -c $< -o $@
+ 
+ $(OBJ)/SDL/%.c.o: SDL/%.c
+ 	-@$(MKDIR) -p $(dir $@)
+-	$(CC) $(CFLAGS) $(FRONTEND_CFLAGS) $(FAT_FLAGS) $(SDL_CFLAGS) $(GL_CFLAGS) -c $< -o $@
++	$(LIBTOOL_CC) $(CFLAGS) $(FRONTEND_CFLAGS) $(FAT_FLAGS) $(SDL_CFLAGS) $(GL_CFLAGS) -c $< -o $@
+ 
+ $(OBJ)/OpenDialog/%.c.o: OpenDialog/%.c
+ 	-@$(MKDIR) -p $(dir $@)
+-	$(CC) $(CFLAGS) $(FRONTEND_CFLAGS) $(FAT_FLAGS) $(SDL_CFLAGS) $(GL_CFLAGS) -c $< -o $@
++	$(LIBTOOL_CC) $(CFLAGS) $(FRONTEND_CFLAGS) $(FAT_FLAGS) $(SDL_CFLAGS) $(GL_CFLAGS) -c $< -o $@
+ 
+ 
+ $(OBJ)/%.c.o: %.c
+ 	-@$(MKDIR) -p $(dir $@)
+-	$(CC) $(CFLAGS) $(FRONTEND_CFLAGS) $(FAT_FLAGS) -c $< -o $@
++	$(LIBTOOL_CC) $(CFLAGS) $(FRONTEND_CFLAGS) $(FAT_FLAGS) -c $< -o $@
+ 	
+ # HexFiend requires more flags
+ $(OBJ)/HexFiend/%.m.o: HexFiend/%.m
+ 	-@$(MKDIR) -p $(dir $@)
+-	$(CC) $(CFLAGS) $(FRONTEND_CFLAGS) $(FAT_FLAGS) $(OCFLAGS) -c $< -o $@ -fno-objc-arc -include HexFiend/HexFiend_2_Framework_Prefix.pch
++	$(LIBTOOL_CC) $(CFLAGS) $(FRONTEND_CFLAGS) $(FAT_FLAGS) $(OCFLAGS) -c $< -o $@ -fno-objc-arc -include HexFiend/HexFiend_2_Framework_Prefix.pch
+ 	
+ $(OBJ)/%.m.o: %.m
+ 	-@$(MKDIR) -p $(dir $@)
+-	$(CC) $(CFLAGS) $(FRONTEND_CFLAGS) $(FAT_FLAGS) $(OCFLAGS) -c $< -o $@
+-    
++	$(LIBTOOL_CC) $(CFLAGS) $(FRONTEND_CFLAGS) $(FAT_FLAGS) $(OCFLAGS) -c $< -o $@
++
+ # iOS Port
+ 
+ $(BIN)/SameBoy-iOS.app: $(BIN)/SameBoy-iOS.app/SameBoy \
+@@ -653,15 +738,28 @@ libretro:
+ # Does not install mimetype icons because FreeDesktop is cursed abomination with no right to exist.
+ # If you somehow find a reasonable way to make associate an icon with an extension in this dumpster
+ # fire of a desktop environment, open an issue or a pull request
++# Install for Linux, and other FreeDesktop platforms.
++install_headers = install -Dm 644 -t $(DESTDIR)$(includedir)/sameboy $(INC)/*
++install_pkgconf_file = install -Dm 644 -t $(DESTDIR)$(libdir)/pkgconfig $(PKGCONF_FILE)
++
+ ifneq ($(FREEDESKTOP),)
+ ICON_NAMES := apps/sameboy mimetypes/x-gameboy-rom mimetypes/x-gameboy-color-rom
+ ICON_SIZES := 16x16 32x32 64x64 128x128 256x256 512x512
+ ICONS := $(foreach name,$(ICON_NAMES), $(foreach size,$(ICON_SIZES),$(DESTDIR)$(PREFIX)/share/icons/hicolor/$(size)/$(name).png))
++ifneq ($(LIBRARY),)
++install: lib pkgconf
++endif
++
+ install: sdl $(DESTDIR)$(PREFIX)/share/mime/packages/sameboy.xml $(ICONS) FreeDesktop/sameboy.desktop
+ 	-@$(MKDIR) -p $(dir $(DESTDIR)$(PREFIX))
+ 	mkdir -p $(DESTDIR)$(DATA_DIR)/ $(DESTDIR)$(PREFIX)/bin/
+ 	cp -rf $(BIN)/SDL/* $(DESTDIR)$(DATA_DIR)/
+ 	mv $(DESTDIR)$(DATA_DIR)/sameboy $(DESTDIR)$(PREFIX)/bin/sameboy
++ifneq ($(LIBRARY),)
++	$(install_headers)
++	$(install_pkgconf_file)
++	$(LIBTOOL) --mode=install install -D $(LIBTOOL_LIBRARY) $(libdir)/libsameboy.la
++endif
+ ifeq ($(DESTDIR),)
+ 	-update-mime-database -n $(PREFIX)/share/mime
+ 	-xdg-desktop-menu install --novendor --mode system FreeDesktop/sameboy.desktop
+@@ -727,20 +825,23 @@ $(OBJ)/control.tar.gz: iOS/deb-postinst iOS/deb-prerm iOS/deb-control
+ $(OBJ)/debian-binary:
+ 	-@$(MKDIR) -p $(dir $@)
+ 	echo 2.0 > $@
+-    
+-$(LIBDIR)/libsameboy.o: $(CORE_OBJECTS)
++
++# Link library objects with libtool.
++$(LIBTOOL_LIBRARY): $(CORE_LOBJECTS)
+ 	-@$(MKDIR) -p $(dir $@)
+-	@# This is a somewhat simple hack to force Clang and GCC to build a native object file out of one or many LTO objects
+-	echo "static const char __attribute__((used)) x=0;"| $(CC) $(filter-out -flto,$(CFLAGS)) -c -x c - -o $(OBJ)/lto_hack.o
+-	@# And this is a somewhat complicated hack to invoke the correct LTO-enabled LD command in a mostly cross-platform nature
+-	$(CC) $(FAT_FLAGS) $(CFLAGS) $(LIBFLAGS) $^ $(OBJ)/lto_hack.o -o $@
+-	-@rm $(OBJ)/lto_hack.o
+-    
+-$(LIBDIR)/libsameboy.a: $(LIBDIR)/libsameboy.o
++	$(LIBTOOL_LD) -rpath $(libdir) $^ -o $@
++
++$(PKGCONF_FILE): sameboy.pc.in
+ 	-@$(MKDIR) -p $(dir $@)
+ 	-@rm -f $@
+-	ar -crs $@ $^
+-	
++	sed -e 's,@prefix@,$(prefix),' \
++	 -e 's/@version@/$(VERSION)/' \
++	 -e 's,@exec_prefix@,$(PKGCONF_EXEC_PREFIX),' \
++	 -e 's,@includedir@,$(PKGCONF_INCLUDEDIR),' \
++	 -e 's,@libdir@,$(PKGCONF_LIBDIR),' $< > $@
++
++pkgconf: $(PKGCONF_FILE)
++
+ $(INC)/%.h: Core/%.h
+ 	-@$(MKDIR) -p $(dir $@)
+ 	-@# CPPP doesn't like multibyte characters, so we replace the single quote character before processing so it doesn't complain
+@@ -754,4 +855,4 @@ lib-unsupported:
+ clean:
+ 	rm -rf build
+ 
+-.PHONY: libretro tester cocoa ios _ios ios-ipa ios-deb liblib-unsupported bootroms
++.PHONY: libretro tester cocoa ios _ios ios-ipa ios-deb lib lib-unsupported bootroms pkgconf
+diff --git a/README.md b/README.md
+index 9c5f8da..e23f2ca 100644
+--- a/README.md
++++ b/README.md
+@@ -53,12 +53,18 @@ On Windows, SameBoy also requires:
+ To compile, simply run `make`. The targets are:
+  * `cocoa` (Default for macOS)
+  * `sdl` (Default for everything else)
+- * `lib` (Creates libsameboy.o and libsameboy.a for statically linking SameBoy, as well as a headers directory with corresponding headers; currently not supported on Windows due to linker limitations)
++ * `lib` (Creates libsameboy.o, libsameboy.a and libsameboy.so for linking SameBoy, as well as a headers directory with corresponding headers; currently not supported on Windows due to linker limitations)
+  * `ios` (Plain iOS .app bundle), `ios-ipa` (iOS IPA archive for side-loading), `ios-deb` (iOS deb package for jailbroken devices)
+  * `libretro`
+  * `bootroms`
+  * `tester` 
+ 
++For convenience, when installing the static and shared libraries is
++desired, you can specify the LIBRARY=1 make variable to have the
++libraries built as part of the default target, as well as installed,
++along the headers. Alternatively, `LIBRARY=shared` will install just
++the shared library, while `LIBRARY=static` only the static one.
++
+ You may also specify `CONF=debug` (default), `CONF=release`, `CONF=native_release` or `CONF=fat_release`  to control optimization, symbols and multi-architectures. `native_release` is faster than `release`, but is optimized to the host's CPU and therefore is not portable. `fat_release` is exclusive to macOS and builds x86-64 and ARM64 fat binaries; this requires using a recent enough `clang` and macOS SDK using `xcode-select`, or setting them explicitly with `CC=` and `SYSROOT=`, respectively. All other configurations will build to your host architecture, except for the iOS targets. You may set `BOOTROMS_DIR=...` to a directory containing precompiled boot ROM files, otherwise the build system will compile and use SameBoy's own boot ROMs.
+ 
+ The SDL port will look for resource files with a path relative to executable and inside the directory specified by the `DATA_DIR` variable. If you are packaging SameBoy, you may wish to override this by setting the `DATA_DIR` variable during compilation to the target path of the directory containing all files (apart from the executable, that's not necessary) from the `build/bin/SDL` directory in the source tree. Make sure the variable ends with a `/` character. On FreeDesktop environments, `DATA_DIR` will default to `/usr/local/share/sameboy/`. `PREFIX` and `DESTDIR` follow their standard usage and default to an empty string an `/usr/local`, respectively
+diff --git a/sameboy.pc.in b/sameboy.pc.in
+new file mode 100644
+index 0000000..dc0ca0b
+--- /dev/null
++++ b/sameboy.pc.in
+@@ -0,0 +1,10 @@
++prefix=@prefix@
++exec_prefix=@exec_prefix@
++includedir=@includedir@
++libdir=@libdir@
++
++Name: sameboy
++Description: The SameBoy library
++Version: @version@
++Cflags: -I${includedir}/sameboy
++Libs: -L${libdir} -lsameboy
-- 
2.46.0