2024-02-03 23:58:41 +00:00
# koreader's native build process
# 1. git clone each dependency lib into base/thirdparty/$lib
# 2. git checkout a specific rev into base/thirdparty/$lib/build/$platform
# 3. invoke cmake in the checkout dir (including `make install` equivalent), which seems to not write outside the dir
# 4. manually copy the "installed" files in that checkout to some other place for koreader to use
# - see: koreader/base/Makefile.third
# ...
# koreader and all its deps are installed to $out/lib/koreader
# - i.e. it vendors its runtime deps
#
# there's probably a simpler implementation of this which just coverrides the rules defined in koreader/base/Makefile.third.
# - maybe, even, if we just satisfy the rules there (i.e. drop our files directly to the output which the Makefile rule would otherwise produce), then all's good?
2023-10-27 11:37:40 +00:00
{ lib
, autoPatchelfHook
2023-07-19 09:51:35 +00:00
, autoconf
, automake
2023-07-21 04:20:33 +00:00
, buildPackages
2024-02-03 23:58:41 +00:00
, callPackage
2023-07-19 06:45:40 +00:00
, cmake
2023-10-27 11:37:40 +00:00
, dpkg
2023-07-18 23:05:26 +00:00
, fetchFromGitHub
2023-07-21 07:59:46 +00:00
, fetchgit
, fetchurl
2023-07-22 09:32:15 +00:00
, gettext
2023-10-27 11:37:40 +00:00
, git
, libtool
2023-07-18 23:05:26 +00:00
, luajit
2023-10-27 11:37:40 +00:00
, makeWrapper
2023-07-21 04:20:33 +00:00
, perl
2023-07-19 23:49:11 +00:00
, pkg-config
2023-10-27 11:37:40 +00:00
, pkgs
2023-07-21 09:15:03 +00:00
, python3
2023-07-20 10:45:44 +00:00
, ragel
2023-07-19 06:45:40 +00:00
, SDL2
2023-10-27 11:37:40 +00:00
, stdenv
2023-07-19 10:15:07 +00:00
, substituteAll
2023-07-19 23:49:11 +00:00
, which
2023-07-19 06:45:40 +00:00
} :
2023-07-18 23:05:26 +00:00
let
2024-02-03 23:58:41 +00:00
sources = callPackage ./sources.nix { luajit = luajit52 ; } ;
2023-11-19 23:04:39 +00:00
version = " 2 0 2 3 . 1 0 " ;
2023-10-27 11:37:40 +00:00
src = fetchFromGitHub {
owner = " k o r e a d e r " ;
repo = " k o r e a d e r " ;
name = " k o r e a d e r " ; # needed because `srcs = ` in the outer derivation is a list
fetchSubmodules = true ;
2023-11-19 23:04:39 +00:00
rev = " v ${ version } " ;
hash = " s h a 2 5 6 - J 8 W N S k h P O 0 Y + m / h 2 4 6 w 1 G p o w O V R O O H V b m u D H F A n i I t k = " ;
2023-10-27 11:37:40 +00:00
} ;
# XXX: for some inscrutable reason, `enable52Compat` is *partially* broken, only when cross compiling.
# `table.unpack` is non-nil, but `table.pack` is nil.
# the normal path is for `enable52Compat` to set `env.NIX_CFLAGS_COMPILE = "-DLUAJIT_ENABLE_LUA52COMPAT";`
# which in turn sets `#define LJ_52 1`, and gates functions like `table.pack`, `table.unpack`.
# instead, koreader just removes the `#if LJ_52` gates. doing the same in nixpkgs seems to work.
# luajit52 = luajit.override { enable52Compat = true; self = luajit52; };
luajit52 = ( luajit . override { self = luajit52 ; } ) . overrideAttrs ( super : {
patches = ( super . patches or [ ] ) ++ [
" ${ src } / b a s e / t h i r d p a r t y / l u a j i t / k o r e a d e r - l u a j i t - e n a b l e - t a b l e _ p a c k . p a t c h "
] ;
} ) ;
2023-07-22 08:44:11 +00:00
luaEnv = luajit52 . withPackages ( ps : with ps ; [
2023-07-21 07:59:46 +00:00
( buildLuarocksPackage {
pname = " l u a j s o n " ;
version = " 1 . 3 . 4 - 1 " ;
src = fetchgit {
url = " h t t p s : / / g i t h u b . c o m / h a r n i n g t / l u a j s o n . g i t " ;
rev = " 1 . 3 . 4 " ;
hash = " s h a 2 5 6 - J a J s j N 5 G p + 8 q s w f z l 5 X b H R Q M f a C A J p W D W j 9 D Y W J 0 g E I = " ;
} ;
knownRockspec = ( fetchurl {
url = " m i r r o r : / / l u a r o c k s / l u a j s o n - 1 . 3 . 4 - 1 . r o c k s p e c " ;
hash = " s h a 2 5 6 - + S 4 g f a 6 Q a O M m O C D X 8 T x B q 3 k F W l b a E e i S M x C f e f Y a k v 0 = " ;
} ) . outPath ;
propagatedBuildInputs = [ lpeg ] ;
} )
] ) ;
2023-07-23 01:29:20 +00:00
crossTargets = {
# koreader-base Makefile targets to use when compiling for the given host platform
# only used when cross compiling
aarch64 = " d e b i a n - a r m 6 4 " ;
} ;
target = if stdenv . buildPlatform == stdenv . hostPlatform then
" d e b i a n "
else
crossTargets . " ${ stdenv . hostPlatform . parsed . cpu . name } " ;
2024-02-03 23:58:41 +00:00
fakeBuildDep = buildPackages . writeShellScript " f a k e - b u i l d - k o - d e p " ''
set - x
lib = " $ 1 "
build_dir = " $ 2 "
prebuilt = " $ 3 "
mkdir - p " $ b u i l d _ d i r / $ l i b - p r e f i x / s r c "
rm - rf " $ b u i l d _ d i r / $ l i b - p r e f i x / s r c / $ l i b "
rm - rf " $ b u i l d _ d i r / $ l i b - p r e f i x / s r c / $ l i b - b u i l d "
# the library build directory koreader uses isn't consistently named, but we can cover most cases ($lib or $lib-build).
# we have to copy the full tree rather than just symlink because koreader/base/Makefile.third
# is copying lib/*.so into include/.
# seriously, wtf are they doing over there.
cp - R " $ p r e b u i l t " " $ b u i l d _ d i r / $ l i b - p r e f i x / s r c / $ l i b "
cp - R " $ p r e b u i l t " " $ b u i l d _ d i r / $ l i b - p r e f i x / s r c / $ l i b - b u i l d "
# ln -s "$prebuilt" "$build_dir/$lib-prefix/src/$lib"
# ln -s "$prebuilt" "$build_dir/$lib-prefix/src/$lib-build"
'' ;
2023-07-18 23:05:26 +00:00
in
stdenv . mkDerivation rec {
pname = " k o r e a d e r - f r o m - s r c " ;
2023-11-19 23:04:39 +00:00
inherit version ;
2023-10-27 11:37:40 +00:00
srcs = [ src ] ++ ( lib . mapAttrsToList
2023-07-19 10:44:00 +00:00
( name : src : fetchgit (
2023-07-19 10:25:41 +00:00
{
2023-07-19 10:44:00 +00:00
inherit name ;
2023-07-20 10:45:44 +00:00
} // src . source // {
2023-07-19 23:03:57 +00:00
# koreader sometimes specifies the rev as `tags/FOO`.
# we need to remember that to place the repo where it expects, but we have to strip it here for fetchgit to succeed.
2023-07-20 10:45:44 +00:00
rev = lib . removePrefix " t a g s / " src . source . rev ;
2023-07-19 23:03:57 +00:00
}
2023-07-19 10:25:41 +00:00
) )
sources . thirdparty
) ;
2023-07-19 10:15:07 +00:00
patches = [
2023-07-23 23:44:33 +00:00
./debug.patch #< not needed to build, just helps debug packaging issues
2023-07-21 04:20:33 +00:00
./no_rm_build_dirs.patch
2023-07-21 07:59:46 +00:00
./lua-Spore-no-luajson.patch #< TODO: test this at runtime! we ship luajson, but just don't expose it via luarocks...
2023-07-19 10:15:07 +00:00
( substituteAll (
{
src = ./vendor-external-projects.patch ;
} // ( lib . mapAttrs
( _proj : source : fetchurl source )
sources . externalProjects
)
) )
2023-10-27 08:41:02 +00:00
./rss-no-interrupt-on-image-failure.patch # just a preference
2023-07-19 10:15:07 +00:00
] ;
2023-07-19 06:45:40 +00:00
sourceRoot = " k o r e a d e r " ;
2023-07-18 23:05:26 +00:00
2023-07-19 06:45:40 +00:00
nativeBuildInputs = [
2023-07-23 01:29:20 +00:00
buildPackages . stdenv . cc # TODO: move to depsBuildBuild?
2023-07-19 09:51:35 +00:00
autoconf # autotools is used by some thirdparty libraries
automake
2023-07-22 08:44:11 +00:00
autoPatchelfHook # TODO: needed?
2023-07-19 09:51:35 +00:00
cmake # for koreader/base submodule
2023-07-19 06:45:40 +00:00
dpkg
2023-07-23 01:29:20 +00:00
gettext
2023-07-19 06:45:40 +00:00
git
2023-07-19 09:51:35 +00:00
libtool
2023-07-19 06:45:40 +00:00
makeWrapper
2023-07-21 04:20:33 +00:00
perl # TODO: openssl might try to take a runtime dep on this; see nixpkg
2023-07-19 23:49:11 +00:00
pkg-config
2023-07-21 09:15:03 +00:00
python3
2023-07-20 10:45:44 +00:00
ragel
2023-07-19 23:49:11 +00:00
which
2023-07-21 07:59:46 +00:00
# luajit_lua52.pkgs.luarocks
luaEnv . pkgs . luarocks
2023-07-19 06:45:40 +00:00
] ;
2023-07-18 23:05:26 +00:00
buildInputs = [
2023-07-21 07:59:46 +00:00
# luajson
luaEnv
2023-07-18 23:05:26 +00:00
] ;
2023-07-21 09:15:03 +00:00
postPatch =
let
env = " ${ buildPackages . coreutils } / b i n / e n v " ;
in ''
substituteInPlace ../openssl/config - - replace ' /usr/bin/env ' ' $ { env } '
2023-07-23 01:29:20 +00:00
substituteInPlace ../openssl/Configure - - replace ' /usr/bin/env ' ' $ { env } '
2023-07-21 09:15:03 +00:00
chmod + x ../glib/gio/gio-querymodules-wrapper.py
chmod + x ../glib/gio/tests/gengiotypefuncs.py
chmod + x ../glib/gobject/tests/taptestrunner.py
# need directory write perm in order to patchShebangs
chmod u + w ../glib / { gio , gio/tests , glib , gobject/tests , tests }
patchShebangs ../glib/gio/data-to-c.py
patchShebangs ../glib/gio/gio-querymodules-wrapper.py
patchShebangs ../glib/gio/tests/gengiotypefuncs.py
patchShebangs ../glib/glib/update-gtranslit.py
patchShebangs ../glib/gobject/tests/taptestrunner.py
patchShebangs ../glib/tests/gen-casefold-txt.py
patchShebangs ../glib/tests/gen-casemap-txt.py
substituteInPlace ../glib/gio/gdbus-2.0/codegen/gdbus-codegen.in - - replace ' /usr/bin/env @ PYTHON @ ' ' @ PYTHON @ '
substituteInPlace ../glib/glib/gtester-report.in - - replace ' /usr/bin/env @ PYTHON @ ' ' @ PYTHON @ '
substituteInPlace ../glib/gobject/glib-genmarshal.in - - replace ' /usr/bin/env @ PYTHON @ ' ' @ PYTHON @ '
substituteInPlace ../glib/gobject/glib-mkenums.in - - replace ' /usr/bin/env @ PYTHON @ ' ' @ PYTHON @ '
2023-07-23 01:29:20 +00:00
substituteInPlace ../harfbuzz/autogen.sh - - replace ' which pkg-config' ' which $ PKG_CONFIG'
substituteInPlace ../fribidi/autogen.sh - - replace ' which pkg-config' ' which $ PKG_CONFIG'
2023-12-07 08:04:35 +00:00
substituteInPlace base/Makefile.defs - - replace \
2024-01-27 14:38:52 +00:00
' LUAROCKS_BINARY = luarocks' ' LUAROCKS_BINARY = $ { lib . optionalString ( ! stdenv . buildPlatform . canExecute stdenv . hostPlatform ) ( stdenv . hostPlatform . emulator buildPackages ) } $ { luajit52 } /bin/lua $ { luaEnv . pkgs . luarocks } /bin/.luarocks-wrapped '
2023-07-21 04:20:33 +00:00
'' ;
2023-07-19 06:45:40 +00:00
dontConfigure = true ;
2023-07-18 23:05:26 +00:00
buildPhase = ''
2024-02-03 23:58:41 +00:00
link_lib_into_build_dir ( ) {
2023-07-19 09:51:35 +00:00
lib = " $ 1 "
rev = " $ 2 "
2023-07-20 10:45:44 +00:00
platform = " $ 3 "
2024-02-03 23:58:41 +00:00
prebuilt = " $ 4 "
2023-07-20 10:45:44 +00:00
2023-07-19 09:51:35 +00:00
lib_src = " . . / $ l i b "
2024-02-03 23:58:41 +00:00
cmake_lists = " b a s e / t h i r d p a r t y / $ l i b / C M a k e L i s t s . t x t "
2023-07-21 04:20:33 +00:00
build_dir = " b a s e / t h i r d p a r t y / $ l i b / b u i l d / $ p l a t f o r m "
2023-07-19 06:45:40 +00:00
# link the nix clone into the directory koreader would use for checkout
# ref="base/thirdparty/$l/build/git_checkout"
# echo "linking thirdparty library $l $ref -> $deref"
# mkdir -p "$ref"
# ln -s "$deref" "$ref/$l"
# mv "$deref" "$ref/$l"
# cp -R "$deref" "$ref/$l"
# needs to be writable for koreader to checkout it specific revision
# chmod u+w -R "$ref/$l/.git"
2023-07-19 07:02:14 +00:00
# koreader wants to clone each library into this git_checkout dir,
# then checkout a specific revision,
# and then copy that checkout into the build/working directory further down.
# instead, we replicate that effect here, and by creating these "stamp" files
# koreader will know to skip the `git clone` and `git checkout` calls.
# the logic we're spoofing lives in koreader/base/thirdparty/cmake_modules/koreader_thirdparty_git.cmake
2023-07-21 04:20:33 +00:00
stamp_dir = " $ b u i l d _ d i r / g i t _ c h e c k o u t / s t a m p "
2023-07-21 01:56:55 +00:00
stamp_info = " $ s t a m p _ d i r / $ l i b - g i t i n f o - $ r e v . t x t "
stamp_clone = " $ s t a m p _ d i r / $ l i b - g i t c l o n e - l a s t r u n . t x t "
echo " c r e a t i n g s t a m p s f o r $ l i b : $ s t a m p _ c l o n e > $ s t a m p _ i n f o "
2023-07-19 11:10:55 +00:00
# mkdir $(dirname ..) to handle the case where `$rev` contains slashes
2023-07-21 01:56:55 +00:00
mkdir - p $ ( dirname " $ s t a m p _ i n f o " )
2023-07-19 07:02:14 +00:00
# koreader-base decides whether to redo the git checkout based on a timestamp compare of these two stamp files
2023-07-21 01:56:55 +00:00
touch - d " l a s t w e e k " $ ( dirname " $ s t a m p _ i n f o " ) #< XXX: necessary?
touch - d " l a s t w e e k " " $ s t a m p _ i n f o "
touch - d " n e x t w e e k " " $ s t a m p _ c l o n e "
2023-07-19 07:02:14 +00:00
2023-07-19 06:45:40 +00:00
# koreader would copy the checkout into this build/working directory,
# but because we spoof the stamps to work around other git errors,
# copy it there on koreader's behalf
2023-07-21 04:20:33 +00:00
prefix = " $ b u i l d _ d i r / $ l i b - p r e f i x "
2023-07-19 06:45:40 +00:00
mkdir - p " $ p r e f i x / s r c "
2023-07-19 09:51:35 +00:00
cp - R " $ l i b _ s r c " " $ p r e f i x / s r c / $ l i b "
2023-07-19 06:45:40 +00:00
# src dir needs to be writable for koreader to apply its own patches
2023-07-19 09:51:35 +00:00
chmod u + w - R " $ p r e f i x / s r c / $ l i b "
2024-02-03 23:58:41 +00:00
if [ - n " $ p r e b u i l t " ] ; then
abs_build_dir = " $ ( r e a l p a t h " $ build_dir " ) "
sed - i ' s/INSTALL_COMMAND . * /INSTALL_COMMAND " " / ' " $ c m a k e _ l i s t s "
sed - i \
" s : B U I L D _ C O M M A N D . * : B U I L D _ C O M M A N D ${ fakeBuildDep } $ l i b $ a b s _ b u i l d _ d i r $ p r e b u i l t : " \
" $ c m a k e _ l i s t s "
fi
2023-07-19 09:51:35 +00:00
}
2024-02-03 16:27:35 +00:00
$ { builtins . concatStringsSep " \n " ( lib . mapAttrsToList
( name : src :
let
# for machine-agnostic libraries (e.g. pure lua), koreader doesn't build them in a flavored directory
machine = if src . machineAgnostic or false then " " else stdenv . hostPlatform . config ;
in
2024-02-03 23:58:41 +00:00
'' l i n k _ l i b _ i n t o _ b u i l d _ d i r " ${ name } " " ${ src . source . rev } " " ${ machine } " " ${ src . package or " " } " ''
2024-02-03 16:27:35 +00:00
)
sources . thirdparty
) }
2023-07-19 06:45:40 +00:00
2023-07-23 01:29:20 +00:00
make TARGET = $ { target } DEBIAN = 1 SHELL = sh VERBOSE = 1
2023-07-18 23:05:26 +00:00
'' ;
2023-07-23 01:29:20 +00:00
env = lib . optionalAttrs ( stdenv . buildPlatform != stdenv . hostPlatform ) {
CHOST = stdenv . hostPlatform . config ;
} ;
2023-07-18 23:05:26 +00:00
installPhase = ''
2023-07-23 01:29:20 +00:00
make TARGET = $ { target } DEBIAN = 1 debianupdate
mv koreader- $ { target } - $ { stdenv . hostPlatform . config } /debian/usr $ out
2023-07-22 08:44:11 +00:00
wrapProgram $ out/bin/koreader - - prefix LD_LIBRARY_PATH : $ {
lib . makeLibraryPath [ SDL2 ]
}
2023-07-18 23:05:26 +00:00
'' ;
2023-07-23 01:29:20 +00:00
# XXX: ^ don't specify INSTALL_DIR="$out" as make arg because that conflicts with vars used by third-party libs
# might be safe to specify that as an env var, though?
2023-07-22 08:44:11 +00:00
# XXX: nixpkgs adds glib and gtk3-x11 to LD_LIBRARY_PATH as well
2023-07-18 23:05:26 +00:00
2023-07-21 07:59:46 +00:00
passthru = {
2023-10-27 11:37:40 +00:00
# exposed for debugging
inherit luajit52 luaEnv ;
2023-07-21 07:59:46 +00:00
} ;
2023-07-18 23:05:26 +00:00
meta = with lib ; {
homepage = " h t t p s : / / g i t h u b . c o m / k o r e a d e r / k o r e a d e r " ;
description =
" A n e b o o k r e a d e r a p p l i c a t i o n s u p p o r t i n g P D F , D j V u , E P U B , F B 2 a n d m a n y m o r e f o r m a t s , r u n n i n g o n C e r v a n t e s , K i n d l e , K o b o , P o c k e t B o o k a n d A n d r o i d d e v i c e s " ;
sourceProvenance = with sourceTypes ; [ fromSource ] ;
platforms = platforms . linux ;
license = licenses . agpl3Only ;
maintainers = with maintainers ; [ colinsane contrun neonfuz ] ;
} ;
}