Merge pull request #243238 from OPNA2608/init/famistudio-source

famistudio: init source-built version
This commit is contained in:
Sandro 2024-03-30 14:17:40 +01:00 committed by GitHub
commit 3ea38d98b1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 190 additions and 46 deletions

View File

@ -0,0 +1,69 @@
{ depname
, version
, src
, sourceRoot
, stdenv
, lib
, patches ? []
, extraPostPatch ? ""
, buildInputs ? []
}:
let
rebuildscriptName = if stdenv.hostPlatform.isLinux then
"build_linux"
else if stdenv.hostPlatform.isDarwin then
"build_macos"
else throw "Don't know how to rebuild FamiStudio's vendored ${depname} for ${stdenv.hostPlatform.system}";
in
stdenv.mkDerivation {
pname = "famistudio-nativedep-${depname}";
inherit version src sourceRoot patches buildInputs;
postPatch = let
libnameBase = lib.optionalString stdenv.hostPlatform.isLinux "lib" + depname;
in ''
# Use one name for build script, eases with patching
mv ${rebuildscriptName}.sh build.sh
# Scripts use hardcoded compilers and try to copy built libraries into FamiStudio's build tree
# Not all scripts use the same compiler, so don't fail on replacing that
substituteInPlace build.sh \
--replace-fail '../../FamiStudio/' "$out/lib/" \
--replace-quiet 'g++' "$CXX"
# Replacing gcc via sed, would break -static-libgcc otherwise
sed -i -e "s/^gcc/$CC/g" build.sh
'' + lib.optionalString stdenv.hostPlatform.isDarwin ''
# Darwin rebuild scripts try to make a universal2 dylib
# - build dylib for non-hostPlatform
# - copy built library into special directory for later packaging script
# - join two dylibs together into a universal2 dylib
# Remove everything we don't need
sed -ri \
-e '/-target ${if stdenv.hostPlatform.isx86_64 then "arm64" else "x86_64"}/d' \
-e '/..\/..\/Setup/d' \
build.sh
# Replace joining multi-arch dylibs with copying dylib for target arch
substituteInPlace build.sh \
--replace-fail 'lipo -create -output ${libnameBase}.dylib' 'cp ${libnameBase}_${if stdenv.hostPlatform.isx86_64 then "x86_64" else "arm64"}.dylib ${libnameBase}.dylib #'
'' + extraPostPatch;
dontConfigure = true;
dontInstall = true; # rebuild script automatically installs
buildPhase = ''
runHook preBuild
mkdir -p $out/lib
# Delete all prebuilt libraries, make sure everything is rebuilt
find . -name '*.so' -or -name '*.dylib' -or -name '*.a' -delete
# When calling normally, an error won't cause derivation to fail
source ./build.sh
runHook postBuild
'';
}

View File

@ -1,59 +1,108 @@
{ lib
, stdenv
, fetchzip
, autoPatchelfHook
, dotnet-runtime
{ stdenv
, lib
, buildDotnetModule
, callPackage
, fetchFromGitHub
, ffmpeg
, libglvnd
, glfw
, libogg
, libvorbis
, makeWrapper
, openal
, portaudio
, rtmidi
}:
stdenv.mkDerivation rec {
let
csprojName = if stdenv.hostPlatform.isLinux then
"FamiStudio.Linux"
else if stdenv.hostPlatform.isDarwin then
"FamiStudio.Mac"
else throw "Don't know how to build FamiStudio for ${stdenv.hostPlatform.system}";
in
buildDotnetModule rec {
pname = "famistudio";
version = "4.1.3";
src = fetchzip {
url = "https://github.com/BleuBleu/FamiStudio/releases/download/${version}/FamiStudio${lib.strings.concatStrings (lib.splitVersion version)}-LinuxAMD64.zip";
stripRoot = false;
hash = "sha256-eAdv0oObczbs8QLGYbxCrdFk/gN5DOCJ1dp/tg8JWIc=";
src = fetchFromGitHub {
owner = "BleuBleu";
repo = "FamiStudio";
rev = "refs/tags/${version}";
hash = "sha256-bryxhminkrTVe5qhGeMStZp3NTHBREXrsUlyQkfPkao=";
};
strictDeps = true;
postPatch = let
libname = library: "${library}${stdenv.hostPlatform.extensions.sharedLibrary}";
buildNativeWrapper = args: callPackage ./build-native-wrapper.nix (args // {
inherit version src;
sourceRoot = "${src.name}/ThirdParty/${args.depname}";
});
nativeWrapperToReplaceFormat = args: let
libPrefix = lib.optionalString stdenv.hostPlatform.isLinux "lib";
in {
package = buildNativeWrapper args;
expectedName = "${libPrefix}${args.depname}";
ourName = "${libPrefix}${args.depname}";
};
librariesToReplace = [
# Unmodified native libraries that we can fully substitute
{ package = glfw; expectedName = "libglfw"; ourName = "libglfw"; }
{ package = rtmidi; expectedName = "librtmidi"; ourName = "librtmidi"; }
] ++ lib.optionals stdenv.hostPlatform.isLinux [
{ package = openal; expectedName = "libopenal32"; ourName = "libopenal"; }
] ++ lib.optionals stdenv.hostPlatform.isDarwin [
{ package = portaudio; expectedName = "libportaudio.2"; ourName = "libportaudio.2"; }
] ++ [
# Native libraries, with extra code for the C# wrapping
(nativeWrapperToReplaceFormat { depname = "GifDec"; })
(nativeWrapperToReplaceFormat { depname = "NesSndEmu"; })
(nativeWrapperToReplaceFormat { depname = "NotSoFatso"; extraPostPatch = ''
# C++17 does not allow register storage class specifier
substituteInPlace build.sh \
--replace-fail "$CXX" "$CXX -std=c++14"
''; })
(nativeWrapperToReplaceFormat { depname = "ShineMp3"; })
(nativeWrapperToReplaceFormat { depname = "Stb"; })
(nativeWrapperToReplaceFormat { depname = "Vorbis"; buildInputs = [ libogg libvorbis ]; })
];
libraryReplaceArgs = lib.strings.concatMapStringsSep " "
(library: "--replace-fail '${libname library.expectedName}' '${lib.getLib library.package}/lib/${libname library.ourName}'")
librariesToReplace;
in ''
# Don't use any prebuilt libraries
rm FamiStudio/*.{dll,dylib,so*}
nativeBuildInputs = [
autoPatchelfHook
makeWrapper
];
# Replace copying of vendored prebuilt native libraries with copying of our native libraries
substituteInPlace ${projectFile} ${libraryReplaceArgs}
buildInputs = [
dotnet-runtime
ffmpeg
libglvnd
openal
];
# Un-hardcode target platform if set
sed -i -e '/PlatformTarget/d' ${projectFile}
dontConfigure = true;
dontBuild = true;
installPhase = ''
runHook preInstall
mkdir -p $out/{bin,lib/famistudio}
mv * $out/lib/famistudio
makeWrapper ${lib.getExe dotnet-runtime} $out/bin/famistudio \
--add-flags $out/lib/famistudio/FamiStudio.dll \
--prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath [ libglvnd ]} \
--prefix PATH : ${lib.makeBinPath [ ffmpeg ]}
# Bundled openal lib freezes the application
rm $out/lib/famistudio/libopenal32.so
ln -s ${openal}/lib/libopenal.so $out/lib/famistudio/libopenal32.so
runHook postInstall
# Don't require a special name to be preserved, our OpenAL isn't 32-bit
substituteInPlace FamiStudio/Source/AudioStreams/OpenALStream.cs \
--replace-fail 'libopenal32' 'libopenal'
'';
projectFile = "FamiStudio/${csprojName}.csproj";
nugetDeps = ./deps.nix;
executables = [ "FamiStudio" ];
postInstall = ''
mkdir -p $out/share/famistudio
for datdir in Setup/Demo\ {Instruments,Songs}; do
cp -R "$datdir" $out/share/famistudio/
done
'';
postFixup = ''
# FFMpeg looked up from PATH
wrapProgram $out/bin/FamiStudio \
--prefix PATH : ${lib.makeBinPath [ ffmpeg ]}
'';
passthru.updateScript = ./update.sh;
meta = with lib; {
homepage = "https://famistudio.org/";
description = "NES Music Editor";
@ -62,10 +111,8 @@ stdenv.mkDerivation rec {
or Famicom. It is targeted at both chiptune artists and NES homebrewers.
'';
license = licenses.mit;
# Maybe possible to build from source but I'm not too familiar with C# packaging
sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ];
maintainers = with maintainers; [ OPNA2608 ];
platforms = [ "x86_64-linux" ];
mainProgram = "famistudio";
platforms = platforms.unix;
mainProgram = "FamiStudio";
};
}

View File

@ -0,0 +1,5 @@
# This file was automatically generated by passthru.fetch-deps.
# Please dont edit it manually, your changes might get overwritten!
{ fetchNuGet }: [
]

View File

@ -0,0 +1,23 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p curl jq common-updater-scripts
set -eo pipefail
cd "$(dirname "${BASH_SOURCE[0]}")"
deps_file="$(realpath "./deps.nix")"
new_version="$(curl ${GITHUB_TOKEN:+-u ":$GITHUB_TOKEN"} \
-s "https://api.github.com/repos/BleuBleu/FamiStudio/releases?per_page=1" | jq -r '.[0].tag_name')"
old_version="$(sed -nE 's/\s*version = "(.*)".*/\1/p' ./default.nix)"
if [[ "$new_version" == "$old_version" ]]; then
echo "Up to date"
exit 0
fi
cd ../../../..
if [[ "$1" != "--deps-only" ]]; then
update-source-version famistudio "$new_version"
fi
$(nix-build . -A famistudio.fetch-deps --no-out-link) "$deps_file"

View File

@ -30979,7 +30979,7 @@ with pkgs;
faircamp = callPackage ../applications/misc/faircamp { };
famistudio = callPackage ../applications/audio/famistudio { };
famistudio = darwin.apple_sdk_11_0.callPackage ../applications/audio/famistudio { };
fasttext = callPackage ../applications/science/machine-learning/fasttext { };