diff mbox series

[bug#73754,4/5] gnu: sameboy: Install shared library.

Message ID 25b9dd5fed046089943709a16ba7aae93b7fd911.1728684335.git.maxim.cournoyer@gmail.com
State New
Headers show
Series Unbundle SameBoy from jg-bsnes. | expand

Commit Message

Maxim Cournoyer Oct. 12, 2024, 4:28 a.m. UTC
* 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

Comments

Maxim Cournoyer Oct. 19, 2024, 2:02 p.m. UTC | #1
Hey,

Maxim Cournoyer <maxim.cournoyer@gmail.com> writes:

> * 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.

This revision uses libtool directly in the makefile rules to generate
shared library.  While it works, it's been pointed to me there are
issues doing that, namely that libtool bakes its CC internally and thus
CC can't be changed later, and cross-compilation is probably broken as
well.

The usual solution to this is to use Autotools, but I'll see if the
libtool problems can't be fixed at its level first.  It's going to need
some time, so consider this series on hold from that effort.
diff mbox series

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