Hello,
This is the first time I write a derivation for a package. My host system is Manjaro.
I created a derivation for “Parallel Launcher” (https://parallel-launcher.ca/), which launches N64 emulators, but joystick detection doesn’t work. In the joystick configuration dialog (GUI), there’s a red text saying “Input driver failed to initialize due to an unexpected error”.
You can try it yourself, this is my current derivation.nix
for Parallel-Launcher:
{ pkgs, stdenv, fetchFromGitLab, lib }:
stdenv.mkDerivation rec {
name = "parallel-launcher";
version = "7.6.0";
meta = {
description = "A simple easy-to-use launcher for the ParallelN64 emulator";
homepage = "https://parallel-launcher.ca";
license = lib.licenses.gpl3Only;
platforms = [ "x86_64-linux" ];
};
src = fetchFromGitLab {
owner = "parallel-launcher";
repo = "parallel-launcher";
rev = "v7.6-0";
hash = "sha256-slIfZ4/3hGCvKH2HtlsrYWO9h5YQ+er4MBj2nr468R0=";
};
nativeBuildInputs = [
pkgs.gnumake
pkgs.qt5.qtdeclarative
pkgs.qt5.qttools
pkgs.qt5.wrapQtAppsHook
pkgs.qt5.qtbase
];
buildInputs = [
pkgs.qt5.qtbase
pkgs.qt5.qtsvg
pkgs.findutils
pkgs.xdg-utils
pkgs.SDL2
pkgs.polkit
pkgs.sqlite
pkgs.libgcrypt
pkgs.dosfstools
pkgs.coreutils
pkgs.p7zip
];
#optdepends=(
# 'noto-fonts: intended font'
# 'udisks2: mounting emulated SD cards'
#)
buildPhase = ''
./qmake-release.sh
make -j $NIX_BUILD_CORES
'';
installPhase = ''
mkdir -p $out/bin
mkdir -p $out/share/applications
mkdir -p $out/share/metainfo
mkdir -p $out/share/icons/hicolor/scalable/apps
mkdir -p $out/share/parallel-launcher
cp parallel-launcher $out/bin/
cp ca.parallel_launcher.ParallelLauncher.desktop $out/share/applications/
cp ca.parallel_launcher.ParallelLauncher.metainfo.xml $out/share/metainfo/
cp data/appicon.svg $out/share/icons/hicolor/scalable/apps/ca.parallel_launcher.ParallelLauncher.svg
cp bps-mime.xml $out/share/parallel-launcher/
cp lang/* $out/share/parallel-launcher/
cp parallel-launcher-sdl-relay $out/share/parallel-launcher/
cp parallel-launcher-lsjs $out/share/parallel-launcher/
'';
}
When I click on the top right controller icon, with the SDL2 input driver selected, I see a red “Input driver failed to initialize” error.
My first guess was that SDL2 joystick detection doesn’t work. The package even has a small separate SDL2 joystick detection executable, it’s just a few lines of C code. When I compiled that on my Manjaro host system (without nix), it works fine and prints the GUID of both my XBox360 controller and a GameCube controller connected via a Mayflash adapter connected to my system which uses a custom udev rule. But when I compile it with nix-build, it only prints a GUID when my XBox360 controller is connected, and that GUID is different than the two previous GUIDs. Not sure where to go from here.
If you want to toy with the SDL2 controller detection alone, here’s the joystick detection C code:
// src/main.cpp
#include <SDL2/SDL.h>
#include <stdio.h>
typedef unsigned char ubyte;
static void writeHex( char *out, const ubyte *data, size_t numBytes ) {
for( size_t i = 0; i < numBytes; i++ ) {
const ubyte upperNibble = data[i] >> 4;
const ubyte lowerNibble = data[i] & 0xF;
out[i*2] = upperNibble + (upperNibble > 9 ? ('a' - (char)10) : '0');
out[i*2+1] = lowerNibble + (lowerNibble > 9 ? ('a' - (char)10) : '0');
}
}
static inline void writeUuid( const ubyte *data, char *buffer ) {
writeHex( buffer, data, 4 );
writeHex( &buffer[9], &data[4], 2 );
writeHex( &buffer[14], &data[6], 2 );
writeHex( &buffer[19], &data[8], 2 );
writeHex( &buffer[24], &data[10], 6 );
}
int main( int argc, char *argv[] ) {
SDL_Init( SDL_INIT_JOYSTICK );
SDL_JoystickUpdate();
char uuid[37] = "00000000-0000-0000-0000-000000000000";
const int numConnected = SDL_NumJoysticks();
for( int i = 0; i < numConnected; i++ ) {
writeUuid( SDL_JoystickGetDeviceGUID( i ).data, uuid );
printf( "%s\n", uuid );
}
SDL_Quit();
return 0;
}
and here’s the corresponding default.nix
build file, placed in the same directory where the “src” folder lives:
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "sdl-sample";
src = ./src;
buildInputs = [ SDL2 ];
buildPhase = "c++ -o main main.cpp -lSDL2";
installPhase = ''
mkdir -p $out/bin
cp main $out/bin/
'';
}
Then run nix-build
and run ./result/bin/main
to print the GUIDs of the connected controllers found by SDL2.