How to redistribute wxHaskell apps? - haskell

I am using ghc 7.6.3. I installed wxHaskell from here: https://github.com/wxHaskell/wxHaskell
It worked, the sample programs compile and the run successfully.
The only problem now is that I want to distribute a wxHaskell application on mac OS X. I tried using macosx-app and cabal-macosx (https://github.com/michaelt/cabal-macosx) to make an "app" file. It runs fine on my machine, but it fails to run on another computer. I get the following error:
Dyld Error Message: Library not loaded: /Users/user/.cabal/lib/wxc-0.90.1.0/ghc-7.6.3/libwxc.dylib.
I am using OS X 10.8.4 (Mountain Lion), but I would be also interested in compiling apps on Windows and redistribute them too.
What would be the best way to redistribute wxHaskell apps?
Setup.hs
-- Example Setup.hs for the wxHello app.
import Distribution.MacOSX
import Distribution.Simple
main :: IO ()
main = defaultMainWithHooks $ simpleUserHooks {
postBuild = appBundleBuildHook guiApps -- no-op if not MacOS X
}
guiApps :: [MacApp]
guiApps = [MacApp "WxHello"
(Just "resources/WxHello.icns")
Nothing -- Build a default Info.plist for the icon.
[] -- No other resources.
[] -- No other binaries.
ChaseWithDefaults -- Try changing to ChaseWithDefaults
]
wxHello.cabal:
Name: wxHello
Version: 0.1.0
Stability: Alpha
Synopsis: wxWidgets `Hello World' example for cabal-macosx
Description:
Example showing how to use cabal-macosx to build an application
bundle for a simple `Hello World' program using the wxWidgets GUI
toolkit.
Category: Data
License: BSD3
License-file: LICENSE
Copyright: Andy Gimblett <haskell#gimbo.org.uk>
Author: Andy Gimblett <haskell#gimbo.org.uk>
Maintainer: Andy Gimblett <haskell#gimbo.org.uk>
Build-Type: Custom
Cabal-Version: >=1.6
Executable WxHello
hs-source-dirs: src
Main-is: Main.hs
Build-Depends: base >= 3 && < 5, cabal-macosx, wx
ghc-options: -fwarn-tabs -threaded -Wall
Here are the dylib files inside the generated package:
WxHello.app $ find . | grep dylib
./Contents/Frameworks/Users/user/.cabal/lib/wxc-0.90.1.0/ghc-7.6.3/libwxc.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_baseu-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_baseu_net-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_baseu_xml-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_adv-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_aui-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_core-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_gl-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_html-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_propgrid-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_qa-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_ribbon-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_richtext-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_stc-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_webview-2.9.5.0.0.dylib
./Contents/Frameworks/Users/user/temp/wxWidgets-2.9.5/build-release/lib/libwx_osx_cocoau_xrc-2.9.5.0.0.dylib
./Contents/Frameworks/usr/lib/libc++abi.dylib
./Contents/Frameworks/usr/lib/libexpat.1.dylib
./Contents/Frameworks/usr/lib/libiconv.2.dylib
./Contents/Frameworks/usr/lib/libstdc++.6.dylib
./Contents/Frameworks/usr/lib/libz.1.dylib

The last redistributable I made in Windows with wxHaskell needed the files
mingwm10.dll and
wxmws28u_gcc.dll
to be in the same folder as the .exe (not just somewhere on my path).
This was using a previous version of wxHaskell, which compiled against a previous version of wxWidgits itself, so presumably you'd need the wx dll to have 29 in it rather than 28.
I compiled with static linking too:
ghc -static -optl-static -optl-mwindows Main -o Project.exe
the -optl-mwindows gets rid of the command prompt window which would otherwise appear alongside your app.

It might be helpful to include your .cabal and Setup.hs files.
From the documentation on cabal-macosx, it seems that you need to ensure that your MacApp data value in Setup.hs gets the appropriate mode for ChaseDeps (use ChaseWithDefaults instead of DoNotChase) in order to build redistributable app bundles.
If you have done that but still get the same error, I would check inside the resulting app bundle to see if the necessary libraries got copied in there at all. You may find enough information to file a bug with the cabal-macosx maintainer.
Edit
Based on what you've included, the setup looks correct, and it appears to have at least copied the library dependencies in. I think the problem is probably with the cabal-macosx package.
Looking at the source code to the dependency-fixup code, it looks like it should have printed a bunch of "Updating <library>'s dependence on <path> to <path>" lines as it was building the bundle. Did you see those? Were there any lines updating the binary itself?
I am not very experienced with the OS X linking process, but I would think that unless the binary is linked after copying the libraries, it would need to be updated as well. You should be able to use /usr/bin/otool -L <filename> and /usr/bin/install_name_tool to manually fix up the paths in binaries the install process may have missed.
Here are the man pages for those two tools:
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/install_name_tool.1.html
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/otool.1.html

Related

"* Missing (or bad) C library: OpenAL32" - from stack build for a haskell project

I have a stack project using Sound.ALUT. The project was building fine on both Windows and Mac before I added sound. (Sound.ALUT is a library layered over OpenAL.) Got thinks working on MacOS but those changes broke the Windows build. Still builds fine on MacOS.
The offending snippit from the "stack build" console log on Windows looks like this
GLUT > [22 of 24] Compiling Graphics.UI.GLUT.Callbacks.Global
GLUT > [23 of 24] Compiling Graphics.UI.GLUT.Callbacks
GLUT > [24 of 24] Compiling Graphics.UI.GLUT
GLUT > copy/register
GLUT > Installing library in C:\sr\snapshots\87ecdd59\lib\x86_64-windows-ghc-8.10.7\GLUT-2.7.0.16-2jeyeunHWey2D1Huuhst8j
GLUT > Registering library for GLUT-2.7.0.16..
OpenAL > configure
OpenAL > Configuring OpenAL-1.7.0.5...
OpenAL > Cabal-simple_Z6RU0evB_3.2.1.0_ghc-8.10.7.exe: Missing dependency on a foreign
OpenAL > library:
OpenAL > * Missing (or bad) C library: OpenAL32
OpenAL > This problem can usually be solved by installing the system package that
OpenAL > provides this library (you may need the "-dev" version). If the library is
OpenAL > already installed but in a non-standard location then you can use the flags
OpenAL > --extra-include-dirs= and --extra-lib-dirs= to specify where it is.If the
OpenAL > library file does exist, it may contain errors that are caught by the C
OpenAL > compiler at the preprocessing stage. In this case you can re-run configure
OpenAL > with the verbosity flag -v3 to see the error messages.
OpenAL >
Progress 10/21
Cleary it can't find OpenAL. I've tried:
installing OpenAL using the Windows installer from https://www.openal.org/downloads
cloning and building openal-soft https://github.com/kcat/openal-soft on windows
setting the --extra-include-dirs and --extra-lib-dirs inslide my stack.yaml to point to where the libraries should be.
I had similar issues getting Sound.ALUT working on the Mac build. In that case building from the sources seemed to solve the problems. I have more trouble building on Windows since the build environment is less familiar. My Windows work has mostly been centered around installing Cygwin and making it look like Unix. But this time, I'm trying to get by on what stack's mingw-w64 provides. I was pulling down things with stack exec -- pacman trying to find something that would install OpenAL as a side effect but no luck.
Some subtleties arise from the fact that stack want to install things in its own self-contained environment. It tries to keep installs localized inside the project directory and not muck around with directories elsewhere. My stack environment looks like this
C:\Users\Mark\slgjff>stack path
snapshot-doc-root: C:\sr\snapshots\aff7b821\doc
local-doc-root: C:\Users\Mark\slgjff\.stack-work\install\f5431f41\doc
local-hoogle-root: C:\Users\Mark\slgjff\.stack-work\hoogle\f5431f41
stack-root: C:\sr
project-root: C:\Users\Mark\slgjff
config-location: C:\Users\Mark\slgjff\stack.yaml
bin-path: .;C:\sr\snapshots\87ecdd59\bin;C:\sr\compiler-tools\x86_64-windows\ghc-8.10.7\bin;C:\Users\Mark\AppData\Local\Programs\stack\x86_64-windows\ghc-8.10.7\bin;C:\Users\Mark\AppData\Local\Programs\stack\x86_64-windows\ghc-8.10.7\mingw\bin;C:\Users\Mark\AppData\Local\Programs\stack\x86_64-windows\msys2-20220503\mingw64\bin;C:\Users\Mark\AppData\Local\Programs\stack\x86_64-windows\msys2-20220503\usr\bin;C:\Users\Mark\AppData\Local\Programs\stack\x86_64-windows\msys2-20220503\usr\local\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\Git\cmd;C:\Users\Mark\AppData\Roaming\local\bin;C:\Users\Mark\AppData\Local\Microsoft\WindowsApps
programs: C:\Users\Mark\AppData\Local\Programs\stack\x86_64-windows
compiler-exe: C:\Users\Mark\AppData\Local\Programs\stack\x86_64-windows\ghc-8.10.7\bin\ghc-8.10.7.exe
compiler-bin: C:\Users\Mark\AppData\Local\Programs\stack\x86_64-windows\ghc-8.10.7\bin
compiler-tools-bin: C:\sr\compiler-tools\x86_64-windows\ghc-8.10.7\bin
local-bin: C:\Users\Mark\AppData\Roaming\local\bin
extra-include-dirs: C:\Users\Mark\AppData\Local\Programs\stack\x86_64-windows\msys2-20220503\mingw64\include
extra-library-dirs: C:\Users\Mark\AppData\Local\Programs\stack\x86_64-windows\msys2-20220503\mingw64\lib, C:\Users\Mark\AppData\Local\Programs\stack\x86_64-windows\msys2-20220503\mingw64\bin
snapshot-pkg-db: C:\sr\snapshots\87ecdd59\pkgdb
local-pkg-db: C:\Users\Mark\slgjff\.stack-work\install\363b2fd8\pkgdb
global-pkg-db: C:\Users\Mark\AppData\Local\Programs\stack\x86_64-windows\ghc-8.10.7\lib\package.conf.d
ghc-package-path: C:\Users\Mark\slgjff\.stack-work\install\363b2fd8\pkgdb;C:\sr\snapshots\87ecdd59\pkgdb;C:\Users\Mark\AppData\Local\Programs\stack\x86_64-windows\ghc-8.10.7\lib\package.conf.d
snapshot-install-root: C:\sr\snapshots\87ecdd59
local-install-root: C:\Users\Mark\slgjff\.stack-work\install\363b2fd8
dist-dir: .stack-work\dist\274b403a
local-hpc-root: C:\Users\Mark\slgjff\.stack-work\install\363b2fd8\hpc
local-bin-path: C:\Users\Mark\AppData\Roaming\local\bin
ghc-paths: C:\Users\Mark\AppData\Local\Programs\stack\x86_64-windows
I'm not sure the configure needs to be happy. I wish I could construct a checklist run through, but I don't understand enough to write that checklist. Do it need the C source for header files? Don't know. Certainly it must need the .lib and .dlls on the path somewhere. But which path exactly?
My package.yaml -- which works fine on MacOS
ghc-options:
#- -dynamic
- -static
dependencies:
- base >= 4.7 && < 5
- random
- gloss
- gloss-juicy
- ALUT
library:
source-dirs: src
executables:
slgjff-exe:
main: Main.hs
source-dirs: app
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- slgjff
tests:
slgjff-test:
main: Spec.hs
source-dirs: test
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- slgjff
And my stack.yaml -- which also works fine on MacOS
resolver:
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/24.yaml
packages:
- .
extra-deps:
- gloss-1.13.2.1#sha256:273d02d30e1896932d45424dab6022a16986c0ed3eef6937776b5f40854ce51c,4075
- JuicyPixels-3.3.6#sha256:03bd32c3a884ac8a32f49334f14695469a710945c84cef9a1e059a79ac416996,3911
- gloss-juicy-0.2.3
And because it may be helpful, here are the includes at top of my program.
import System.Exit ( exitSuccess, exitFailure )
import System.IO ( hPutStrLn, stderr )
import Data.List
import Graphics.Gloss
import Graphics.Gloss.Interface.Pure.Game
import Graphics.Gloss.Interface.IO.Game
import Graphics.Gloss.Data.Vector
import Graphics.Gloss.Juicy
import Control.Monad( when, unless )
import Sound.ALUT as S
I got so desperate I stuck C:/Windows/System32 on the path and almost spilled my drink when the build tried to delete files from C:/Windows/System32. So, I took that out. Running out of ideas.
My sense is that out of inexperience with ghc on Windows, I must be missing something that would be really obvious to someone with more experience. Thanks in advance for any insights.
P.S. I created a stripped down version of the project and put it up on github at https://github.com/markcornwell/alut-glitch
See the README for the project for instruction on how to reproduce the error.

Hardcode datadir path upon installing executable

Problem: I've got a command-line tool written in Haskell that reads a data file. Upon installing the program, I'd like for the program to be able to read that data file regardless of the directory I find myself in. That is, upon installing, the path that the program knows should be aligned with the path that the installer chooses.
Initial attempt: I was directed to the section 7.6. Accessing data files from package code in Cabal (the library) and learned that I can import getDataDir :: IO FilePath from Paths_myprog, as long as I add Paths_myprog to other-modules (although Hpack auto-includes this by default) and that after installing my program, I can run it with:
myprog_datadir=~/tmp ~/.local/bin/myprog
Then all I need to do is have the installer move the data file to this directory, since myprog dynamically accesses that path rather than some hardcoded value. But I don't want to have to specify myprog_datadir=~/tmp in my environment every time I run the program, I want it hardcoded into the binary! And it seems that setting myprog_datadir=~/tmp when building and installing doesn't set a compile-time default.
So: Is there a way I can hardcode this path upon installation?
(Preferrably, an answer that relates to Stack, but a cabal-install answer is also greatly appreciated.)
Files listed in data-files are already automatically installed in the right location so that Paths_pkg will find them. Here's a minimal example:
% cat Main.hs
import Paths_so_test
main :: IO ()
main = getDataDir >>= putStrLn
% cat so-test.cabal
cabal-version: >=1.10
name: so-test
version: 0.1.0.0
build-type: Simple
data-files: test
executable so-test
main-is: Main.hs
other-modules: Paths_so_test
autogen-modules: Paths_so_test
build-depends: base >=4.14 && <4.15
default-language: Haskell2010
% cat test
Hello, world!
% cabal install
Wrote tarball sdist to
/home/dmwit/projects/oneoff/tmp.dir/dist-newstyle/sdist/so-test-0.1.0.0.tar.gz
Resolving dependencies...
Up to date
Symlinking 'so-test'
% cat `so-test`/test
Hello, world!

Conditional Compilation in Haskell submodule

I'm trying to have a submodule in my program compile conditionally to switch small parts of the code between release builds and development builds.
Currently I'm attempting to use cpphs however when I change the flags passed into GHC to define a variable and change an ifdef statement stack won't recompile those files.
For example, I've got a port number that I want to switch based on which target I have built. The code I have defining this number looks like this.
#ifdef StableRelease
port = 12345
#else
port = 54321
#endif
the stable build has the following options in its cabal file
ghc-options: -threaded -rtsopts -with-rtsopts=-N -pgmP cpphs -optP "-DStableRelease"
When I run stack build though it doesn't seem to actually pre-process the code above.
Does anyone have experience with cpphs or another preprocessing solution?
I would solve this with the help of flags
cppstuf.cabal-file
name: cppstuf
version: 0.1.0.0
...
cabal-version: >=1.10
flag StableRelease {
Description: Stable release settings like port ...
Default: False
}
executable cppstuf
main-is: Main.hs
build-depends: base >=4.9 && <5.00
default-language: Haskell2010
extensions: CPP
if flag(StableRelease) {
GHC-Options: -DSTABLE
}
Main.hs
module Main where
main :: IO ()
main =
#if STABLE
putStrLn "Hello, Haskell!"
#else
putStrLn "Hello, Haskell?"
#endif
and compiling it
stack build
or
stack build --flag cppstuf:stablerelease
Personal Note aside from the answer
I would not use CPP to manage configuration options - either providing command-line options I like optparse-applicative but there is also cmdargs,and or a configuration file I have used configurator for that, but there are several options out there on hackage. One being configurator-ng as #Shersh said - the other one is not being developed anymore.
CPP on the other hand I tend to use for making libraries work across multiple GHC/library versions.
Update - w\ regards to the comment.
If I deliver a program, the operations team should be able to change ports, hostname or handle file location of input files etc. without knowing haskell let alone recompiling a project.
It makes error chasing a lot easier if your production source code does not differ from your development sources, say you would have a postgres db in dev mode, but an oracle in production - you'll never find the oracle specific bug.
For things like optimization levels - I don't mind too much.
But make sure you test multi-threaded stuff properly, I once ran out of file handles because I was opening a lot but not closing fast enough - If your dev-setting is single threaded you'll deliver a bug.

Can I automatically embed pandoc's default templates in my application?

Pandoc comes with several default templates, which are distributed with the pandoc package. However, if I write an application that uses pandoc as a library, those default templates don't get included in the binary. I can still use them on my machine:
module Main where
import Text.Pandoc (getDefaultTemplate)
main = getDefaultTemplate Nothing "latex" >>= print
This will print the default.latex template. However, it's not portable, since it really refers to a file somewhere on my system:
$ cd path/to/example/project
$ stack build
$ scp path/to/binary remote:remote/path
$ ssh remote:remote/path/binary
example: Could not find data file /home/Zeta/.stack/snapshots/.../pandoc-1.16.0.2/data/templates/default.latex
Since pandoc's debian package does not include those files, it's somehow able to embed them. And indeed, there is a flag -f embed_data_files. I've tried to enable it in the local stack.yaml:
extra-deps: [pandoc-1.16]
flags:
pandoc:
embed_data_files: true
But that didn't change anything, the compiled binary still complains about missing data files.
So, is there any way to automatically include pandoc's template files?
It turns out that pandoc injects its data files during its build via hsb2hs. Somehow that step failed during stack build I missed the error message.
Neither hsb2hs nor its main dependency processing-tools are part of stack's LTS, they're only in the nightly stackage versions. The following additions to stack.yaml fixed the problem:
# part of stack.yaml:
extra-deps:
- preprocessor-tools-1.0.1
- hsb2hs-0.3.1
- pandoc-1.16
flags:
pandoc:
embed_data_files: true
For those using Cabal, this is somewhat equal to
cabal sandbox init
cabal update
cabal install hsb2hs-0.3.1 && cabal install pandoc-1.16 -f embed_data_files
cabal install --dependencies-only
cabal build
Here's how I verified that the templates are actually included:
$ stack build
$ grep "usepackage\{hyperref\}" .stack-work/install/*/bin/example -a
\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry}
$endif$
\usepackage{hyperref}
$if(colorlinks)$
\PassOptionsToPackage{usenames,dvipsnames}{color} % color is loaded by hyperref
That snippet is part of default.latex, so it's really included in the binary.

Minimal haskell (ghc) program installation (deployment without ghc/cabal)

(My problem is about distribute binaries without haskell-platform, ghc, cabal, ...)
I need deploy a well cabal formed haskell application (a Yesod scaffolded) but I have disk space restrictions.
GHC size is about 1Gbytes, store all cabal source code, packages, etc... require more disk space, etc...
Obviously, haskell-platform, ghc, ... is about development (not deployment).
In my specific case I can generate
cabal clean && cabal configure && cabal build
and run succesfully (some like)
./dist/build/MyEntryPoint/MyEntryPoint arg arg arg
But, what about dependencies?, how move it to production environment? (together my "dist" compilation)
Can I put binary dependencies without cabal? How?
Thank you very much!
By default, ghc uses static linking of the Haskell libraries. So the resulting binary is independent of the Haskell ecosystem. If your program does not need any data files, just copy the binary out from ./dist/build/MyEntryPoint/MyEntryPoint to the host
If you also have data files (e.g templates, images, static html pages) that are referenced by the binary using the data path finding logic of Cabal, you can use Setup copy as follows (using happy as an example):
/tmp/happy-1.18.10 $ ./Setup configure
Warning: defaultUserHooks in Setup script is deprecated.
Configuring happy-1.18.10...
/tmp/happy-1.18.10 $ ./Setup build
Building happy-1.18.10...
Preprocessing executable 'happy' for happy-1.18.10...
[ 1 of 18] Compiling NameSet ( src/NameSet.hs, dist/build/happy/happy-tmp/NameSet.o )
[..]
[18 of 18] Compiling Main ( src/Main.lhs, dist/build/happy/happy-tmp/Main.o )
Linking dist/build/happy/happy ...
/tmp/happy-1.18.10 $ ./Setup copy --destdir=/tmp/to_be_deployed/
Installing executable(s) in /tmp/to_be_deployed/usr/local/bin
/tmp/happy-1.18.10 $ find /tmp/to_be_deployed
/tmp/to_be_deployed
/tmp/to_be_deployed/usr
/tmp/to_be_deployed/usr/local
/tmp/to_be_deployed/usr/local/bin
/tmp/to_be_deployed/usr/local/bin/happy
/tmp/to_be_deployed/usr/local/share
/tmp/to_be_deployed/usr/local/share/doc
/tmp/to_be_deployed/usr/local/share/doc/happy-1.18.10
/tmp/to_be_deployed/usr/local/share/doc/happy-1.18.10/LICENSE
/tmp/to_be_deployed/usr/local/share/happy-1.18.10
/tmp/to_be_deployed/usr/local/share/happy-1.18.10/GLR_Lib-ghc-debug
/tmp/to_be_deployed/usr/local/share/happy-1.18.10/GLR_Lib-ghc
/tmp/to_be_deployed/usr/local/share/happy-1.18.10/GLR_Lib
/tmp/to_be_deployed/usr/local/share/happy-1.18.10/GLR_Base
/tmp/to_be_deployed/usr/local/share/happy-1.18.10/HappyTemplate-arrays-coerce-debug
/tmp/to_be_deployed/usr/local/share/happy-1.18.10/HappyTemplate-arrays-ghc-debug
/tmp/to_be_deployed/usr/local/share/happy-1.18.10/HappyTemplate-arrays-debug
/tmp/to_be_deployed/usr/local/share/happy-1.18.10/HappyTemplate-arrays-coerce
/tmp/to_be_deployed/usr/local/share/happy-1.18.10/HappyTemplate-arrays-ghc
/tmp/to_be_deployed/usr/local/share/happy-1.18.10/HappyTemplate-arrays
/tmp/to_be_deployed/usr/local/share/happy-1.18.10/HappyTemplate-coerce
/tmp/to_be_deployed/usr/local/share/happy-1.18.10/HappyTemplate-ghc
/tmp/to_be_deployed/usr/local/share/happy-1.18.10/HappyTemplate
/tmp/happy-1.18.10 $ rsync -rva /tmp/to_be_deployed/ production.host:/
[..]
If you do not want to install into /usr/local then pass the desired prefix to Setup configure.
This works well if the target host is otherwise similar (same versions of C libraries such as gmp and ffi installed). If you also need to statically link some C library, see the question that hammar has linked in his comment.

Resources