-
Notifications
You must be signed in to change notification settings - Fork 0
/
opam-dist.mk
277 lines (251 loc) · 8.99 KB
/
opam-dist.mk
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
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# -*- makefile-gmake -*-
# ----------------------------------------------------------------------
#
# Makefile utilities to build and distribute opam packages either
# directly (`pool' or `url' methods) or web-hosted git.
#
# Copyright (C) 2015 Nicolas Berthier
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# ----------------------------------------------------------------------
#
# o Usage Instructions
#
# To use these utilities, define an environment variable (e.g.,
# OPAM_DIST_DIR) and make it refer the absolute directory containting
# this `opam-dist.mk' file. This variable will be used to check the
# project is built on a setup capable of buildingt and distributing
# the projects' release archives.
#
# Configuration can be done on a per-project or per-site basis:
#
# - Per-site definitions are read first, and should be placed in a
# file named `$(OPAM_DIST_DIR)/opam-dist-config.mk' (i.e., in the
# same directory as `opam-dist.mk');
#
# - Per-project definitions must be placed at the root of the
# projects' source code directory, in a file named either
# `opam-dist-config.mk' or `.opam-dist-config.ml'.
#
# When loaded by make, `opam-dist.mk' first reads, if they exist, the
# per-site configuration file and then the per-project ones. In the
# end, several variables must have been defined; among them are the
# two following variables, common to all distribution methods:
#
# OPAM_REPO_DIR = <path of OPAM repository directory>
# OPAM_DIST_METHOD = { pool | url | git }
#
# Three methods are currently available for distributing the archives:
# `pool', `url' or `git'.
#
# - Selecting the `pool' distribution method means that the
# distributed archives will be generated into a given directory that
# should then be accessible on the Internet. To use it, you must
# additionally define the following variables:
#
# DIST_POOL_DIR = <absolute path of directory where archives will be \
# put>
# DIST_POOL_URL = <URL of the directory pointed to by the above \
# variable>
#
# - The `url' distribution method is similar to the `pool' except that
# the distribution archive is already available on the
# Internet. Define the OPAM_DIST_URL variable to use it:
#
# OPAM_DIST_URL = <URL of the archive>
#
# - Selecting the `git' distribution method means that the released
# archives shall be retrieved directly form a git repository
# available on the Internet (such as github). In this case, you must
# define the following variable:
#
# OPAM_DIST_GIT_ARCH_FROM_REF = <URL of the reference $(1)>
#
# e.g., on github, for project `p' of user `u', one cas define this
# variable as:
#
# OPAM_DIST_GIT_ARCH_FROM_REF = \
# https://github.com/u/p/archive/$(1).tar.gz
#
# o Specifying the Contents of Project Distribution Archives
#
# Once opam-dist is configured, add the following definitions in the
# Makefile of your project:
#
# PKGNAME = <OPAM package name>
# PKGVERS = <OPAM-compatible version of your package>
# ifneq ($(OPAM_DIST_DIR),)
# OPAM_DIR = <directory containting the OPAM-related files listed \
# bellow>
# OPAM_FILES = descr opam files
# DIST_FILES = <list of files to put in the distribution archive \
# (configure LICENSE README Makefile myocamlbuild.ml src
# _tags ...)>
# -include $(OPAM_DIST_DIR)/opam-dist.mk
# endif
#
# Note that default values for OPAM_DIR and OPAM_FILES are "opam" and
# "descr opam", respectively.
#
# Remarks for the `git' distribution method:
#
# - The DIST_FILES is facultative in this case;
#
# - It is recommended to use tags to define version numbers, and then
# generate PKGVERS using something like:
#
# PKGVERS = $(shell git describe --tags --always)
#
# - Also, do not forget to push tags (using `git push --tags') on the
# remote repository before building packages using this method.
#
# o Building and Distributing the Package
#
# Eventually, type `make opam-package' to create the distribution
# archive (if using the `pool' method) and deploy the necessary files
# in the OPAM repository directory ($(OPAM_REPO_DIR)).
#
# If the repository directory is version-controlled using git, then
# just commit (anf push) the changes. Otherwise run `opam-admin make
# -g -i' in it to set it up. If and when the changes made in
# $(OPAM_REPO_DIR) by the latter command are made accessible through a
# public URL of the repository (say, `http://repo-url/', and the pool
# is also made accessible through $(DIST_POOL_URL), then the OPAM
# package should be available for installation after executing `opam
# repo add <repo-name> http://repo-url/; opam update repo
# <repo-name>'.
#
# ------------------------------------------------------------------------------
-include $(dir $(lastword $(MAKEFILE_LIST)))/opam-dist-config.mk
-include opam-dist-config.mk
-include .opam-dist-config.mk
# ---
ifdef VERSION_STR
$(warning Variable VERSION_STR is deprecated; use PKGVERS instead)
PKGVERS = $(VERSION_STR)
else
ifndef PKGVERS
$(error PKGVERS must be defined to the package version)
endif
endif
# ---
# Default value for OPAM specification directory.
OPAM_DIR ?= opam
OPAM_FILE_VERSION ?= 2
ifeq ($(OPAM_FILE_VERSION),1)
OPAM_FILES ?= descr opam
else
OPAM_FILES ?= opam
endif
# ---
ifeq ($(OPAM_DIST_METHOD),pool)
DIST_ROOT_DIR := $(PKGNAME)-$(PKGVERS)
ifeq ($(DIST_POOL_DEEP),yes)
DIST_NAME := $(PKGNAME)/$(DIST_ROOT_DIR).tar.gz
else
DIST_NAME := $(DIST_ROOT_DIR).tar.gz
endif
DIST_POOL_DIR ?= .
DIST_ARCH := $(DIST_POOL_DIR)/$(DIST_NAME)
.PHONY: dist-arch
opam-dist-arch: $(DIST_ARCH) force
$(DIST_ARCH): $(DIST_FILES) $(DIST_DEPS)
mkdir -p "$(DIST_ROOT_DIR)";
cp -r $(DIST_FILES) "$(DIST_ROOT_DIR)";
mkdir -p "$(dir $@)";
tar cvaf "$@" "$(DIST_ROOT_DIR)";
chmod a+r "$@";
rm -rf "$(DIST_ROOT_DIR)";
endif
# ---
HAS_OPAM_INFO = $(shell test -d "$(OPAM_DIR)" && echo yes || echo no)
ifeq ($(HAS_OPAM_INFO),yes)
OPAM_REPO_DIR ?= .
OPAM_PKG_DIR := $(OPAM_REPO_DIR)/packages
ifeq ($(OPAM_REPO_DEEP),yes)
OPAM_PKG_DIR := $(OPAM_PKG_DIR)/$(PKGNAME)
endif
OPAM_DEST_DIR := $(OPAM_PKG_DIR)/$(PKGNAME).$(PKGVERS)
OPAM_DEPS = $(addprefix $(OPAM_DIR)/, $(OPAM_FILES))
.PHONY: opam-package opam-package-pool
opam-package: opam-package-$(OPAM_DIST_METHOD)
opam-package-dir-repo: $(OPAM_DEPS)
@test -d "$(OPAM_DEST_DIR)" && rm -rf "$(OPAM_DEST_DIR)" || true;
@echo -n "Creating \`$(OPAM_DEST_DIR)'..." 1>&2; \
mkdir -p "$(OPAM_DEST_DIR)"; \
cp -r $(OPAM_DEPS) "$(OPAM_DEST_DIR)"; \
chmod a+r -R "$(OPAM_DEST_DIR)"; \
echo " done" 1>&2;
ifeq ($(OPAM_FILE_VERSION),1)
define mk_url
echo -n "Generating url file..." 1>&2; \
exec 1>"$(OPAM_DEST_DIR)/url"; \
echo "archive: \"$${arch}\""; \
echo "checksum: \"$${sha512sum}\""; \
chmod a+r "$(OPAM_DEST_DIR)/url"; \
echo " done" 1>&2
endef
else
define mk_url
echo -n "Appending url section in opam file..." 1>&2; \
exec 1>>"$(OPAM_DEST_DIR)/opam"; \
echo "url {"; \
echo " src: \"$${arch}\""; \
echo " checksum: \"sha512=$${sha512sum}\""; \
echo "}"; \
echo " done" 1>&2
endef
endif
define mk_url_from_local_arch
echo -n "Computing checksum..." 1>&2; \
sha512sum="$$(sha512sum "$(DIST_ARCH)" | cut -d ' ' -f 1)"; \
echo " done" 1>&2; \
$(mk_url)
endef
define mk_url_from_remote_arch
echo -n "Computing checksum..." 1>&2; \
sha512sum="$$(wget -O - -q "$${arch}" | sha512sum | cut -d ' ' -f 1)"; \
echo " done" 1>&2; \
$(mk_url)
endef
opam-package-pool: opam-dist-arch opam-package-dir-repo
arch="$(DIST_POOL_URL)/$(DIST_NAME)"; \
$(mk_url_from_local_arch);
opam-package-url: opam-package-dir-repo
@arch="$(OPAM_DIST_URL)"; \
$(mk_url_from_remote_arch);
opam-package-git: opam-package-dir-repo
@ref="$(PKGVERS)"; \
arch="$(call OPAM_DIST_GIT_ARCH_FROM_REF,$${ref})"; \
echo -n "Testing archive \`$${arch}'..." 1>&2; \
if wget --spider -q "$${arch}"; then \
echo " found" 1>&2; \
else \
echo " not found" 1>&2; \
echo "\`$${ref}' does not seem to exist on remote repository."\
"Did you push your changes?" 1>&2; \
echo "Hint: Remember to push tags using" \
"\`git push --tags'." 1>&2; \
exit 1; \
fi; \
$(mk_url_from_remote_arch);
.PHONY: opam-package-clean
opam-package-clean: force
rm -rf $(OPAM_DEST_DIR);
endif
# ---
.PHONY: force
force:
# ------------------------------------------------------------------------------