about summary refs log tree commit diff
path: root/pkgs/games
diff options
context:
space:
mode:
authoraszlig <aszlig@nix.build>2020-07-01 06:07:09 +0200
committeraszlig <aszlig@nix.build>2020-07-12 20:26:03 +0200
commitdd25608bfa723ba979504234dd689e502c52fcd3 (patch)
treed26203ff90652f19aaefa874243a2bee1cf6b310 /pkgs/games
parent522a2a65c3758e9953c883f2b99e251d26d9f039 (diff)
games/gog: Add Baldur's Gate I and II
Both are the enhanced edition from GOG. Packaging is mostly
straightforward, although I had to use patchelf with a custom patch,
since while --remove-needed removes the DT_NEEDED entries from the ELF
it doesn't however remove the corresponding entries in the
.gnu.version_r section.

The reason why I did this is because we really should not need Expat and
OpenSSL, because they're only used by the XMPP portions of the
statically linked libjingle.

Signed-off-by: aszlig <aszlig@nix.build>
Diffstat (limited to 'pkgs/games')
-rw-r--r--pkgs/games/gog/baldurs-gate/default.nix78
-rw-r--r--pkgs/games/gog/baldurs-gate/patchelf-remove-verneed.patch53
-rw-r--r--pkgs/games/gog/default.nix2
3 files changed, 133 insertions, 0 deletions
diff --git a/pkgs/games/gog/baldurs-gate/default.nix b/pkgs/games/gog/baldurs-gate/default.nix
new file mode 100644
index 00000000..938d1b57
--- /dev/null
+++ b/pkgs/games/gog/baldurs-gate/default.nix
@@ -0,0 +1,78 @@
+{ stdenv, lib, fetchFromGitHub, autoreconfHook
+, buildGame, makeWrapper, fetchGog, openal, libGL
+}:
+
+let
+  patchelf = stdenv.mkDerivation {
+    pname = "patchelf";
+    version = "2020-06-23";
+
+    src = fetchFromGitHub {
+      owner = "NixOS";
+      repo = "patchelf";
+      rev = "e61654be0acf4454ab070a8c8e1345aa7d5b3d74";
+      sha256 = "1bfr6303i0hii8s86kj2j8dhi97abgancb08xpvfx2dh6608kcr0";
+    };
+
+    patches = [ ./patchelf-remove-verneed.patch ];
+    nativeBuildInputs = [ autoreconfHook ];
+  };
+
+  mkBaldursGate = { pname, version, src, executable }: buildGame rec {
+    name = "${pname}-${version}";
+    inherit pname version src;
+
+    nativeBuildInputs = [ makeWrapper ];
+    buildInputs = [ openal libGL ];
+    execName = executable + lib.optionalString stdenv.is64bit "64";
+
+    # The game uses libjingle for NAT traversal only, so let's remove the
+    # XMPP-related libraries since all we should need here is STUN/TURN
+    # support.
+    buildPhase = ''
+      ${patchelf}/bin/patchelf \
+        --remove-needed libcrypto.so.1.0.0 \
+        --remove-needed libssl.so.1.0.0 \
+        --remove-needed libexpat.so.1 \
+        "$execName"
+    '';
+
+    installPhase = ''
+      install -vD "$execName" "$out/libexec/$pname/$pname"
+      install -vD -m 0644 engine.lua "$out/share/$pname/engine.lua"
+      install -vD -m 0644 chitin.key "$out/share/$pname/chitin.key"
+      cp -rt "$out/share/$pname" data lang movies music scripts
+      makeWrapper "$out/libexec/$pname/$pname" "$out/bin/$pname" \
+        --run "cd '$out/share/$pname'"
+    '';
+
+    # Allow access to both data dirs to allow export/import of characters.
+    sandbox.paths.required = [
+      "$XDG_DATA_HOME/Baldur's Gate - Enhanced Edition"
+      "$XDG_DATA_HOME/Baldur's Gate II - Enhanced Edition"
+    ];
+  };
+
+in {
+  bg1ee = mkBaldursGate {
+    pname = "baldurs-gate";
+    version = "2.5.23121";
+    executable = "BaldursGate";
+
+    src = fetchGog {
+      productId = 1207666353;
+      sha256 = "0r8d4pc7rszkgw0wwfvzvng48hc0915qz6vw3hpkhrffccsl9bc0";
+    };
+  };
+
+  bg2ee = mkBaldursGate {
+    pname = "baldurs-gate-2";
+    version = "2.5.21851";
+    executable = "BaldursGateII";
+
+    src = fetchGog {
+      productId = 1207666373;
+      sha256 = "0l4rbc1zbhasnkbfcspbjb8vwsw574ld2aw6x9gk9bdbr8rz0fik";
+    };
+  };
+}
diff --git a/pkgs/games/gog/baldurs-gate/patchelf-remove-verneed.patch b/pkgs/games/gog/baldurs-gate/patchelf-remove-verneed.patch
new file mode 100644
index 00000000..31db58b2
--- /dev/null
+++ b/pkgs/games/gog/baldurs-gate/patchelf-remove-verneed.patch
@@ -0,0 +1,53 @@
+diff --git a/src/patchelf.cc b/src/patchelf.cc
+index ea6c6c0..d2d7d3b 100644
+--- a/src/patchelf.cc
++++ b/src/patchelf.cc
+@@ -1344,6 +1344,8 @@ void ElfFile<ElfFileParamNames>::removeNeeded(const std::set<std::string> & libs
+     auto shdrDynStr = findSection(".dynstr");
+     char * strTab = (char *) contents + rdi(shdrDynStr.sh_offset);
+ 
++    unsigned int verNeedNum = 0;
++
+     Elf_Dyn * dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic.sh_offset));
+     Elf_Dyn * last = dyn;
+     for ( ; rdi(dyn->d_tag) != DT_NULL; dyn++) {
+@@ -1358,9 +1360,39 @@ void ElfFile<ElfFileParamNames>::removeNeeded(const std::set<std::string> & libs
+             }
+         } else
+             *last++ = *dyn;
++
++        if (rdi(dyn->d_tag) == DT_VERNEEDNUM)
++            verNeedNum = rdi(dyn->d_un.d_val);
+     }
+ 
+     memset(last, 0, sizeof(Elf_Dyn) * (dyn - last));
++
++    if (verNeedNum) {
++        auto shdrVersionR = findSection(".gnu.version_r");
++        Elf_Shdr & shdrVersionRStrings = shdrs[rdi(shdrVersionR.sh_link)];
++        char * verStrTab = (char *) contents + rdi(shdrVersionRStrings.sh_offset);
++        std::string versionRStringsSName = getSectionName(shdrVersionRStrings);
++
++        debug("found .gnu.version_r with %i entries, strings in %s\n", verNeedNum, versionRStringsSName.c_str());
++
++        Elf_Verneed * need = (Elf_Verneed *) (contents + rdi(shdrVersionR.sh_offset));
++        Elf_Verneed * last = need;
++
++        while (verNeedNum > 0) {
++            char * file = verStrTab + rdi(need->vn_file);
++
++            if (libs.find(file) != libs.end()) {
++                debug("removing .gnu.version_r entry for '%s'\n", file);
++                // Relative offset, so all we need to do here is punch a hole.
++                last->vn_next += need->vn_next;
++                changed = true;
++            }
++
++            last = need;
++            need = (Elf_Verneed *) (((char *) need) + rdi(need->vn_next));
++            --verNeedNum;
++        }
++    }
+ }
+ 
+ template<ElfFileParams>
diff --git a/pkgs/games/gog/default.nix b/pkgs/games/gog/default.nix
index 91c06b2d..a651c86d 100644
--- a/pkgs/games/gog/default.nix
+++ b/pkgs/games/gog/default.nix
@@ -12,6 +12,8 @@ let
     };
 
     albion = callPackage_i686 ./albion {};
+    baldurs-gate = (callPackage ./baldurs-gate {}).bg1ee;
+    baldurs-gate-2 = (callPackage ./baldurs-gate {}).bg2ee;
     crosscode = callPackage ./crosscode.nix {};
     dungeons3 = callPackage ./dungeons3.nix {};
     epistory = callPackage ./epistory.nix { };