Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions nix/ios-deps.nix
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
, consumerCabalFile ? null
, consumerCabal2Nix ? null
, hpkgs ? (_: _: {}) # consumer haskellPackages overrides
, hatterSrc ? null # hatter source tree (builds hatter as a normal dep)
}:
let
pkgs = import sources.nixpkgs {};
Expand All @@ -25,8 +26,27 @@ let
}) {};
};

# Build hatter as a regular haskellPackages derivation from local source.
# Executables and tests are stripped to avoid pulling in test-framework deps.
hatterOverride = self: super:
if hatterSrc != null then {
hatter = pkgs.haskell.lib.overrideCabal
(self.callCabal2nix "hatter" hatterSrc {})
(old: {
postPatch = (old.postPatch or "") + ''
sed -i '/^executable /,$d' hatter.cabal
sed -i '/^test-suite /,$d' hatter.cabal
'';
doCheck = false;
});
} else {};

nativeHaskellPkgs = pkgs.haskellPackages.override {
overrides = pkgs.lib.composeExtensions unwitchOverride hpkgs;
overrides = pkgs.lib.composeManyExtensions [
unwitchOverride
hatterOverride
hpkgs
];
};

ghc = nativeHaskellPkgs.ghc;
Expand All @@ -37,11 +57,15 @@ let
haskellPkgs = nativeHaskellPkgs;
};

# When hatterSrc is provided, add the hatter package to the collected deps
# so its .a and .conf are available for linking.
hatterDep = if hatterSrc != null then [ nativeHaskellPkgs.hatter ] else [];

# Hatter's own non-boot dependencies — always included so mkIOSLib's
# raw GHC invocation can find them even without a consumer cabal file.
hatterOwnDeps = [ nativeHaskellPkgs.unwitch ];

in import ./collect-deps.nix {
inherit pkgs ghc ghcPkgCmd;
deps = resolvedDeps ++ hatterOwnDeps;
deps = resolvedDeps ++ hatterDep ++ hatterOwnDeps;
}
1 change: 1 addition & 0 deletions nix/ios.nix
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ let
lib = import ./lib.nix { inherit sources; };
iosDeps = import ./ios-deps.nix {
inherit sources consumerCabalFile consumerCabal2Nix hpkgs;
hatterSrc = ../.;
};
in
lib.mkIOSLib {
Expand Down
88 changes: 84 additions & 4 deletions nix/lib.nix
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ in {
, simulator ? false
, pname ? "hatter-ios"
, extraModuleCopy ? ""
, crossDeps ? null # output of ios-deps.nix (lib/, hi/, pkgdb/)
, crossDeps ? null # output of ios-deps.nix (lib/, pkgdb/)
}:
let
iosPkgs = import sources.nixpkgs {};
Expand Down Expand Up @@ -584,6 +584,46 @@ in {
buildInputs = [ libffiStatic gmpStatic ];

buildPhase = ''
${if crossDeps != null then ''
# Hatter is pre-built in crossDeps — only compile per-app files.
cp ${mainModule} Main.hs

# run_main.c is not in cabal c-sources (references per-app ZCMain_main_closure)
mkdir -p cbits
cp ${hatterSrc}/cbits/run_main.c cbits/

# Extra module copies (consumer overrides)
${extraModuleCopy}

ghc -staticlib \
-O2 \
-o libHatter.a \
-I${hatterSrc}/include \
-package-db ${crossDeps}/pkgdb \
-optl-lffi \
-optl-Wl,-u,_haskellRunMain \
-optl-Wl,-u,_haskellOnLifecycle \
-optl-Wl,-u,_haskellRenderUI \
-optl-Wl,-u,_haskellOnUIEvent \
-optl-Wl,-u,_haskellOnPermissionResult \
-optl-Wl,-u,_haskellOnSecureStorageResult \
-optl-Wl,-u,_haskellOnBleScanResult \
-optl-Wl,-u,_haskellOnDialogResult \
-optl-Wl,-u,_haskellOnLocationUpdate \
-optl-Wl,-u,_haskellOnAuthSessionResult \
-optl-Wl,-u,_haskellOnPlatformSignInResult \
-optl-Wl,-u,_haskellOnCameraResult \
-optl-Wl,-u,_haskellOnVideoFrame \
-optl-Wl,-u,_haskellOnAudioChunk \
-optl-Wl,-u,_haskellOnBottomSheetResult \
-optl-Wl,-u,_haskellOnHttpResult \
-optl-Wl,-u,_haskellOnNetworkStatusChange \
-optl-Wl,-u,_haskellLogLocale \
-optl-Wl,-u,_haskellLogDeviceInfo \
cbits/run_main.c \
Main.hs
'' else ''
# Standalone build — compile hatter from source.
mkdir -p Hatter
cp ${hatterSrc}/src/Hatter/Types.hs Hatter/
cp ${hatterSrc}/src/Hatter/Lifecycle.hs Hatter/
Expand Down Expand Up @@ -640,7 +680,6 @@ in {
-O2 \
-o libHatter.a \
-I${hatterSrc}/include \
${if crossDeps != null then "-package-db ${crossDeps}/pkgdb -i${crossDeps}/hi" else ""} \
-optl-lffi \
-optl-Wl,-u,_haskellRunMain \
-optl-Wl,-u,_haskellOnLifecycle \
Expand Down Expand Up @@ -682,6 +721,7 @@ in {
cbits/device_info.c \
Main.hs \
Hatter.hs
''}
'';

installPhase = ''
Expand Down Expand Up @@ -790,7 +830,7 @@ open(sys.argv[1], "w").write(yml)
, simulator ? false
, pname ? "hatter-watchos"
, extraModuleCopy ? ""
, crossDeps ? null # output of ios-deps.nix (lib/, hi/, pkgdb/)
, crossDeps ? null # output of ios-deps.nix (lib/, pkgdb/)
}:
let
iosPkgs = import sources.nixpkgs {};
Expand Down Expand Up @@ -821,6 +861,46 @@ open(sys.argv[1], "w").write(yml)
buildInputs = [ libffiStatic gmpStatic ];

buildPhase = ''
${if crossDeps != null then ''
# Hatter is pre-built in crossDeps — only compile per-app files.
cp ${mainModule} Main.hs

# run_main.c is not in cabal c-sources (references per-app ZCMain_main_closure)
mkdir -p cbits
cp ${hatterSrc}/cbits/run_main.c cbits/

# Extra module copies (consumer overrides)
${extraModuleCopy}

ghc -staticlib \
-O2 \
-o libHatter.a \
-I${hatterSrc}/include \
-package-db ${crossDeps}/pkgdb \
-optl-lffi \
-optl-Wl,-u,_haskellRunMain \
-optl-Wl,-u,_haskellOnLifecycle \
-optl-Wl,-u,_haskellRenderUI \
-optl-Wl,-u,_haskellOnUIEvent \
-optl-Wl,-u,_haskellOnPermissionResult \
-optl-Wl,-u,_haskellOnSecureStorageResult \
-optl-Wl,-u,_haskellOnBleScanResult \
-optl-Wl,-u,_haskellOnDialogResult \
-optl-Wl,-u,_haskellOnLocationUpdate \
-optl-Wl,-u,_haskellOnAuthSessionResult \
-optl-Wl,-u,_haskellOnPlatformSignInResult \
-optl-Wl,-u,_haskellOnCameraResult \
-optl-Wl,-u,_haskellOnVideoFrame \
-optl-Wl,-u,_haskellOnAudioChunk \
-optl-Wl,-u,_haskellOnBottomSheetResult \
-optl-Wl,-u,_haskellOnHttpResult \
-optl-Wl,-u,_haskellOnNetworkStatusChange \
-optl-Wl,-u,_haskellLogLocale \
-optl-Wl,-u,_haskellLogDeviceInfo \
cbits/run_main.c \
Main.hs
'' else ''
# Standalone build — compile hatter from source.
mkdir -p Hatter
cp ${hatterSrc}/src/Hatter/Types.hs Hatter/
cp ${hatterSrc}/src/Hatter/Lifecycle.hs Hatter/
Expand Down Expand Up @@ -877,7 +957,6 @@ open(sys.argv[1], "w").write(yml)
-O2 \
-o libHatter.a \
-I${hatterSrc}/include \
${if crossDeps != null then "-package-db ${crossDeps}/pkgdb -i${crossDeps}/hi" else ""} \
-optl-lffi \
-optl-Wl,-u,_haskellRunMain \
-optl-Wl,-u,_haskellOnLifecycle \
Expand Down Expand Up @@ -919,6 +998,7 @@ open(sys.argv[1], "w").write(yml)
cbits/device_info.c \
Main.hs \
Hatter.hs
''}
'';

installPhase = ''
Expand Down
1 change: 1 addition & 0 deletions nix/watchos.nix
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ let
lib = import ./lib.nix { inherit sources; };
iosDeps = import ./ios-deps.nix {
inherit sources consumerCabalFile consumerCabal2Nix hpkgs;
hatterSrc = ../.;
};
in
lib.mkWatchOSLib {
Expand Down
Loading