Skip to content

Commit 68e1224

Browse files
authored
Merge pull request #120 from hvr/pr/simple-alex
Make bootstrapping even easier by avoiding custom Setup.hs
2 parents b6fc5c3 + 73ad11d commit 68e1224

File tree

12 files changed

+204
-120
lines changed

12 files changed

+204
-120
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*~
44
*.o
55
*.info
6+
/.ghc.environment.*
67
/AlexTemplate-debug.bak
78
/AlexTemplate-ghc-debug.bak
89
/AlexTemplate-ghc.bak
@@ -32,6 +33,7 @@
3233
/AlexWrapper-posn
3334
/AlexWrapper-posn-bytestring
3435
/AlexWrapper-strict-bytestring
36+
/data/
3537
/dist
3638
/dist-newstyle
3739
/doc/alex.1

.travis.yml

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
11
# language: haskell
22

33
env:
4+
# - GHCVER=7.0.4
5+
- GHCVER=7.4.2
6+
- GHCVER=7.6.3
47
- GHCVER=7.8.4
58
- GHCVER=7.10.3
6-
- GHCVER=8.0.1
9+
- GHCVER=8.0.2
10+
- GHCVER=8.2.2
11+
- GHCVER=8.4.1
712

813
before_install:
914
- sudo add-apt-repository -y ppa:hvr/ghc
1015
- sudo apt-get update
11-
- sudo apt-get install alex-3.1.7 happy-1.19.5 cabal-install-1.24 ghc-$GHCVER
12-
- export PATH=/opt/cabal/bin:/opt/ghc/$GHCVER/bin:/opt/alex/3.1.7/bin:/opt/happy/1.19.5/bin:$PATH
16+
- sudo apt-get install alex-3.1.7 happy-1.19.5 cabal-install-head ghc-$GHCVER
17+
- export PATH=/opt/cabal/head/bin:/opt/ghc/$GHCVER/bin:/opt/alex/3.1.7/bin:/opt/happy/1.19.5/bin:$PATH
1318

1419
install:
15-
- cabal-1.24 update
16-
- cabal-1.24 install --only-dependencies --enable-tests
20+
- cabal update
1721

1822
script:
1923
- make sdist
2024
- cd dist
2125
- tar xvzf alex-*.tar.gz
2226
- cd alex-*/
23-
- cabal-1.24 configure --enable-tests
24-
- cabal-1.24 build
25-
- cabal-1.24 test
27+
- "echo 'packages: .' > cabal.project"
28+
- cabal new-test --enable-tests

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ sdist ::
1313
$(ALEX) $(ALEX_OPTS) src/Scan.x -o src/Scan.hs
1414
mv src/Parser.y src/Parser.y.boot
1515
mv src/Scan.x src/Scan.x.boot
16+
cabal new-run gen-alex-sdist
1617
cabal sdist
1718
git checkout .
1819
git clean -f

README.md

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,9 @@
55
Alex is a Lex-like tool for generating Haskell scanners. For complete
66
documentation, see the doc directory.
77

8-
http://www.haskell.org/alex/
8+
- <https://www.haskell.org/alex/>
99

10-
http://hackage.haskell.org/package/alex
11-
12-
Alex is built using Cabal. First install GHC and cabal-install, then:
13-
14-
$ cabal configure
15-
$ cabal build
16-
$ cabal install
10+
- <https://hackage.haskell.org/package/alex>
1711

1812
Alex version 2.0 has changed fairly considerably since version 1.x,
1913
and the syntax is almost completely different. For a detailed list of
@@ -29,6 +23,63 @@ The source code in the 'src' and 'examples' directories is intended
2923
for a Haskell 98 compiler with hierarchical modules. It should work
3024
with GHC >= 5.04.
3125

26+
## Build Instructions
27+
28+
If you just want to *use* Alex, you can download or install (via
29+
`cabal install alex`) an
30+
[Alex release from Hackage](https://hackage.haskell.org/package/alex); also note that
31+
distributions such as the
32+
[Haskell Platform](https://www.haskell.org/platform/) and other package
33+
manager-based distributions provide packages for Alex. Moreover,
34+
recent versions of `cabal` will automatically install the required
35+
version of `alex` based on
36+
[`build-tools`/`build-tool-depends` declarations](http://cabal.readthedocs.io/en/latest/developing-packages.html#pkg-field-build-tool-depends).
37+
38+
Read on if you want to build Alex directly from Git.
39+
40+
Alex is built using GHC & Cabal; so first install
41+
[GHC](https://www.haskell.org/ghc) and
42+
[`cabal-install-2.0`](https://www.haskell.org/cabal) (or later).
43+
44+
Since Alex itself is implemented in terms of an Alex scanner,
45+
bootstrapping Alex is a bit tricky:
46+
47+
You need to have the build-tools `alex` and `happy` manually
48+
installed; either via your system package manager distribution, the
49+
Haskell Platform, or e.g. via (run this outside the Git repository!):
50+
51+
$ cabal install alex happy
52+
53+
which installs them into `${HOME}/.cabal/bin` by default (make sure
54+
they're in your `$PATH` for the next steps!).
55+
56+
### Variant A
57+
58+
First you need to generate the pre-processed templates via
59+
60+
$ cabal new-run gen-alex-sdist
61+
62+
(otherwise `cabal install` will complain about
63+
"`data/AlexTemplate: copyFile: does not exist (No such file or directory)`")
64+
65+
And then you can install `alex` simply by invoking
66+
67+
$ cabal install
68+
69+
from inside the Git folder.
70+
71+
### Variant B
72+
73+
Alternatively, you can use the `Makefile` which automates the steps of
74+
producing a self-contained pre-bootstrapped source distribution with
75+
pre-generated lexer/scanners (and which also performs the `cabal
76+
new-run gen-alex-sdist` pre-preprocessing step):
77+
78+
$ make sdist
79+
$ cabal install dist/alex-*.tar.gz
80+
81+
## Contributing & Reporting Issues
82+
3283
Please report any bugs or comments at https://github.com/simonmar/alex/issues
3384

3485
Share and enjoy,

Setup.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import Distribution.Simple
2+
main = defaultMain

Setup.lhs

Lines changed: 0 additions & 99 deletions
This file was deleted.

alex.cabal

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
cabal-version: >= 1.8
12
name: alex
23
version: 3.2.3
34
-- don't forget updating changelog.md!
@@ -18,8 +19,26 @@ description:
1819
lex or flex for C/C++.
1920

2021
category: Development
21-
cabal-version: >= 1.8
22-
build-type: Custom
22+
build-type: Simple
23+
24+
data-dir: data/
25+
26+
data-files:
27+
AlexTemplate
28+
AlexTemplate-ghc
29+
AlexTemplate-ghc-nopred
30+
AlexTemplate-ghc-debug
31+
AlexTemplate-debug
32+
AlexWrapper-basic
33+
AlexWrapper-basic-bytestring
34+
AlexWrapper-strict-bytestring
35+
AlexWrapper-posn
36+
AlexWrapper-posn-bytestring
37+
AlexWrapper-monad
38+
AlexWrapper-monad-bytestring
39+
AlexWrapper-monadUserState
40+
AlexWrapper-monadUserState-bytestring
41+
AlexWrapper-gscan
2342

2443
extra-source-files:
2544
CHANGELOG.md
@@ -50,7 +69,7 @@ extra-source-files:
5069
src/Parser.y.boot
5170
src/Scan.x.boot
5271
src/ghc_hooks.c
53-
templates/GenericTemplate.hs
72+
templates/GenericTemplate.hs
5473
templates/wrappers.hs
5574
tests/Makefile
5675
tests/simple.x
@@ -126,4 +145,7 @@ executable alex
126145
test-suite tests
127146
type: exitcode-stdio-1.0
128147
main-is: test.hs
148+
-- This line is important as it ensures that the local `exe:alex` component declared above is built before the test-suite component is invoked, as well as making sure that `alex` is made available on $PATH and `$alex_datadir` is set accordingly before invoking `test.hs`
149+
build-tools: alex
150+
129151
build-depends: base, process

cabal.project

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
packages:
3+
./
4+
./gen-alex-sdist/
5+
6+

gen-alex-sdist/Main.hs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
module Main (main) where
2+
3+
import Control.Monad
4+
import Language.Preprocessor.Cpphs
5+
import System.Directory
6+
import System.FilePath
7+
8+
main :: IO ()
9+
main = do
10+
sequence_ ([ cpp_template "GenericTemplate.hs" dst opts | (dst,opts) <- templates ] ++
11+
[ cpp_template "wrappers.hs" dst opts | (dst,opts) <- wrappers ])
12+
13+
putStrLn ""
14+
putStrLn "-- fragment for alex.cabal file"
15+
putStrLn "data-dir: data/"
16+
putStrLn ""
17+
putStrLn "data-files:"
18+
forM_ all_template_files $ \fn -> putStrLn (" " ++ fn)
19+
putStrLn "-- end of fragment"
20+
putStrLn ""
21+
putStrLn "You can invoke `cabal sdist` now"
22+
23+
cpp_template :: FilePath -> FilePath -> [String] -> IO ()
24+
cpp_template src0 dst0 defs = do
25+
ex <- doesFileExist src
26+
unless ex $
27+
fail ("file " ++ show src ++ " not found; are you in the right directory?")
28+
29+
putStrLn ("generating " ++ show dst ++ " (from " ++ show src ++ ")...")
30+
createDirectoryIfMissing False "data"
31+
srcdat <- readFile src
32+
outdat <- runCpphs cppflags src =<< readFile src
33+
writeFile dst outdat
34+
35+
return ()
36+
where
37+
src = "templates" </> src0
38+
dst = "data" </> dst0
39+
40+
cppflags = defaultCpphsOptions
41+
{ defines = [(d,"1") | d <- defs ]
42+
, boolopts = defaultBoolOptions
43+
{ hashline = False
44+
, locations = True
45+
, ansi = False
46+
, macros = True
47+
}
48+
}
49+
50+
all_template_files :: [FilePath]
51+
all_template_files = map fst (templates ++ wrappers)
52+
53+
templates :: [(FilePath,[String])]
54+
templates = [
55+
("AlexTemplate", []),
56+
("AlexTemplate-ghc", ["ALEX_GHC"]),
57+
("AlexTemplate-ghc-nopred",["ALEX_GHC", "ALEX_NOPRED"]),
58+
("AlexTemplate-ghc-debug", ["ALEX_GHC","ALEX_DEBUG"]),
59+
("AlexTemplate-debug", ["ALEX_DEBUG"])
60+
]
61+
62+
wrappers :: [(FilePath,[String])]
63+
wrappers = [
64+
("AlexWrapper-basic", ["ALEX_BASIC"]),
65+
("AlexWrapper-basic-bytestring", ["ALEX_BASIC_BYTESTRING"]),
66+
("AlexWrapper-strict-bytestring", ["ALEX_STRICT_BYTESTRING"]),
67+
("AlexWrapper-posn", ["ALEX_POSN"]),
68+
("AlexWrapper-posn-bytestring", ["ALEX_POSN_BYTESTRING"]),
69+
("AlexWrapper-monad", ["ALEX_MONAD"]),
70+
("AlexWrapper-monad-bytestring", ["ALEX_MONAD_BYTESTRING"]),
71+
("AlexWrapper-monadUserState", ["ALEX_MONAD", "ALEX_MONAD_USER_STATE"]),
72+
("AlexWrapper-monadUserState-bytestring", ["ALEX_MONAD_BYTESTRING", "ALEX_MONAD_USER_STATE"]),
73+
("AlexWrapper-gscan", ["ALEX_GSCAN"])
74+
]

gen-alex-sdist/Setup.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import Distribution.Simple
2+
main = defaultMain

0 commit comments

Comments
 (0)