Unverified Commit de8b8195 authored by Niklas Korz's avatar Niklas Korz Committed by GitHub
Browse files

wesnoth: fix darwin and LLVM 19 compatibility (#381227)

parents 65a96506 87efe407
Loading
Loading
Loading
Loading
+78 −8
Original line number Diff line number Diff line
{
  lib,
  stdenv,
  stdenvNoCC,
  fetchFromGitHub,
  cmake,
  pkg-config,
@@ -21,19 +22,48 @@
  icu,
  lua,
  curl,
  fetchpatch,
  nix-update-script,
}:

stdenv.mkDerivation rec {
stdenv.mkDerivation (finalAttrs: {
  pname = "wesnoth";
  version = "1.18.4";

  src = fetchFromGitHub {
    rev = version;
    owner = "wesnoth";
    repo = "wesnoth";
    tag = finalAttrs.version;
    hash = "sha256-c3BoTFnSUqtp71QeSCsC2teVuzsQwV8hOJtIcZdP+1E=";
  };

  # LLVM 19 removed support for types not officially supported by `std::char_traits`:
  # https://libcxx.llvm.org/ReleaseNotes/19.html#deprecations-and-removals
  # Wesnoth <1.19 relies on this previously supported non-standard behavior for
  # some types that should either have been a vector or span:
  # https://github.com/wesnoth/wesnoth/issues/9546
  # Wesnoth moved to a `std::span` wrapper for byte views in the 1.19 branch, which we apply as
  # patches until 1.20 is released.
  patches = lib.optionals (stdenv.cc.isClang && lib.versionAtLeast stdenv.cc.version "19") [
    # The next two patches are cherry-picked from https://github.com/wesnoth/wesnoth/pull/10102,
    # which is already included in the 1.19 branch.
    # Introduces the `std::span` wrapper based on `boost::span`.
    (fetchpatch {
      url = "https://github.com/wesnoth/wesnoth/commit/63266cc2c88fefa7e0792ac59d14c14e3711440c.patch";
      hash = "sha256-3Zi/njG7Kovmyd7yiKUoeu4u0QPQxxw+uLz+k9isOLU=";
    })
    # Replace all string views with spans.
    (fetchpatch {
      url = "https://github.com/wesnoth/wesnoth/commit/d3daa161eb2c02670b5ffbcf86cd0ec787f6b9ee.patch";
      hash = "sha256-9DCeZQZKE6fN91T5DCpNJsKGXbv5ihZC8UpuNkiA9zc=";
    })
    # Wesnoth <1.19 uses `std::basic_string` for lightmap computations, which is not standard compliant
    # and incompatible to LLVM 19.
    # While this was fixed in https://github.com/wesnoth/wesnoth/pull/10128, the fix is not
    # trivially backportable to 1.18 so we apply a simpler fix instead.
    ./llvm19-lightmap.patch
  ];

  nativeBuildInputs = [
    cmake
    pkg-config
@@ -63,9 +93,45 @@ stdenv.mkDerivation rec {
    "-DENABLE_SYSTEM_LUA=ON"
  ];

  NIX_LDFLAGS = lib.optionalString stdenv.hostPlatform.isDarwin "-framework AppKit";
  postInstall = lib.optionalString stdenv.hostPlatform.isDarwin ''
    app_name="The Battle for Wesnoth"
    app_bundle="$out/Applications/$app_name.app"
    app_contents="$app_bundle/Contents"
    mkdir -p "$app_contents"
    echo "APPL????" > "$app_contents/PkgInfo"
    mv $out/bin "$app_contents/MacOS"
    mv $out/share/wesnoth "$app_contents/Resources"
    pushd ../projectfiles/Xcode
    substitute Info.plist "$app_contents/Info.plist" \
      --replace-fail ''\'''${EXECUTABLE_NAME}' wesnoth \
      --replace-fail '$(PRODUCT_BUNDLE_IDENTIFIER)' org.wesnoth.Wesnoth \
      --replace-fail ''\'''${PRODUCT_NAME}' "$app_name"
    cp -r Resources/SDLMain.nib "$app_contents/Resources/"
    install -m0644 Resources/{container-migration.plist,icon.icns} "$app_contents/Resources"
    popd

    # Make the game and dedicated server binary available for shell users
    mkdir -p "$out/bin"
    ln -s "$app_contents/MacOS/wesnothd" "$out/bin/wesnothd"
    # Symlinking the game binary is unsifficient as it would be unable to
    # find the bundle resources
    cat << EOF > "$out/bin/wesnoth"
    #!${stdenvNoCC.shell}
    open -na "$app_bundle" --args "\$@"
    EOF
    chmod +x "$out/bin/wesnoth"
  '';

  passthru.updateScript = nix-update-script {
    extraArgs = [
      "--version-regex"
      # the minor release number also denotes if this is a beta release:
      # even is stable, odd is beta
      "^(\\d+\\.\\d*[02468]\\.\\d+)$"
    ];
  };

  meta = with lib; {
  meta = {
    description = "Battle for Wesnoth, a free, turn-based strategy game with a fantasy theme";
    longDescription = ''
      The Battle for Wesnoth is a Free, turn-based tactical strategy
@@ -76,8 +142,12 @@ stdenv.mkDerivation rec {
    '';

    homepage = "https://www.wesnoth.org/";
    license = licenses.gpl2Plus;
    maintainers = with maintainers; [ abbradar ];
    platforms = platforms.unix;
    license = lib.licenses.gpl2Plus;
    maintainers = with lib.maintainers; [
      abbradar
      niklaskorz
    ];
    platforms = lib.platforms.unix;
    mainProgram = "wesnoth";
  };
}
})
+59 −0
Original line number Diff line number Diff line
diff --git a/src/display.cpp b/src/display.cpp
index 0f6552222b7..9d50046de2f 100644
--- a/src/display.cpp
+++ b/src/display.cpp
@@ -1082,7 +1082,8 @@ void display::get_terrain_images(const map_location& loc, const std::string& tim

 		// add the directional transitions
 		tod_color acol = atod1.color + color_adjust_;
-		lt += image::get_light_string(d + 1, acol.r, acol.g, acol.b);
+		auto new_lt = image::get_light_string(d + 1, acol.r, acol.g, acol.b);
+		lt.insert(lt.end(), new_lt.begin(), new_lt.end());
 	}

 	for(int d = 0; d < 6; ++d) {
@@ -1114,7 +1115,8 @@ void display::get_terrain_images(const map_location& loc, const std::string& tim

 		// add the directional transitions
 		tod_color acol = atod1.color + color_adjust_;
-		lt += image::get_light_string(d + 7, acol.r, acol.g, acol.b);
+		auto new_lt = image::get_light_string(d + 7, acol.r, acol.g, acol.b);
+		lt.insert(lt.end(), new_lt.begin(), new_lt.end());
 	}

 	for(int d = 0; d < 6; ++d) {
@@ -1146,7 +1148,8 @@ void display::get_terrain_images(const map_location& loc, const std::string& tim

 		// add the directional transitions
 		tod_color acol = atod2.color + color_adjust_;
-		lt += image::get_light_string(d + 13, acol.r, acol.g, acol.b);
+		auto new_lt = image::get_light_string(d + 13, acol.r, acol.g, acol.b);
+		lt.insert(lt.end(), new_lt.begin(), new_lt.end());
 	}

 	if(lt.empty()){
diff --git a/src/picture.cpp b/src/picture.cpp
index e7aeddaa821..5ad1ebcbcbc 100644
--- a/src/picture.cpp
+++ b/src/picture.cpp
@@ -526,7 +526,9 @@ static surface apply_light(surface surf, const light_string& ls)

 		// decompose into atomic lightmap operations (4 chars)
 		for(std::size_t c = 0; c + 3 < ls.size(); c += 4) {
-			light_string sls = ls.substr(c, 4);
+			auto start = ls.begin() + c;
+			auto end = start + 4;
+			light_string sls(start, end);

 			// get the corresponding image and apply the lightmap operation to it
 			// This allows to also cache lightmap parts.
diff --git a/src/picture.hpp b/src/picture.hpp
index 85a3b3a15a1..a26e1e27bc7 100644
--- a/src/picture.hpp
+++ b/src/picture.hpp
@@ -120,7 +120,7 @@ std::ostream& operator<<(std::ostream&, const locator&);
  *  7-12: convex half-corners 1
  * 13-19: convex half-corners 2
  */
-typedef std::basic_string<signed char> light_string;
+typedef std::vector<signed char> light_string;