-
-
Notifications
You must be signed in to change notification settings - Fork 142
/
Makefile
195 lines (160 loc) · 8.22 KB
/
Makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# ImplicitCAD Makefile. Build and test Implicitcad.
## This is the makefile if you are running cabal-install 1.24 or later.
## Locations of binaries used when running tests, or generating the images to go along with our README.md.
# The location of stl2ps, from stltools, available from https://github.com/rsmith-nl/stltools/tree/develop
stl2ps=/disk4/faikvm.com/stltools/stltools/stl2ps.py
# The location of convert, from imagemagick
convert=convert
# The location of GHC, used to compile .hs examples.
GHC=ghc
GHCVERSION=$(shell ${GHC} --version | sed "s/.*version //")
CABAL=cabal
CABALVERSION=$(shell ${CABAL} --version | sed -n "s/.*install version \([0-9.]*\).*/\1/p")
IMPLICITVERSION=$(shell cat implicit.cabal | sed -n "s/Version[: ]*\([0-9]*.*\)/\1/p")
ARCHITECTURE=$(shell uname -m | sed "s/i[3-6]86/i386/" )
# FIXME: detect this on other OSes.
OS=linux
# new-style location root. must NOT have trailing slash
BUILDROOT=dist-newstyle/build/${ARCHITECTURE}-${OS}/ghc-${GHCVERSION}/implicit-${IMPLICITVERSION}
EXEBUILDROOT=${BUILDROOT}/x/
TESTBUILDROOT=${BUILDROOT}/t/
BENCHBUILDROOT=${BUILDROOT}/b/
exebin = ${EXEBUILDROOT}/$(1)/build/$(1)/$(1)
exedir = ${EXEBUILDROOT}/$(1)
# The location of the created extopenscad binary, for running shell based test cases.
EXTOPENSCAD=extopenscad
EXTOPENSCADBIN=$(call exebin,${EXTOPENSCAD})
EXTOPENSCADDIR=$(call exedir,${EXTOPENSCAD})
# The location of the implicitsnap binary, which listens for requests via http. The backend of the website.
IMPLICITSNAP=implicitsnap
IMPLICITSNAPBIN=$(call exebin,${IMPLICITSNAP})
IMPLICITSNAPDIR=$(call exedir,${IMPLICITSNAP})
# The location of the benchmark binary, for benchmarking some implicitcad internals.
BENCHMARK=Benchmark
BENCHMARKBIN=${BENCHBUILDROOT}/Benchmark/build/Benchmark/Benchmark
BENCHMARKDIR=${BENCHBUILDROOT}/Benchmark
# The location of the documentation generator. for documenting (some of) the extopenscad language.
DOCGEN=docgen
DOCGENBIN=$(call exebin,${DOCGEN})
DOCGENDIR=$(call exedir,${DOCGEN})
# The location of the parser benchmark binary, specifically for benchmarking implicitcad's parser.
PARSERBENCH=${BENCHBUILDROOT}/parser-bench/build/parser-bench/parser-bench
PARSERBENCHDIR=${BENCHBUILDROOT}/parser-bench
# The location of the created test binary, for running haskell test cases.
TESTSUITE=${TESTBUILDROOT}/test-implicit/build/test-implicit/test-implicit
TESTSUITEDIR=${TESTBUILDROOT}/test-implicit
# The location of it's source.
TESTFILES=$(shell find tests/ -name '*.hs')
## Options used when calling ImplicitCAD. for testing, and for image generation.
# Enable multiple CPU usage.
# Use the parallel garbage collector.
# spit out some performance statistics.
RTSOPTS=+RTS -N -qg -t
# The resolution to generate objects at. FIXME: what does this mean in human terms?
RESOPTS=-r 50
SCADOPTS?=-q
# Uncomment for profiling support. Note that you will need to recompile all of the libraries, as well.
#PROFILING= --enable-profiling
## FIXME: escape this right
# Uncomment for valgrind on the examples.
#VALGRIND=valgrind --tool=cachegrind --cachegrind-out-file=$$each.cachegrind.`date +%s`
LIBDIR=Graphics
LIBFILES=$(shell find ${LIBDIR} -name '*.hs')
LIBBUILDS=$(shell find ${LIBDIR} -name '*.hi' -o -name '*.o')
LIBTARGET=${BUILDROOT}/build/Graphics/Implicit.o
# don't try to compile implicitsnap unless the flag for compiling it has been set.
MAYBEIMPLICITSNAPBIN=$(shell bash -c "[ -n \"$$([ -f cabal.project.local ] && cat cabal.project.local | sed -n '/flags: .*+implicitsnap.*/p')\" ] && echo ${IMPLICITSNAPBIN}" )
EXECTARGETS=$(EXTOPENSCADBIN) $(MAYBEIMPLICITSNAPBIN) $(BENCHMARKBIN) $(TESTSUITE) $(PARSERBENCH) $(DOCGENBIN)
EXECBUILDDIRS=$(EXTOPENSCADDIR) $(IMPLICITSNAPDIR) $(BENCHMARKDIR) $(DOCGENDIR)
TARGETS=$(EXECTARGETS) $(LIBTARGET)
ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
# Options to GHC during compilation of our examples.
EXAMPLEOPTS=-package linear -package show-combinators -package lens -package blaze-svg -package data-default -package JuicyPixels
# Mark the below fake targets as unreal, so make will not get choked up if a file with one of these names is created.
.PHONY: build install clean distclean nukeclean docs dist examples tests benchmarks benchmarkdir
# Empty out the default suffix list, to make debugging output cleaner.
.SUFFIXES:
# Allow for us to (ab)use $$* in dependencies of rules.
.SECONDEXPANSION:
# Disable make's default builtin rules, to make debugging output cleaner.
MAKEFLAGS += --no-builtin-rules
# Build implicitcad binaries.
build: ensureBootstrap $(TARGETS)
# Ensure the haskell environment is sane
ensureBootstrap:
@if [ "${CABALVERSION}" = "2.4.0.0" ] && [ ! -d ~/.cabal/store/ghc-${GHCVERSION}/package.db ] ; then { echo "please create ~/.cabal/store/ghc-${GHCVERSION}/package.db , to workaround a known cabal bug." ; error 1 ; } fi
# Install implicitcad.
install: build
cabal install
# Cleanup from using the rules in this file.
clean:
rm -f Examples/*.stl
rm -f Examples/*.svg
rm -f Examples/*.ps
rm -f Examples/*.png
rm -f Examples/example[0-9][0-9]
rm -f Examples/*.hi
rm -f Examples/*.o
rm -f Examples/example*.cachegrind.*
rm -f tests/*.stl
rm -rf docs/parser.md
rm -f ${TARGETS}
rm -f ${LIBBUILDS}
rm -f benchmarks
rm -rf ${EXECBUILDDIRS} ${PARSERBENCHDIR} ${TESTSUITEDIR}
rm -f ${BUILDROOT}/build/libHS*
rm -f ${BUILDROOT}/cache/registration
# Clean up before making a release.
distclean: clean
cabal clean
rm -rf dist
rm -rf dist-newstyle
rm -rf .stack-work
rm -f cabal.project.local
rm -f .ghc.environment.${ARCHITECTURE}-${OS}-${GHCVERSION}
rm -f `find ./ -name "*~"`
rm -f `find ./ -name "\#*\#"`
# Destroy the current user's cabal/ghc environment.
nukeclean: distclean
rm -rf ~/.cabal/ ~/.ghc/
# Generate documentation.
docs: $(DOCGENBIN)
cabal haddock --enable-documentation
$(DOCGENBIN) > docs/escad.md
# Upload to hackage?
dist: $(TARGETS)
cabal sdist
# Generate examples.
examples: $(EXTOPENSCADBIN)
cd Examples && for each in `find ./ -name '*scad' -type f | sort`; do { echo $$each ; ../$(EXTOPENSCADBIN) $(SCADOPTS) $$each $(RTSOPTS); } done
# NOTE: on debian, if this fails to find the linear package, run: 'apt install libghc-linear-dev libghc-show-combinators-dev libghc-blaze-svg-dev libghc-data-default-dev libghc-juicypixels-dev'
cd Examples && for each in `find ./ -name '*.hs' -type f | sort`; do { filename=$(basename "$$each"); filename="$${filename%.*}"; cd ..; $(GHC) $(EXAMPLEOPTS) Examples/$$filename.hs -o Examples/$$filename; cd Examples; echo $$filename; $$filename +RTS -t ; } done
# Generate images from the examples, so we can upload the images to our website.
images: examples
cd Examples && for each in `find ./ -name '*.stl' -type f | sort`; do { filename=$(basename "$$each"); filename="$${filename%.*}"; if [ -e $$filename.transform ] ; then echo ${stl2ps} $$each $$filename.ps `cat $$filename.transform`; else ${stl2ps} $$each $$filename.ps; fi; ${convert} $$filename.ps $$filename.png; } done
# Hspec parser tests.
tests: $(TESTSUITE) $(TESTFILES)
# cd tests && for each in `find ./ -name '*scad' -type f | sort`; do { ../$(EXTOPENSCADBIN) $$each ${RESOPTS} ${RTSOPTS}; } done
$(TESTSUITE)
benchmarkdir:
[ ! -e benchmarks ] && bash -c 'rm -f benchmarks; ln -s `mktemp --tmpdir -d icad-XXX` benchmarks' || true
benchmarks: $(BENCHMARKBIN) benchmarkdir
cd benchmarks && ${ROOT_DIR}/${BENCHMARKBIN}
# The ImplicitCAD library.
$(LIBTARGET): $(LIBFILES)
cabal new-build implicit
# The parser test suite, since it's source is stored in a different location than the other binaries we build:
${TESTBUILDROOT}/test-implicit/build/test-implicit/test-implicit: $(TESTFILES) ${BUILDROOT}/setup-config $(LIBTARGET) $(LIBFILES)
cabal new-build test-implicit
# Build a binary target with cabal.
${EXEBUILDROOT}/%: programs/$$(word 1,$$(subst /, ,%)).hs ${BUILDROOT}/setup-config $(LIBTARGET) $(LIBFILES)
cabal new-build $(word 1,$(subst /, ,$*))
touch $@
# Build a benchmark target with cabal.
${BENCHBUILDROOT}/%: programs/$$(word 1,$$(subst /, ,%)).hs ${BUILDROOT}/setup-config $(LIBTARGET) $(LIBFILES)
cabal new-build $(word 1,$(subst /, ,$*))
# Prepare to build.
${BUILDROOT}/setup-config: implicit.cabal
cabal new-update
cabal new-install --only-dependencies --upgrade-dependencies --overwrite-policy=always $(PROFILING)
cabal new-configure --enable-tests --enable-benchmarks $(PROFILING)