Skip to content

Commit 46d7eae

Browse files
author
Mitsutoshi Aoe
authored
Merge pull request #67 from maoe/embed-data-files
Embed data files into binary for easier deployment
2 parents a51cffe + 88b3269 commit 46d7eae

File tree

8 files changed

+126
-17
lines changed

8 files changed

+126
-17
lines changed

GUI/App.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{-# LANGUAGE CPP #-}
2+
{-# LANGUAGE TemplateHaskell #-}
23

34
-------------------------------------------------------------------------------
45
-- | Module : GUI.App
@@ -12,6 +13,7 @@ module GUI.App (initApp) where
1213
#if defined(darwin_HOST_OS)
1314
import qualified Graphics.UI.Gtk as Gtk
1415
import qualified Graphics.UI.Gtk.OSX as OSX
16+
import GUI.DataFiles (loadLogo)
1517
#endif
1618

1719
-------------------------------------------------------------------------------
@@ -25,6 +27,8 @@ initApp = do
2527
app <- OSX.applicationNew
2628
menuBar <- Gtk.menuBarNew
2729
OSX.applicationSetMenuBar app menuBar
30+
logo <- $loadLogo
31+
OSX.applicationSetDockIconPixbuf app (Just logo)
2832
OSX.applicationReady app
2933

3034
#else

GUI/DataFiles.hs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{-# LANGUAGE TemplateHaskell #-}
2+
module GUI.DataFiles
3+
( ui
4+
, loadLogo
5+
) where
6+
import System.IO
7+
8+
import Data.FileEmbed
9+
import Graphics.UI.Gtk (Pixbuf, pixbufNewFromFile)
10+
import Language.Haskell.TH
11+
import System.IO.Temp
12+
import qualified Data.ByteString as B
13+
import qualified Data.Text.Encoding as TE
14+
15+
uiFile :: FilePath
16+
uiFile = "threadscope.ui"
17+
18+
logoFile :: FilePath
19+
logoFile = "threadscope.png"
20+
21+
-- | Textual representaion of the UI file
22+
ui :: Q Exp
23+
ui = [| TE.decodeUtf8 $(makeRelativeToProject uiFile >>= embedFile) |]
24+
25+
renderLogo :: B.ByteString -> IO Pixbuf
26+
renderLogo bytes =
27+
withSystemTempFile logoFile $ \path h -> do
28+
B.hPut h bytes
29+
hClose h
30+
pixbufNewFromFile path
31+
32+
-- | Load the logo file as a 'Pixbuf'.
33+
loadLogo :: Q Exp
34+
loadLogo = [| renderLogo $(makeRelativeToProject logoFile >>= embedFile) |]

GUI/Dialogs.hs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
{-# LANGUAGE TemplateHaskell #-}
12
module GUI.Dialogs where
23

3-
import Paths_threadscope (getDataFileName, version)
4+
import GUI.DataFiles (loadLogo)
5+
import Paths_threadscope (version)
46

57
import Graphics.UI.Gtk
68

@@ -13,8 +15,7 @@ import System.FilePath
1315
aboutDialog :: WindowClass window => window -> IO ()
1416
aboutDialog parent
1517
= do dialog <- aboutDialogNew
16-
logoPath <- getDataFileName "threadscope.png"
17-
logo <- pixbufNewFromFile logoPath
18+
logo <- $loadLogo
1819
set dialog [
1920
aboutDialogName := "ThreadScope",
2021
aboutDialogVersion := showVersion version,

GUI/Main.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{-# LANGUAGE CPP #-}
2+
{-# LANGUAGE TemplateHaskell #-}
23
module GUI.Main (runGUI) where
34

45
-- Imports for GTK
@@ -16,13 +17,12 @@ import Control.Exception
1617
import Data.Array
1718
import Data.Maybe
1819

19-
import Paths_threadscope
20-
2120
-- Imports for ThreadScope
2221
import qualified GUI.App as App
2322
import qualified GUI.MainWindow as MainWindow
2423
import GUI.Types
2524
import Events.HECs hiding (Event)
25+
import GUI.DataFiles (ui)
2626
import GUI.Dialogs
2727
import Events.ReadEvents
2828
import GUI.EventsView
@@ -117,7 +117,7 @@ constructUI :: IO UIEnv
117117
constructUI = failOnGError $ do
118118

119119
builder <- Gtk.builderNew
120-
Gtk.builderAddFromFile builder =<< getDataFileName "threadscope.ui"
120+
Gtk.builderAddFromString builder $ui
121121

122122
eventQueue <- Chan.newChan
123123
let post = postEvent eventQueue

GUI/MainWindow.hs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE TemplateHaskell #-}
12
module GUI.MainWindow (
23
MainWindow,
34
mainWindowNew,
@@ -10,12 +11,10 @@ module GUI.MainWindow (
1011

1112
) where
1213

13-
import Paths_threadscope
14-
15-
-- Imports for GTK
1614
import Graphics.UI.Gtk as Gtk
1715
import qualified System.Glib.GObject as Glib
1816

17+
import GUI.DataFiles (loadLogo)
1918

2019
-------------------------------------------------------------------------------
2120

@@ -146,8 +145,8 @@ mainWindowNew builder actions = do
146145

147146
------------------------------------------------------------------------
148147

149-
logoPath <- getDataFileName "threadscope.png"
150-
windowSetIconFromFile mainWindow logoPath
148+
logo <- $loadLogo
149+
set mainWindow [ windowIcon := Just logo ]
151150

152151
------------------------------------------------------------------------
153152
-- Status bar functionality

README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,67 @@
33
[![Hackage-Deps](https://img.shields.io/hackage-deps/v/threadscope.svg)](http://packdeps.haskellers.com/feed?needle=threadscope)
44
[![Build Status](https://travis-ci.org/haskell/ThreadScope.svg?branch=master)](https://travis-ci.org/haskell/ThreadScope)
55
[![Build status](https://ci.appveyor.com/api/projects/status/y6kd8pyh2f3qok4f?svg=true)](https://ci.appveyor.com/project/Mikolaj/threadscope)
6+
7+
## Installation
8+
9+
### Linux
10+
11+
GTK+2 is required to be installed. On Ubuntu-like systems:
12+
13+
```sh
14+
sudo apt install libgtk2.0-dev
15+
```
16+
17+
Then you can build threadscope using cabal:
18+
```sh
19+
cabal new-build
20+
```
21+
22+
Or using stack:
23+
```sh
24+
stack setup
25+
stack install
26+
```
27+
28+
### macOS
29+
30+
GTK+ and gtk-mac-integration are required.
31+
32+
```sh
33+
brew install gtk+ gtk-mac-integration
34+
```
35+
36+
Then you can build threadscope using cabal:
37+
```sh
38+
cabal new-build --constraint="gtk +have-quartz-gtk"
39+
```
40+
41+
Or using stack:
42+
```sh
43+
stack setup
44+
stack install --flag gtk:have-quartz-gtk
45+
```
46+
47+
### Windows
48+
49+
stack is the recommended tool to build threadscope on Windows.
50+
51+
CAVEAT: Currently gtk2 needs to be installed twice: one for stack's MSYS2 environment and another for local MSYS2 environment.
52+
53+
In command prompt:
54+
```sh
55+
stack setup
56+
stack exec -- pacman --needed -Sy bash pacman pacman-mirrors msys2-runtime msys2-runtime-devel
57+
stack exec -- pacman -Syu
58+
stack exec -- pacman -Syuu
59+
stack exec -- pacman -S base-devel mingw-w64-x86_64-pkg-config mingw-w64-x86_64-toolchain mingw-w64-x86_64-gtk2
60+
stack install
61+
```
62+
63+
Then in MSYS2 MINGW64 shell:
64+
```sh
65+
pacman -S $MINGW_PACKAGE_PREFIX-gtk2
66+
echo 'export PATH=$APPDATA/local/bin:$PATH' >> .profile
67+
source .profile
68+
threadscope
69+
```

appveyor.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,21 @@ platform: x64
22
shallow_clone: true
33
environment:
44
global:
5-
STACK_ROOT: "c:\\sr"
5+
STACK_ROOT: c:\sr
66
cache:
7-
- "c:\\sr -> appveyor.yml"
7+
- c:\sr -> appveyor.yml
8+
- c:\msys64\var\cache\pacman\pkg -> appveyor.yml
89
install:
910
- set HOME=.
10-
- set "PATH=C:\msys64\usr\bin;%PATH%"
11+
- set "PATH=c:\msys64\usr\bin;%PATH%"
1112
- curl -ostack.zip -LsS --insecure https://www.stackage.org/stack/windows-x86_64
1213
- 7z x stack.zip stack.exe
1314
- stack setup > nul
1415
- stack exec -- pacman --noconfirm --needed -Sy bash pacman pacman-mirrors msys2-runtime msys2-runtime-devel
1516
- stack exec -- pacman --noconfirm -Syu
1617
- stack exec -- pacman --noconfirm -Syuu
17-
- stack exec -- pacman --noconfirm -S base-devel mingw-w64-x86_64-toolchain mingw-w64-x86_64-gtk2
18+
- stack exec -- pacman --noconfirm -S base-devel mingw-w64-x86_64-pkg-config mingw-w64-x86_64-toolchain mingw-w64-x86_64-gtk2
19+
- stack exec -- pacman --noconfirm -Sc
1820
build_script:
1921
- stack --no-terminal build --only-dependencies
2022
test_script:

threadscope.cabal

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,13 @@ Executable threadscope
5959
containers >= 0.2 && < 0.6,
6060
deepseq >= 1.1,
6161
text < 1.3,
62-
time >= 1.1 && < 1.9
62+
time >= 1.1 && < 1.9,
63+
bytestring < 0.11,
64+
file-embed < 0.1,
65+
template-haskell < 2.13,
66+
temporary >= 1.1 && < 1.3
6367
if os(osx)
64-
build-depends: gtk-mac-integration
68+
build-depends: gtk-mac-integration < 0.4
6569

6670
include-dirs: include
6771
Extensions: RecordWildCards, NamedFieldPuns, BangPatterns, PatternGuards
@@ -76,6 +80,7 @@ Executable threadscope
7680
GUI.Main,
7781
GUI.MainWindow,
7882
GUI.EventsView,
83+
GUI.DataFiles,
7984
GUI.Dialogs,
8085
GUI.SaveAs,
8186
GUI.Timeline,

0 commit comments

Comments
 (0)