Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

berkeley-db: Build db_dump185 compatibility util #191419

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions Formula/b/berkeley-db.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,19 @@ class BerkeleyDb < Formula

depends_on "openssl@3"

on_linux do
resource "libdb1.85" do
# NOTE: Debian's source version reflects Glib's version, not libdb1's version
# It also fixes security bug: https://insecure.org/sploits/libdb.snprintf.redefine.html
url "http://deb.debian.org/debian/pool/main/d/db1-compat/db1-compat_2.1.3.orig.tar.gz"
sha256 "b01f560f00a67f921e678586d903969015b0c9cec6c18b1679b7e9fd6d27394e"
end
resource "libdb1.85-patches" do
url "http://deb.debian.org/debian/pool/main/d/db1-compat/db1-compat_2.1.3-25.debian.tar.xz"
sha256 "5c3773cf41105ccbe9d07d42b90013e40ab09b8f615d5cecbac298aa72cbb9db"
end
end

# Fix -flat_namespace being used on Big Sur and later.
patch do
url "https://raw.githubusercontent.com/Homebrew/formula-patches/03cf8088210822aa2c1ab544ed58ea04c897d9c4/libtool/configure-pre-0.4.2.418-big_sur.diff"
Expand All @@ -39,19 +52,50 @@ class BerkeleyDb < Formula
def install
# Work around undefined NULL causing incorrect detection of thread local storage class
ENV.append "CFLAGS", "-include stddef.h" if DevelopmentTools.clang_build_version >= 1500
ENV.append "CFLAGS", "-Wno-error=implicit-function-declaration" if DevelopmentTools.clang_build_version >= 1200

# BerkeleyDB dislikes parallel builds
ENV.deparallelize

# db_dump185 needs libdb 1.85 on Linux only (macOS & BSD variants already have it)
if OS.linux?
resource("libdb1.85").stage do
libdb1_src_path = Pathname(Utils.safe_popen_read("pwd").chomp).realpath

resource("libdb1.85-patches").stage do
File.read("patches/series").each_line do |p|
# Omit db_dump185.patch: it includes another version of the entire db_dump185 source code
# We will use the version included with Oracle upstream's source instead, and link against libdb1
# See build doc: Chapter 6. Building Berkeley DB for UNIX/POSIX - Architecture independent FAQ #8
# NOTE: PDF footer labeled p. 49, but URL page num differs
# https://www.oracle.com/technetwork/database/berkeleydb/bdb-installation-160957.pdf#page=66
next if p.match?(/^(db_dump185\.patch)/)

patch_fullpath = Pathname(File.join("patches", p.chomp)).realpath
cd libdb1_src_path do
system "patch", "-g", "0", "-f", "-p1", "-i", patch_fullpath
end
end
end
system "make"
include.install "db.h"
lib.install "libdb1.so.2"
ln_s "libdb1.so.2", lib/"libdb1.so"
end
end

# --enable-compat185 is necessary because our build shadows
# the system berkeley db 1.x
# --enable-dump185 Builds the db_dump185 utility, which can dump Berkeley DB 1.85 and 1.86 databases.
# See: https://docs.oracle.com/cd/E17275_01/html/programmer_reference/build_unix_conf.html#build_unix_conf
args = %W[
--disable-debug
--disable-static
--prefix=#{prefix}
--mandir=#{man}
--enable-cxx
--enable-compat185
--enable-dump185
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like a huge pain to install this on Linux. Can we just do it on macOS?

Copy link
Contributor Author

@trinitronx trinitronx Oct 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just do it on macOS?

Possibly, although then it would not be in feature parity with the already built macOS binaries. From time to time, I find myself on Linux needing some BSD-specific tool (or vice versa). The idea was to keep things working the same across different OS for a better user experience. A big plus!

Also, I did spend a few days doing all the hard work already. 😅 🤷

It seems like a huge pain to install this on Linux.

While it might seem like this at first glance, the simpler-looking alternatives were either not supported 1, or Debian-specific (and hiding complexity). Plus, I figured the policy for Linuxbrew would be to keep things building independently without tying into system dependencies on one distro or another.

This avoids locking to Debian build tools, which would have the usual simpler-looking apt-get build-dep ..., apt-get source ..., debuild method 2. Otherwise, just installing apt-get install libdb1-compat and building against system libs worked but then again only works on Debian-based distros and creates a build dependency on something outside Homebrew.

The usual method on Debian is to unpack the .orig.tar.gz and .debian.tar.xz files and just run debuild, which applies all the patches inside the unpacked debian/patches directory which came from the *.debian.tar.xz archive. We could have done that here with system commands and it would look cleaner, but then it would depend on Debian-specific build tools and increase the build dependencies needed.

Footnotes

  1. At first, I tried using patch with apply %W [ ... ] nested inside the resource block for the debian source code, simlar to how mytop does with a top-level .debian.tar.xz Formula patch. However, nesting this to patch another resource didn't appear to be supported in the current Ruby Formulary DSL. Also, patch only expected a single patch via URL or possibly more via :DATA with an embedded __END__ section. Although, using that wouldn't be ideal because all patches are already from upstream and we'd need to then duplicate & maintain them in this Formula to use :DATA. Although it didn't work, it would've looked much simpler if we could nest them like:

    resource 'foo' do
      url '... source code tar.gz ...'
      ...
      patch do
        url '... debian.tar.xz with patches inside ...'
    
        apply %W[ ... list of files in debian/patches to apply ... ]
      end
    end
    
  2. While this might look simple, it hides complexity and also yields more build dependencies. For example: debuild internally applies the debian/patches via quilt push -a, runs dpkg-buildpackage and more, hiding all the complexity inside one command. Yet, again this uses more Debian-specific packaging tools internally which increases the build dependency list and locks it into only working on Debian-based distros.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I appreciate that you've done a lot of work here, but keeping this around just isn't very maintainable. Sorry!

If you need db_dump185 on Linux, I suggest hosting a version of this formula in your own tap.

--enable-sql
--enable-sql_codegen
--enable-dbm
Expand All @@ -60,6 +104,12 @@ def install

# BerkeleyDB requires you to build everything from the build_unix subdirectory
cd "build_unix" do
if OS.linux?
args << "CPPFLAGS=-I#{include}"
db185_linkerflags = "-Xlinker '-L #{lib}' -Xlinker '-l db1'"
inreplace "../dist/Makefile.in", /^DB185LIB=.*/, "DB185LIB=#{db185_linkerflags}"
end

system "../dist/configure", *args
system "make", "install", "DOCLIST=license"

Expand Down
Loading