-
Notifications
You must be signed in to change notification settings - Fork 125
/
Makefile.bld
196 lines (165 loc) · 6.22 KB
/
Makefile.bld
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
#!/usr/bin/make
# [ Warning ] don't use make to solve dependencies !!
#
# we rely on ocamlbuild which already handles them ; every rule should
# call it only once (more details below)
#
# The OPA build system
# --------------------
#
# - it's based on ocamlbuild, the Makefiles are simple wrappers on top of it
#
# - you should include this Makefile to handle the automatic building of the myocamlbuild extensions
#
# - this Makefile uses build_rules.ml, build_libs, build_tools to:
# - generate the ocamlbuild plugin (target $(MYOCAMLBUILD), run with $(OCAMLBUILD))
# - generate Makefile targets:
# single tool/lib: <tool>, install-<tool>, <lib>, install-<lib>
# all tools/libs: tools, install-tools, libs, install-libs
# - generate Makefile variables:
# target-tool-<tool> (an ocamlbuild target)
# copy-tool-<tool>, install-<tool>, install-<lib> (commands)
# lib-cmi-<lib> (all exported modules within the lib)
# copy-tool puts the generated tool in its desired directory, under $(BUILD_DIR)
#
# - we want to call ocamlbuild only once, so you should always factorise your calls,
# with something like:
# .PHONY: my_final_rule
# my_final_rule: $(MYOCAMLBUILD)
# $(OCAMLBUILD) $(call target-tools,<my_tools>) $(call target-libs,<my_libs>) <my_other_targets>
# @$(call copy-tools,<my_tools>)
#
# - all targets in here are PHONY, we actually build to $(BUILD_DIR). That's what we
# want because it's ocamlbuild that will check if anything needs to be rebuilt.
#
BUILD_DIR ?= _build
BLDDIR ?= build
MYOCAMLBUILD = $(BUILD_DIR)/myocamlbuild
OCAMLBUILD = $(MYOCAMLBUILD) -no-plugin -j 6 $(OCAMLBUILD_FLAGS)
INSTALL ?= cp -u
DESTDIR ?=
INSTALL_DIR = $(DESTDIR)$(PREFIX)
LIB_INSTALL_DIR = $(INSTALL_DIR)/lib/opa/static
.PHONY: clean
clean::
rm -rf _build
.PHONY: distclean
distclean: clean
rm -f config.sh config.ml config.make
-include $(BUILD_DIR)/build_libs.make
-include $(BUILD_DIR)/build_tools.make
ifdef private
BUILD_RULES := $(wildcard build_rules*.ml)
BUILD_LIBS := $(wildcard build_libs*)
BUILD_TOOLS := $(wildcard build_tools*)
else
BUILD_RULES := build_rules.ml
BUILD_LIBS := build_libs
BUILD_TOOLS := build_tools
endif
MYOCAMLBUILD_SOURCES = $(BLDDIR)/gen_myocamlbuild.sh $(BLDDIR)/myocamlbuild_prefix.ml $(BLDDIR)/myocamlbuild_suffix.ml config.ml $(BUILD_RULES) $(BUILD_LIBS) $(BUILD_TOOLS)
$(MYOCAMLBUILD): $(MYOCAMLBUILD_SOURCES)
@echo "Ocamlbuild plugin generation"
@$(BLDDIR)/gen_myocamlbuild.sh
# arguments: path to cmi file, lib name
cmi-in-lib = $(shell grep -si '^\(\([^\#].* \)\? *\|?[^: ]\+:\)$(1)\( \|$$\)' $(2).mllib*)
# arguments: lib name, directory
lib-cmi = \
$(foreach cmi,$(wildcard $(BUILD_DIR)/$(2)/*.cmi),\
$(if $(call cmi-in-lib,$(2)/$(notdir $(basename $(cmi))),$(1)),\
$(cmi:$(BUILD_DIR)/%=%)))
# Generate a specialised Makefile from build_libs
$(BUILD_DIR)/build_libs.make: $(BUILD_LIBS)
@mkdir -p $(BUILD_DIR)
@awk '/^internal/ { \
lib = $$2; libs[i++] = $$2; \
dir = $$3 ? $$3 : lib; \
printf ".PHONY: %s\n",lib; \
printf "%s: $$(MYOCAMLBUILD)\n\t$$(OCAMLBUILD) $$@.cmxa\n",lib; \
printf "install-%s:\n\t@$$(install-%s)", lib, lib; \
printf "\n"; \
printf "lib-cmi-%s = $$(call lib-cmi,%s,%s)\n", lib, lib, dir; \
printf "install-%s = mkdir -p $$(LIB_INSTALL_DIR) && ", lib; \
printf "$$(INSTALL)"; \
printf " $$(addprefix $$(BUILD_DIR)/,%s.$(EXT_LIB) %s.cmxa $$(lib-cmi-%s))", lib, lib, lib; \
printf " $$(wildcard $$(BUILD_DIR)/%s/*.*a)", dir; \
printf " $$(LIB_INSTALL_DIR)/\n\n"; \
} \
END { \
printf "ALL_LIBS ="; for (i in libs) printf " %s",libs[i]; printf "\n"; \
}' \
$(^F) > $@
ALL_LIBS := $(filter-out $(DISABLED_LIBS),$(ALL_LIBS))
target-libs = $(addsuffix .cmxa,$(1))
.PHONY: libs
libs: $(MYOCAMLBUILD)
$(OCAMLBUILD) $(call target-libs,$(ALL_LIBS))
.PHONY: install-libs
install-libs:
@$(foreach lib,$(ALL_LIBS),$(install-lib-$(lib));)
# Generate a specialised Makefile from build_tools
$(BUILD_DIR)/build_tools.make: $(BUILD_TOOLS)
@mkdir -p $(BUILD_DIR)
@awk '/^internal/ && ! /\.(cmx|cmo|o|xml|js)/ { \
tool = $$2; tools[i] = tool; \
target = $$3; targets[i] = target; \
dir = $$4 ? $$4 : "bin"; dirs[i++] = dir; \
printf ".PHONY: %s\n", tool; \
printf "%s: $$(MYOCAMLBUILD)\n", tool; \
printf "\t$$(OCAMLBUILD) %s\n", target; \
printf "\t@$$(copy-tool-%s)\n", tool; \
printf ".PHONY: install-%s\n", tool; \
printf "install-%s:\n\t@$$(install-%s)", tool, tool; \
printf "\n"; \
printf "target-tool-%s = %s\n", tool, target; \
printf "copy-tool-%s = ", tool; \
printf "mkdir -p $$(BUILD_DIR)/%s && $$(INSTALL) $$(BUILD_DIR)/%s $$(BUILD_DIR)/%s/%s", \
dir, target, dir, tool; \
if (dir=="bin") printf " && chmod a+x $$(BUILD_DIR)/%s/%s\n",dir,tool; \
else printf "\n"; \
printf "install-%s = ", tool; \
printf "mkdir -p $$(PREFIX)/%s && $$(INSTALL) $$(BUILD_DIR)/%s/%s $$(INSTALL_DIR)/%s/%s\n", \
dir, dir, tool, dir, tool; \
printf "\n"; \
} \
END { \
printf "ALL_TOOLS ="; for (i in tools) printf " %s",tools[i]; printf "\n"; \
}' \
$(^F) > $@
target-tools = $(foreach tool,$(1),$(target-tool-$(tool)))
copy-tools = $(foreach tool,$(1),$(copy-tool-$(tool));)
.PHONY: tools
tools: $(MYOCAMLBUILD)
$(OCAMLBUILD) $(call target-tools,$(ALL_TOOLS))
@$(call copy-tools,$(ALL_TOOLS))
.PHONY: install-tools
install-tools:
$(foreach tool,$(ALL_TOOLS),$(install-tool-$(tool));)
# some helper bindings
.PHONY: *.stamp
%.stamp: $(MYOCAMLBUILD)
$(OCAMLBUILD) $@
.PHONY: *.native
%.native: $(MYOCAMLBUILD)
$(OCAMLBUILD) $@
.PHONY: *.cmx
%.cmx: $(MYOCAMLBUILD)
$(OCAMLBUILD) $@
.PHONY: *.cma
%.cma: $(MYOCAMLBUILD)
$(OCAMLBUILD) $@
# from %.mltop
.PHONY: *.top
%.top: $(MYOCAMLBUILD)
$(OCAMLBUILD) $@
.PHONY: *.html
%.html: $(MYOCAMLBUILD) %.odocl
$(OCAMLBUILD) $*.docdir/index.html
@rm -rf $(BUILD_DIR)/$@
@mv $(BUILD_DIR)/$*.docdir $(BUILD_DIR)/$@
.PHONY: *.man
%.man: $(MYOCAMLBUILD) %.odocl
$(OCAMLBUILD) -tag manpage $*.docdir/man
@rm -rf $(BUILD_DIR)/$@
@mkdir -p $(BUILD_DIR)/$@
@mv $(BUILD_DIR)/$*.docdir $(BUILD_DIR)/$@/man3