-
-
Notifications
You must be signed in to change notification settings - Fork 368
/
GNUmakefile
159 lines (135 loc) · 6.46 KB
/
GNUmakefile
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
####################################################
# This makefile's main purpose is to build
# dynamically linked HLS executables on gitlab CI
# and produce appropriate bindists. This can also
# be executed locally on dev machines.
#
# It is not meant to be run by users.
# ##################################################
UNAME := $(shell uname)
ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
GHC_VERSION ?=
ARTIFACT ?= unknown-platform
HLS_VERSION := $(shell grep '^version:' haskell-language-server.cabal | awk '{ print $$2 }')
TARBALL ?= haskell-language-server-$(HLS_VERSION)-$(ARTIFACT).tar.xz
CHMOD := chmod
CHMOD_X := $(CHMOD) 755
INSTALL := install
INSTALL_D := $(INSTALL) -d
INSTALL_X := $(INSTALL) -vm 755
PATCHELF := patchelf
FIND := find
SED := sed
MKDIR := mkdir
MKDIR_P := $(MKDIR) -p
TAR := tar
TAR_MK := $(TAR) caf
CABAL := cabal
STRIP := strip
ifeq ($(UNAME), Darwin)
STRIP_S := strip
else
STRIP_S := strip -s
endif
RM := rm
RM_RF := $(RM) -rf
CD := cd
CP := cp
# by default don't run ghcup
GHCUP ?= echo
GHCUP_GC ?= $(GHCUP) gc
GHCUP_RM ?= $(GHCUP) rm
CABAL_CACHE_BIN ?= echo
ifeq ($(UNAME), Darwin)
DLL := *.dylib
else
DLL := *.so
endif
INSTALL_NAME_TOOL := install_name_tool
STORE_DIR := store/$(ARTIFACT)
BINDIST_BASE_DIR := out/bindist/$(ARTIFACT)
BINDIST_OUT_DIR := $(BINDIST_BASE_DIR)/haskell-language-server-$(HLS_VERSION)
CABAL_BASE_ARGS ?= --store-dir=$(ROOT_DIR)/$(STORE_DIR)
CABAL_ARGS ?= --disable-tests --disable-profiling -O2 $(ADD_CABAL_ARGS)
CABAL_INSTALL_ARGS ?= --overwrite-policy=always --install-method=copy
CABAL_INSTALL := $(CABAL) $(CABAL_BASE_ARGS) v2-install
PROJECT_FILE := cabal.project
S3_HOST ?=
S3_KEY ?=
# set rpath relative to the current executable
# TODO: on darwin, this doesn't overwrite rpath, but just adds to it,
# so we'll have the old rpaths from the build host in there as well
define set_rpath
$(if $(filter Darwin,$(UNAME)), $(INSTALL_NAME_TOOL) -add_rpath "@executable_path/$(1)" "$(2)", $(PATCHELF) --force-rpath --set-rpath "\$$ORIGIN/$(1)" "$(2)")
endef
define sync_from
$(CABAL_CACHE_BIN) sync-from-archive --host-name-override=$(S3_HOST) --host-port-override=443 --host-ssl-override=True --region us-west-2 --store-path="$(ROOT_DIR)/$(STORE_DIR)" --archive-uri "s3://haskell-language-server/$(S3_KEY)"
endef
define sync_to
$(CABAL_CACHE_BIN) sync-to-archive --host-name-override=$(S3_HOST) --host-port-override=443 --host-ssl-override=True --region us-west-2 --store-path="$(ROOT_DIR)/$(STORE_DIR)" --archive-uri "s3://haskell-language-server/$(S3_KEY)"
endef
hls:
@if test -z "$(GHCS)" ; then echo >&2 "GHCS is not set" ; false ; fi
for ghc in $(GHCS) ; do \
$(GHCUP) install ghc `echo $$ghc` && \
$(GHCUP_GC) -p -s -c -t && \
$(MAKE) GHC_VERSION=`echo $$ghc` hls-ghc || exit 1 && \
$(GHCUP_RM) `echo $$ghc` ; \
done
hls-ghc:
$(MKDIR_P) out/$(ARTIFACT)
$(MKDIR_P) out/plan.json
@if test -z "$(GHC_VERSION)" ; then echo >&2 "GHC_VERSION is not set" ; false ; fi
$(CABAL) $(CABAL_BASE_ARGS) configure --project-file="$(PROJECT_FILE)" -w "ghc-$(GHC_VERSION)" $(CABAL_ARGS) exe:haskell-language-server exe:haskell-language-server-wrapper
$(CABAL) $(CABAL_BASE_ARGS) build --project-file="$(PROJECT_FILE)" -w "ghc-$(GHC_VERSION)" $(CABAL_ARGS) --dependencies-only --dry-run exe:haskell-language-server exe:haskell-language-server-wrapper
$(call sync_from)
$(CP) dist-newstyle/cache/plan.json "$(ROOT_DIR)/out/plan.json/$(ARTIFACT)-ghc-$(GHC_VERSION)-plan.json"
$(CABAL_INSTALL) --project-file="$(PROJECT_FILE)" -w "ghc-$(GHC_VERSION)" $(CABAL_ARGS) $(CABAL_INSTALL_ARGS) --installdir="$(ROOT_DIR)/out/$(ARTIFACT)/$(GHC_VERSION)" exe:haskell-language-server exe:haskell-language-server-wrapper
$(call sync_to)
$(STRIP_S) "$(ROOT_DIR)/out/$(ARTIFACT)/$(GHC_VERSION)/haskell-language-server"
$(STRIP_S) "$(ROOT_DIR)/out/$(ARTIFACT)/$(GHC_VERSION)/haskell-language-server-wrapper"
bindist:
@if test -z "$(GHCS)" ; then echo >&2 "GHCS is not set" ; false ; fi
for ghc in $(GHCS) ; do \
$(GHCUP) install ghc `echo $$ghc` && \
$(GHCUP_GC) -p -s -c -t && \
$(MAKE) GHC_VERSION=`echo $$ghc` bindist-ghc || exit 1 && \
$(GHCUP_RM) `echo $$ghc` ; \
done
$(SED) -e "s/@@HLS_VERSION@@/$(HLS_VERSION)/" \
bindist/GNUmakefile.in > "$(BINDIST_OUT_DIR)/GNUmakefile"
$(INSTALL_D) "$(BINDIST_OUT_DIR)/scripts/"
$(INSTALL_X) "bindist/relpath.sh" "$(BINDIST_OUT_DIR)/scripts/relpath.sh"
bindist-tar:
$(CD) "$(BINDIST_BASE_DIR)" ; $(TAR_MK) "$(ROOT_DIR)/out/$(TARBALL)" "haskell-language-server-$(HLS_VERSION)"
bindist-ghc:
if test -z "$(GHC_VERSION)" ; then echo >&2 "GHC_VERSION is not set" ; false ; fi
$(MKDIR_P) "$(BINDIST_OUT_DIR)/bin"
$(MKDIR_P) "$(BINDIST_OUT_DIR)/lib/$(GHC_VERSION)"
$(INSTALL_D) "$(BINDIST_OUT_DIR)/bin/"
$(INSTALL_X) "out/$(ARTIFACT)/$(GHC_VERSION)/haskell-language-server" "$(BINDIST_OUT_DIR)/bin/haskell-language-server-$(GHC_VERSION)"
$(call set_rpath,../lib/$(GHC_VERSION),$(BINDIST_OUT_DIR)/bin/haskell-language-server-$(GHC_VERSION))
$(SED) \
-e "s/@@EXE_NAME@@/haskell-language-server-$(GHC_VERSION)/" \
-e "s/@@GHC_VERSION@@/$(GHC_VERSION)/" \
-e "s/@@BOOT_PKGS@@/$(shell ghc-pkg-$(GHC_VERSION) --global list --simple-output)/" \
-e "s/@@ABI_HASHES@@/$(shell for dep in `ghc-pkg-$(GHC_VERSION) --global list --simple-output` ; do printf "%s:" "$$dep" && ghc-pkg-$(GHC_VERSION) field $$dep abi --simple-output ; done | tr '\n' ' ' | xargs)/" \
bindist/wrapper.in > "$(BINDIST_OUT_DIR)/haskell-language-server-$(GHC_VERSION).in"
$(CHMOD_X) "$(BINDIST_OUT_DIR)/haskell-language-server-$(GHC_VERSION).in"
$(INSTALL_D) "$(BINDIST_OUT_DIR)/bin/"
$(INSTALL_X) "out/$(ARTIFACT)/$(GHC_VERSION)/haskell-language-server-wrapper" "$(BINDIST_OUT_DIR)/bin/haskell-language-server-wrapper"
$(INSTALL_D) "$(ROOT_DIR)/$(BINDIST_OUT_DIR)/lib/$(GHC_VERSION)"
$(FIND) "$(STORE_DIR)/ghc-$(GHC_VERSION)" -type f -name "$(DLL)" -execdir $(INSTALL_X) "{}" "$(ROOT_DIR)/$(BINDIST_OUT_DIR)/lib/$(GHC_VERSION)/{}" \;
$(FIND) "$(ROOT_DIR)/$(BINDIST_OUT_DIR)/lib/$(GHC_VERSION)" -type f -name '$(DLL)' -execdir $(call set_rpath,,{}) \;
version:
@echo "$(HLS_VERSION)"
clean:
$(RM_RF) out/*
clean-ghcs:
@if test -z "$(GHCS)" ; then echo >&2 "GHCS is not set" ; false ; fi
for ghc in $(GHCS) ; do \
$(GHCUP) rm ghc `echo $$ghc` ; \
done
clean-all: clean-ghcs
$(RM_RF) out/* $(STORE_DIR)
.PHONY: hls hls-ghc bindist bindist-ghc bindist-tar clean clean-all install-ghcs version